2018/09/18

gvm使用時にvscode-goで「Cannot find "go" binary. Update PATH or GOROOT appropriately」が出たときの解決方法

新しいMBP2018(High Sierra)にしてからGo言語(以下、golangと呼ぶ)の開発環境構築をしていた。そのとき、VSCodeのMicrosoft謹製のgolang用拡張機能(vscode-go)を使って、golangを書こうとしたときにかなりハマった。

ハマった点はいくつかあるのだが、今回は「Cannot find "go" binary. Update PATH or GOROOT appropriately」というエラーがでたときのことに絞って書こうと思う。

私の開発環境は以下のとおり。
  • macOS High Sierra
  • gvm@1.0.22
  • go@1.11
    • gvmでインストールする
  • VSCode@1.27.x
  • vscode-go@0.6.89

TL;DR


解消するためにいくつかの方法を試したのだが、まず結果から書く。

$GOROOTをVSCodeの設定ファイルに指定する。
# GOROOTの確認する
$ echo $GOROOT
/Users/rikko/.gvm/gos/go1.11

# GOROOTが設定されていなかったらgoバイナリの場所を確認する
$ which go

# それでもなかったら、直接gvmのパスを確認する
$ cd /Users/rikko/.gvm/gos
$ ls
go 1.11

goバイナリの場所が確認できたら、VSCodeでgo.gorootを設定する。
{
  // 略
 
  "go.goroot": "/Users/rikko/.gvm/gos/go1.11",

  // 略
}

これでエラーが解消される。


以降、この解決方法を見つけるためにいろいろ試した結果を残しておく。



gvmとgoをインストールする


まずはgvmとgoをインストールする。
# gvmのインストール
$ bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)

Cloning from https://github.com/moovweb/gvm.git to $HOME/.gvm
No existing Go versions detected
Installed GVM v1.0.22

Please restart your terminal session or to get started right away run
 `source $HOME/.gvm/scripts/gvm`


# 設定ファイルの再読込
$ source $HOME/.gvm/scripts/gvm


# gvmのバージョン確認
$ gvm version
Go Version Manager v1.0.22 installed at $HOME/.gvm

# goをインストールし、デフォルトに設置sるう
$ gvm install go1.11 -B
$ gvm use go1.11 --default
$ go version
Now using version go1.11
go version go1.11 darwin/amd64

詳細なインストール方法は、以下の記事を御覧ください。

「Cannot find "go" binary. Update PATH or GOROOT appropriately」が出る


VSCodeにvscode-goをインストールしてから、golangのファイルを作って保存するときに「Cannot find "go" binary. Update PATH or GOROOT appropriately」が発生する。



PATHやGOROOTを確認する


VSCodeのターミナルでPATHGOROOTを確認する。
$ echo $PATH
/Users/rikko/.gvm/pkgsets/go1.11/global/bin
/Users/rikko/.gvm/gos/go1.11/bin
/Users/rikko/.gvm/pkgsets/go1.11/global/overlay/bin
/Users/rikko/.gvm/bin
/Users/rikko/go/bin
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin

$ echo $GOROOT
/Users/rikko/.gvm/gos/go1.11

どうやらPATHGOROOTも設定されていて問題なさそうに見える。
シェルではパスが通っているのに、VSCodeでは通っていない?!



vscode-goのソースコードを読んで見る

まずエラーメッセージで検索してみたところ、それっぽいメソッドがヒットした。
// https://github.com/Microsoft/vscode-go/blob/0.6.89/src/goCheck.ts#L57
export function check(fileUri: vscode.Uri, goConfig: vscode.WorkspaceConfiguration): Promise<ICheckResult[]> {
  // 略
  let goRuntimePath = getBinPath('go');

  if (!goRuntimePath) {
    
    // ↓この部分
    vscode.window.showInformationMessage('Cannot find "go" binary. Update PATH or GOROOT appropriately');
    return Promise.resolve([]);
  }

  // 略
}

goBinPath('go')でパスが取得できなかったときにエラーを出しているようだ。そこでgoBinPathメソッドでもう一度検索して、メソッドを深掘りしていくと…
// https://github.com/Microsoft/vscode-go/blob/0.6.89/src/util.ts#L368
/**
 * @param tool 'go'という文字列が渡ってくる
 */
export function getBinPath(tool: string): string {
  return getBinPathWithPreferredGopath(tool, tool === 'go' ? [] : [getToolsGopath(), getCurrentGoPath()], vscode.workspace.getConfiguration('go', null).get('alternateTools'));
}

// https://github.com/Microsoft/vscode-go/blob/0.6.89/src/goPath.ts#L33
/**
 * @param toolName 'go'という文字列が渡ってくる
 * @param preferredGopaths [](空配列)が渡ってくる
 * @param alternateTools ユーザ設定、またはワークスペース設定のjsonが渡ってくる
 */
export function getBinPathWithPreferredGopath(toolName: string, preferredGopaths: string[], alternateTools?: { [key: string]: string; }) {
  // 略

  // Check GOROOT (go, gofmt, godoc would be found here)
  let pathFromGoRoot = getBinPathFromEnvVar(binname, process.env['GOROOT'], true);  // binnameは設定ファイル
  if (pathFromGoRoot) {
    // ↓設定ファイルにGOROOTの設定があったらそれを使う
    binPathCache[toolName] = pathFromGoRoot;
    return pathFromGoRoot;
  }

  // 略

  // Check default path for go
  if (toolName === 'go') {

    // ↓ 設定ファイルにGOROOTの指定がなかったらデフォルトで'/usr/local/go/bin/go'を参照する
    let defaultPathForGo = process.platform === 'win32' ? 'C:\\Go\\bin\\go.exe' : '/usr/local/go/bin/go';
    if (fileExists(defaultPathForGo)) {
      binPathCache[toolName] = defaultPathForGo;
      return defaultPathForGo;
    }
    return;
  }

  // 略
}

設定ファイルにGOROOTの指定がないと、デフォルトで「/usr/local/go/bin/go」を見に行っている。gvmでインストールしたgoバイナリは「$HOME/.gvm/gos/go1.11」なので参照されていないことがわかる。

ちなみにhomebrewでgoをインストールすると「/usr/local/go/bin/go」にバイナリファイルができるので、その場合は「Cannot find "go" binary」にはならなかった。



強制的にVSCode内のGOROOTのパスを変更する

デフォルトでは前述のとおり「/usr/local/bin/go/bin」を見に行ってしまうので、強制的にVSCode内のGOROOTを「$HOME/.gvm/gos/go1.11」に変更する。

設定ファイルでGOROOTを変更するため、go.gorootを使う。ということでユーザ設定に以下のような設定を追加する。
{
  // 略
 
  "go.goroot": "/Users/rikko/.gvm/gos/go1.11",

  // 略
}

実際にVSCode上で動かしてみると、「Cannot find "go" binary」のエラーがでなくなった。


実際はログインシェルをbashからfishに変えていたこともあって、.bash_profile.config/fish/config.fishを書き換えたりとかなり時間を浪費してしまった。



以上

written by @bc_rikko

0 件のコメント :

コメントを投稿