go

MacにGo言語の開発環境を構築する【準備編】 (direnv+go1.5Vendoring+glide)

Go言語の開発をしようとして色々調べたんだけど結構大変だったのでまとめ。
基本的にMacでの作業を前提としています。

Goのインストール

MacならHomebrewで一発。

$ brew install go

GOPATH環境変数?

Goでは、GOPATHという環境変数を設定すると、そこが作業スペースとなります。
ひとまずどこでも好きな場所をGOPATHに設定しましょう。
また、$GOPATH/binをPATHに通しておきます。

$ export GOPATH=$HOME/go
$ export PATH=$PATH:$GOPATH/bin

同様の内容を.bashrcなどにも入れておきます。

すると、

$ go get [package name]

とすることで、importできるパッケージが自動的にダウンロードしてインストールするという便利な仕組みがあります。

例えば、revelというWebフレームワークの場合、

$ go get github.com/revel/revel

とするだけで依存関係を含め自動的にダウンロード&インストールできます。
Node.jsでいうところのnpmとかRubyのgemとかみたいな感じですね。

しかし、ちょっと待ってください。

npmの場合は、installの際に -g をつけるかどうかでグローバル領域かローカルのディレクトリかインストール先を選ぶことができますが、
Goの場合、これらのパッケージは自動的にGOPATHにどんどん入っていってしまいます。

これの何が問題かというと...

  • プロジェクトごとに作業スペースを分けづらい
  • プロジェクトごとに何のパッケージに依存しているかが明らかでない
  • 全てGOPATHに入ってしまうので、例えばプロジェクト単位で特定のパッケージのバージョンを分けたりできない
  • 要するにビルドの再現性が保証されない

解決するには、プロジェクトごとに作った作業ディレクトリをそれぞれGOPATHにする必要があります。

direnvを使う

これを実現するためのツールが運よくあります!
direnvというツールがそれなのですが、これが本当に素晴らしい。

  • ディレクトリごとに設定ファイルで環境変数が設定できる
  • ディレクトリに入ったら自動的に設定される(サブディレクトリにも適用)
  • ディレクトリから抜けたら自動的に解除される

なんかもう、このためにあるようなツールですね!
プロジェクトルートに設定ファイルを置き、GOPATHにカレントディレクトリを追加すればよさそうです。

では、早速direnvをインストールします。

$ brew install direnv
$ echo 'eval "$(direnv hook bash)"' >> ~/.bashrc

上記はBashの場合です。別のシェルを使っている場合はevalの書き方が違うので公式サイトを参照してください。

先ほどの設定ファイルを作るには、

$ cd /projects/some_project
$ direnv edit .

とします。"direnv: $EDITOR not found." というエラーが出た場合は、環境変数EDITORにviか何かを設定してください。

うまくいけばエディタが立ち上がりますので、

export GOPATH=$(pwd):$GOPATH

という内容を書いて保存しておきます。

direnv: loading .envrc
direnv: export +GOPATH

と出れば成功です。

Vendoring

ここまででだいぶ改善されましたが、まだ1点気になるところがあります。
それは、この状態では自分で開発していてリポジトリにコミットしたいコードと、依存ライブラリとが同じ場所に混在してしまうという点です。

理想を言うと、以下のような構成にしたいわけです。

- $GOPATH/src/app
  |
  |-- main.go
  |
  |-- subpackage
  |    |
  |    |-- foo.go
  |
  |-- vendor
       |-- github.com
            |
            |-- bar
                  |
                  |-- ... etc.

こうすると、vendor以下が依存している外部ライブラリだとはっきりわかります。

実は、Go1.5以降ではこういう構成でビルドできる機能がすでにあります!!

それは、環境変数 GO15VENDOREXPERIMENT=1 を設定するだけで有効になります。
そこで、せっかくなので先ほどのdirenvの設定を追加します。

export GOPATH=$(pwd):$GOPATH
export GO15VENDOREXPERIMENT=1

これでOKです。

glideを使う

ただし、このままではgo getしてもvendorではなく、$GOPATH/src内にパッケージがインストールされてしまいます...。

何かいい方法はないものか、と調べていたところ見つけたのが、glideです。

インストール方法はいつものHomebrewで。

$ brew install glide

これは、vendor内のパッケージをYAMLで管理し、それらを自動的にインストールできるようにするものです。

インストール先は、YAMLのあるディレクトリ(glideを実行するディレクトリ)の下のvendor以下です。

使い方は、まず

$ glide create

とソースディレクトリで実行すると、ソースコードのimport文を解析して自動的にYAMLファイル(glide.yaml)が生成されます。

その後、

$ glide up

とすることで自動的にインストールされていきます。

新しくパッケージを入れたい場合は、go getではなく、

$ glide get github.com/Masterminds/cookoo

のようにすると、YAMLへの追加とvendor以下へのインストールが自動的に行われます。

どうでしょうか。かなり理想的な環境になったと思います!

.gitignore

glide.yamlでパッケージを管理するので、vendor以下のファイルはリポジトリへのコミットは不要になります。ということで、.gitignoreに vendor/ を追加しておきましょう。

実際、glideのリポジトリ自体もそのようにしているようです。

おわりに

お気楽にちょっとしたツールを作るだけなら適当にGOPATHを設定するだけでいいと思いますが、ちゃんと構成を管理できるように構築するのはなかなか大変でした・・・。

次回は、IntelliJを使って開発する環境を整えます。

参考サイト

そろそろ真面目に Golang 開発環境について考える — GOPATH 汚染問題 - Qiita

Go言語のDependency/Vendoringの問題と今後.gbあるいはGo1.5 | SOTA

glide - パッケージ管理のお困りの方へ - - Qiita

LINEで送る
Pocket

MacにGo言語の開発環境を構築する【準備編】 (direnv+go1.5Vendoring+glide)」への2件のフィードバック

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です