One minute
Go言語の依存パッケージ管理の闇
複数人で開発している場合、各メンバーのローカル環境が揃っていることは重要なこと。
OSや言語のランタイムのバージョンはもちろんだけど、
依存しているパッケージのバージョンを同じにしておくことは重要。
俺はテスト通ってるけどTravisさんでは通らないとかマジいらっとするし、
バグった時の再現性とかもろもろ問題が出てくるので、環境の同期は重要。
例えば、JavaではMaven+pom.xmlやGradle+build.gradle、Nodeならnpm+package.jsonなところを、 Goではどうやるんだっていう話。
Goで依存パッケージを取得する
go get github.com/google/go-github/github
以上。
簡単。これは捗る!
と思いきや、実際の開発ではいろいろ問題が発生する。
バージョンいくつなんだよ問題
Goは、パッケージ取得の仕組み(go get hoge/hoge
のこと)は言語レベルで存在するが、
パッケージの列挙とバージョンを管理する仕組みは存在しない。
「このプロジェクトで使われているパッケージはA(ver0.9)とB(ver1.2)である。」
というのを表現する方法は無い。
よって各メンバーが、README等をみながら、
go get A
go get B
go get C
...
をぽちぽちやらなくてはいけない。
また、go get したタイミングによっては依存しているパッケージの別のバージョンが入ってしまう。
なんてったって、go get にはバージョンを指定しないのだから、何が落ちてきてるのかわからん。
Goの思想としては常に最新バージョン使おうぜ、ということらしいが、
そのことと、メンバー間の環境の同期はまた別の話だよね。
別のプロジェクトでも使ってる問題
Goのプロジェクトとして、AとBがあって、両方でパッケージKを使ってるとする。
「AではK:ver1.1.2を使って、BではK:ver1.1.3を使う」
ということはできない。
GOPATHをそれぞれで設定しておいて、いじるときにいちいち切り替えれば出来るんだろうけど、
基本的にはGOPATHは一個だけ設定するのが良いとされているので、AとBは同じバージョンのKを参照せざるを得なくなる。
これは辛い。。
Godep
そこで登場するのがプロジェクト毎に依存関係を指定、管理できるツール、Godep。
安心のGitHub製。
そのプロジェクトで使っているパッケージとバージョン(正確にはコミットsha)を
godep save ./...
で記録(その時点のスナップショット的な感じ)できる。
新しく Godeps
と Gedeps/_workspace
というディレクトリと、Godep.json
というJSONファイルが生成される。
このJSONが、mavenでいうpom.xml、npmでいうpackage.json にあたるもので、基本手動でいじらない。
このGodep.json
はGitのバージョン管理対象にするが、_workspace
ディレクトリは.gitignoreに追記しておく。
Godep.json に更新があった場合、他のメンバーは、
godep restore
で同じパッケージの同じバージョンを GOPATH配下に配置できる。
これは捗る!
ここで言う、他のメンバーとは、Travis等のCIツールも含まれる。
ちなみに、GodepはTravisが対応しているので、Goをビルドする時にちょっと楽。
まとめ
Java = maven + pom.xml
Node = npm + package.json
Golang = Godep + Godep.json
で今のところいいのでは。
Goには、依存パッケージを取得する仕組みはあるが、依存の列挙、バージョンを管理する仕組みはない。
なので、別途Godepなどのツールで管理しとかないとチーム開発やCIは辛いかも。