あらかじめ予防線を張っておくと Go 言語の開発環境で「これ!」という正解はない。特にチームで開発している場合は,チームの流儀に従うのが最善だと思っている。なので,この記事は「こういうやり方もあるよ」という参考程度に見ていただけるとありがたい。

GOPATH の構造

皆さん御存知の通り,環境変数 GOPATHGo 言語パッケージや開発環境を指定するものだが,実は複数のパスを指定できる。Windows 環境ならこんな感じにセミコロン(;)で区切って指定する。

SET GOPATH=C:\path\to\go-packages;C:\go-wkspace

Linux 等ならこんな感じにコロン(:)で区切ればいいだろうか。

export GOPATH=/usr/local/go-packages:~/go-wkspace

GOPATH に複数のパスを指定した場合, go get コマンドで導入した(依存関係を含む)パッケージ群は最初に指定したパスの配下に格納される。上の例なら go-packages フォルダがそれに該当する。

今回はこれを利用する。

Go 言語ツールチェーンを分離する

つまり開発に必要で go get コマンドで導入するツール群(ここでは仮に「Go 言語ツールチェーン」と呼ぶことにする)は go-packages フォルダに集約させ,自身の開発環境は go-wkspace フォルダ配下で行うようにするのである。もちろん導入した Go 言語ツールチェーンに PATH を通しておくのも忘れずに。

SET PATH=%PATH%;C:\path\to\go-packages\bin

この方法なら Go 言語ツールチェーン導入時に依存関係で導入されるパッケージ群によって開発環境が汚染されるのを防ぐことができる。

開発で使う外部パッケージは dep で管理する

じゃあ自身が作るパッケージが依存している外部パッケージはどうやって管理するのかというと, go get コマンドではなく, dep を使う。 dep で管理するパッケージを追加するには,以下のようにすればよい。

$ dep ensure -add github.com/pkg/errors

もしくは Gopkg.toml ファイルを直接いじって dep ensure で更新するか。

Gopkg.toml
[[constraint]]
  name = "github.com/pkg/errors"
  version = "^0.8.0"

これで外部パッケージは vendor フォルダ以下に一括管理できる。

利点と欠点

このやり方の利点は「プロジェクトごとに環境を切り替えなくていい」ということに尽きる。自身の開発環境は(上の例で言うところの) go-wkspace フォルダ配下に集約されるため「GOPATH 汚染」みたいなことは一切気にしなくてよくなる。

また開発環境の管理に使用するツールとその手順が少ないのも利点に挙げていいかもしれない。 dep は事実上の公式ツールなので,余程のことがない限りなくなることはないだろう(go コマンドに組み込まれることはあるかもしれないがw)。

欠点は利点の裏返しで,自身の開発リポジトリがどうしてもモノリシックな構成になってしまうことである。複数のプロジェクトを同時に抱えている場合は,そのプロジェクト同士の関係管理が煩雑になりがちである。

もっともモノリシックなリポジトリ構成は近年見直されつつあるようなので,運用次第では帳消しにできる欠点ではある。それに今はプロジェクト環境の分離は docker などで仮想環境ごとやっちゃうのが主流みたいだし。

参考

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.