Golang環境構築手順メモ

最近Goを触り始めました。
開発環境を構築する際に毎回忘れて調べ直しているので、備忘録としてメモしたいと思います。
OSはLinux(CentOS7)とWindows10を対象にしています。(Mac持っていないので試せていません。)

ちなみに、エディタはVimを使用します。

# Linux(CentOS7)
Goのインストール、Vimのアップデート、vim-goプラグインの導入の順で記載していきます。

Linuxについては、Virtualbox、Vagrantで以下のVagrantfileを使用して作成しています。
(※IPはそのままでも大丈夫だと思いますが、適当です。)
使用する場合、以下のようなフォルダ構成で、shareフォルダをVagrantfileと同じ場所に作成して起動してください。

```text:フォルダ構成
gotest (フォルダ)
  |-share (フォルダ)
  |-Vagrantfile
```

```ruby:Vagrantfile
Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  config.vm.hostname = "gotest"
  config.vm.network "private_network", ip: "192.168.50.10"
  config.vm.synced_folder "./share", "/home/vagrant/ws", mount_options: ['dmode=755','fmode=644']
  config.vm.provider "virtualbox" do |v|
    v.name = "gotest"
    v.memory = 4096
    v.cpus = 2
  end
  config.vm.provision "shell", inline: <<-SHELL
    yum update -y
    yum install epel-release -y
    yum install man-pages.noarch man-pages-ja.noarch vim-enhanced git -y
  SHELL
end
```

## Goのインストール
yumでもインストールできますが、若干バージョンが古いため、公式サイトからダウンロードしてインストールします。
※curlで指定しているURLは[Downloads](https://golang.org/dl/)からリンクをコピーして持ってきています。

```
Goのインストール
$ mkdir ~/DL        # ダウンロードしたファイルをホームに置くのが好きじゃないのでDLフォルダを作っています。(任意)
$ cd ~/DL
$ curl -L -O https://dl.google.com/go/go1.12.9.linux-amd64.tar.gz
$ sudo tar -C /usr/local -xzf go1.12.9.linux-amd64.tar.gz

環境変数の設定
$ echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bash_profile
$ echo 'export PATH=$PATH:$(go env GOPATH)/bin' >> ~/.bash_profile
$ source ~/.bash_profile

確認
$ go version
go version go1.12.9 linux/amd64

Go用のディレクトリ作成
$ mkdir -p `go env GOPATH`/{src,bin,pkg}
```

※/usr/localに直接コマンドのを置いているだけなので、更新の際は上書きで大丈夫かな？(調べていない。)

Go自体のインストールは上記で終わりですが、
追加でやっておくと良さそうな手順を補足しておきます。

```
ライブラリやコマンドの追加時に使用するパッケージのインストール
$ sudo yum install -y git mercurial subversion
```

```
GOのREPLをインストール
$ GO111MODULE=off go get -u github.com/motemen/gore/cmd/gore

確認
$ gore
gore version 0.4.1  :help for help
gore>

終了は:q
gore> :q
```

## Vimのアップデート
後続手順でインストールするvim-goは`Vim 7.4.2009`または`Neovim 0.3.1.`以上のバージョンが必要な為アップデートします。

> vim-go requires at least Vim 7.4.2009 or Neovim 0.3.1.

```
環境のアップデート
$ sudo yum update -y
$ sudo yum install -y git gcc ncurses-devel

GitHubからダウンロード
$ cd 
$ git clone https://github.com/vim/vim.git ~/DL/vim    # DLはGoインストール時に作成したディレクトリ

Vimのビルド
$ cd ~/DL/vim
$ make && sudo make install
$ cd        # ホームに戻る

バージョン確認
$ vim --version | head -n 1
VIM - Vi IMproved 8.1 (2018 May 18, compiled May  7 2019 13:12:36)

(バージョンが変わっていない場合は、再ログインを試してください。)
```

## vim-go(Vimプラグイン)のインストール
プラグインを入れると、保存時にフォーマットを直してくれるなど便利！。

```
$ curl -fLo ~/.vim/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
$ git clone https://github.com/fatih/vim-go.git ~/.vim/plugged/vim-go

以下の内容を ~/.vimrc に追加。　(echoから>> ~/.vimrcまでで1つのコマンドです。)
echo "call plug#begin()
  Plug 'fatih/vim-go', { 'do': ':GoInstallBinaries' }
call plug#end()" >> ~/.vimrc
```

Vimを起動しコマンドラインモードで`:GoInstallBinaries`を実行する。

```bash:プラグインインストール
$ vi        # または $ vim

コマンドラインモード(:を入力)で実行する
:GoInstallBinaries
```

※上記を実行していない場合、既存のgoファイル(例：sample.go)を開いた際に以下のエラーが表示されます。

```
vim-go: could not find 'gopls'. Run :GoInstallBinaries to fix it
Error detected while processing function <SNR>10_register[9]..go#lsp#DidOpen:
line   19:
E117: Unknown function: sendMessage
```

※プラグインのアップデートは以下のコマンドで実行できます。

```
:PlugUpdate
```

# Windows10
Windowsでインストールした時のメモです。
WindowsではGitBashを使用しているので、GitBashを前提とした内容になっています。
しっかり確認できていない部分もあるため、補足程度に参照よろしくお願いします。

## Chocolateyのインストール
Chocolateyをインストールしていない方は、以下を参考にインストールします。
(コマンドをコピーして管理者権限で実行するだけです)
https://chocolatey.org/install

## Goのインストール

管理者権限で起動したコマンドプロンプト、またはPowerShellで以下を実行してインストールします。

```
検索
> choco search golang

インストール
> choco install -y golang

更新は以下
> choco upgrade -y golang
```

# Git Bash導入
最新(2019/08/24現在：2.23)のGitBashでは、Vimのバージョンがvim-goの要求するバージョンになっています。
Vimのバージョンが古い場合は、[公式サイト](https://gitforwindows.org/)からインストーラーをダウンロードして最新をインストールしてください。

※GitBash(Git for Windows)もChocolateyでインストールできるらしいですが、
　インストーラーを使用してインストール済みだったため、ここではインストーラーを使用しています。

インストール後、GitBashを起動し以下を実行してGo用の環境変数を追加します。

```
環境変数の設定
$ echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bash_profile
$ echo 'export PATH=$PATH:$(go env GOPATH)/bin' >> ~/.bash_profile
$ echo 'export GOBIN=$HOME/go/bin' >> ~/.bash_profile

設定の反映
$ source ~/.bash_profile
```

Windowsでもgoreが使用できます。Linuxと同様にインストールします。

```
GOのREPLをインストール
$ GO111MODULE=off go get -u github.com/motemen/gore/cmd/gore

GitBashでは挙動がおかしい場合があるので、コマンドプロンプトを使用します。
> gore
gore version 0.4.1  :help for help
gore>
gore> :q
```

# vim-goのインストール（Windows用 補足）
vim-goのインストールについてはLinuxでの手順とほぼ同様のため、まずはそちらを参照してください。
以下はWindowsでの設定時に発生したエラー?の補足です。

##補足1：curl実行失敗
curlコマンドの実行時に以下のようなメッセージが表示される場合があります。

```
$ curl -fLo ~/.vim/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
You don't have permission to create C:.
```

GitBashの起動は、「フォルダを開く - 右クリック - Git Bash Here」で起動することが多いですが、
その際に保存する場所(今回は`~/.vim`)でGitBashを起動することで問題なく実行できました。

自分の場合、Cドライブ、Dドライブに分割しており、
保存する場所がCドライブになのに、GitBashの起動をDドライブで実行したため、
上記のようなメッセージが表示されたようです。

## 補足2：GoInstallBinaries実行時のエラー
WindowsではLinuxで設定していない環境変数`GOBIN`を設定しています。
設定していない場合`:GoInstallBinaries`の実行時に以下のようなメッセージが出力されました。

`vim-go: installing finished!`と最後に出力されるため、
成功したかのように見えますが、goのファイルを開くと初回と同様のエラーが表示され`:GoInstallBinaries`の実行を再度求められます。

```
vim-go: gogetdoc not found. Installing github.com/zmb3/gogetdoc to folder C/bin/
vim-go: guru not found. Installing golang.org/x/tools/cmd/guru to folder C/bin/
vim-go: gopls not found. Installing golang.org/x/tools/gopls@latest to folder C/bin/
Error installing golang.org/x/tools/gopls@latest: Fetching https://golang.org/x/tools/gopls?go-get=1^@Parsing meta tags from https://golang.org/x/tools/gopls?go-get=1 (status code 200)^@get "golang.org/x/tools/gopls": f
ound meta tag get.metaImport{Prefix:"golang.org/x/tools", VCS:"git", RepoRoot:"https://go.googlesource.com/tools"} at https://golang.org/x/tools/gopls?go-get=1^@get "golang.org/x/tools/gopls": verifying non-authoritativ
e meta tag^@Fetching https://golang.org/x/tools?go-get=1^@Parsing meta tags from https://golang.org/x/tools?go-get=1 (status code 200)^@go: finding golang.org/x/tools/gopls v0.1.3^@Fetching https://golang.org/x/tools?go
-get=1^@Parsing meta tags from https://golang.org/x/tools?go-get=1 (status code 200)^@get "golang.org/x/tools": found meta tag get.metaImport{Prefix:"golang.org/x/tools", VCS:"git", RepoRoot:"https://go.googlesource.com
/tools"} at https://golang.org/x/tools?go-get=1^@go: finding golang.org/x/tools v0.0.0-20190710153321-831012c29e42^@Fetching https://golang.org/x/net?go-get=1^@Fetching https://golang.org/x/sync?go-get=1^@Parsing meta t
ags from https://golang.org/x/net?go-get=1 (status code 200)^@get "golang.org/x/net": found meta tag get.metaImport{Prefix:"golang.org/x/net", VCS:"git", RepoRoot:"https://go.googlesource.com/net"} at https://golang.org
/x/net?go-get=1^@Parsing meta tags from https://golang.org/x/sync?go-get=1 (status code 200)^@get "golang.org/x/sync": found meta tag get.metaImport{Prefix:"golang.org/x/sync", VCS:"git", RepoRoot:"https://go.googlesour
ce.com/sync"} at https://golang.org/x/sync?go-get=1^@go: finding golang.org/x/net v0.0.0-20190620200207-3b0461eec859^@go: finding golang.org/x/sync v0.0.0-20190423024810-112230192c58^@Fetching https://golang.org/x/crypt
o?go-get=1^@Fetching https://golang.org/x/text?go-get=1^@Fetching https://golang.org/x/sys?go-get=1^@Parsing meta tags from https://golang.org/x/text?go-get=1 (status code 200)^@get "golang.org/x/text": found meta tag g
et.metaImport{Prefix:"golang.org/x/text", VCS:"git", RepoRoot:"https://go.googlesource.com/text"} at https://golang.org/x/text?go-get=1^@Parsing meta tags from https://golang.org/x/crypto?go-get=1 (status code 200)^@get
 "golang.org/x/crypto": found meta tag get.metaImport{Prefix:"golang.org/x/crypto", VCS:"git", RepoRoot:"https://go.googlesource.com/crypto"} at https://golang.org/x/crypto?go-get=1^@Parsing meta tags from https://golan
g.org/x/sys?go-get=1 (status code 200)^@get "golang.org/x/sys": found meta tag get.metaImport{Prefix:"golang.org/x/sys", VCS:"git", RepoRoot:"https://go.googlesource.com/sys"} at https://golang.org/x/sys?go-get=1^@go: f
inding golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2^@go: finding golang.org/x/text v0.3.0^@go: finding golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a^@go: downloading golang.org/x/tools v0.0.0-20190710153
321-831012c29e42^@go: extracting golang.org/x/tools v0.0.0-20190710153321-831012c29e42^@go: downloading golang.org/x/tools/gopls v0.1.3^@go: extracting golang.org/x/tools/gopls v0.1.3^@go: downloading golang.org/x/sync
v0.0.0-20190423024810-112230192c58^@go: extracting golang.org/x/sync v0.0.0-20190423024810-112230192c58^@cannot install, GOBIN must be an absolute path^@
vim-go: could not find 'gopls'. Run :GoInstallBinaries to fix it
function <SNR>13_GoInstallBinaries[133]..go#lsp#Restart の処理中にエラーが検出されました:
行    7:
E18: 予期せぬ文字が :let にありました
vim-go: fillstruct not found. Installing github.com/davidrjenni/reftools/cmd/fillstruct to folder C/bin/
vim-go: godef not found. Installing github.com/rogpeppe/godef to folder C/bin/
vim-go: motion not found. Installing github.com/fatih/motion to folder C/bin/
vim-go: errcheck not found. Installing github.com/kisielk/errcheck to folder C/bin/
vim-go: dlv not found. Installing github.com/go-delve/delve/cmd/dlv to folder C/bin/
vim-go: gocode not found. Installing github.com/mdempsky/gocode to folder C/bin/
vim-go: impl not found. Installing github.com/josharian/impl to folder C/bin/
vim-go: golangci-lint not found. Installing github.com/golangci/golangci-lint/cmd/golangci-lint to folder C/bin/
vim-go: gotags not found. Installing github.com/jstemmer/gotags to folder C/bin/
vim-go: gorename not found. Installing golang.org/x/tools/cmd/gorename to folder C/bin/
vim-go: goimports not found. Installing golang.org/x/tools/cmd/goimports to folder C/bin/
vim-go: gocode-gomod not found. Installing github.com/stamblerre/gocode to folder C/bin/
vim-go: gomodifytags not found. Installing github.com/fatih/gomodifytags to folder C/bin/
vim-go: keyify not found. Installing honnef.co/go/tools/cmd/keyify to folder C/bin/
vim-go: golint not found. Installing golang.org/x/lint/golint to folder C/bin/
vim-go: iferr not found. Installing github.com/koron/iferr to folder C/bin/
vim-go: asmfmt not found. Installing github.com/klauspost/asmfmt/cmd/asmfmt to folder C/bin/
vim-go: gometalinter not found. Installing github.com/alecthomas/gometalinter to folder C/bin/
vim-go: installing finished!
```

メッセージ内容を見ると以下の内容があり、「GOBINは絶対パスである必要があります」とのことです。
> Error installing <中略> cannot install, GOBIN must be an absolute path
> vim-go: could not find 'gopls'. Run :GoInstallBinaries to fix it

# おわり
これで一通りGoの環境ができました。
今回は以上です。

# 参考
https://golang.org/doc/install
https://golang.org/dl/
https://stupiddog.jp/note/archives/1148
https://stupiddog.jp/note/archives/1147
https://github.com/hnakamur/vim-go-tutorial-ja
https://motemen.hatenablog.com/entry/2015/02/go-repl-gore
https://github.com/motemen/gore
https://www.slideshare.net/zaruhiroyukisakuraba/go-80884259
https://budougumi0617.github.io/2018/05/30/debug-go-by-vim-go-and-delve/
https://qiita.com/shiro01/items/a300b6d5b572a314ce5e
https://chocolatey.org/docs/commands-reference