mattn/gomにGoのvendoringサポートが追加されました

以前Go言語のDependency/Vendoringの問題と今後.gbあるいはGo1.5 | SOTAを読んだのですが、その時は様子見にしていました。

しかし、仕事でGoを書くとなるとやはりVendoringは必要だろうと思い、遅ればせながら今回gb, tools/godep, mattn/gomを試してみました。

gbの不満

gbの例を見ると、自分のプロジェクトのトップディレクトリに src/cmd あるいは src/github.com/ユーザID/プロジェクト名 というディレクトリを作ってそこにソースを置く必要があるようです。

FAQにもWhy can't I place source in $PROJECT/src?という項があるので、これは仕様のようです。

でもこれだと、自分のプロジェクトを他のプロジェクトで使いたい時に go get で使えないですよね。 FAQに "Can I use gb if I am working on a Go library?" とか "Copying code is gross! Can I use git submodules?" とかあるんですが、git submoduleにせよgit subtreeにせよ面倒だなと思いました。

godepsの不満

tools/godep の"Go 1.5 vendor/ experiment"の項を読んで試してみたところ、go build が使用する環境変数 GO15VENDOREXPERIMENTexport GO15VENDOREXPERIMENT=1 のように設定しておくと、そうでないときは Godeps/_workspace/ に置かれる依存ライブラリが vendor/ 以下に置かれるようになることがわかりました。

vendor/.gitignore で除外してコミットしたいので、後から Godeps/Godeps.json から vendor/ を再構成する必要があります。READMEには書いてないですが、 godep get でダウンロードして、 godep savevendor/ に反映できることがわかりました。

ただ、 godep get でダウンロードする先は環境変数 GOPATH で指しているディレクトリなんですよね。 godep save$GOPATH から vendor/ に反映するコマンドです。

ちなみに godep restore というコマンドもありますが、これは vendor/ から $GOPATH に反映します。GoにVendoringサポートがなかったときは、これで $GOPATH に反映してから go build という手順も妥当な気がしますが、Vendoringがある今となってはグローバルの $GOPATH 配下は触らずに vendor/ 以下を直接更新したいところです。

とりあえずイシューDownload dependency to vendor/ directory with godep get when GO15VENDOREXPERIMENT=1 · Issue #299 · tools/godep を立ててみたところ、同じことを考えていたというコメントがついていました。

gomならバッチリ!

mattn/gomを見るとConsider adding GO15VENDOREXPERIMENT support · Issue #51 · mattn/gomというイシューがあったので、対応するコードを書いて Support go15vendorexperiment by mattn · Pull Request #57 · mattn/gomで追加修正の上マージしていただきました。

gom install では内部的に go get を呼び出しているので、ターゲットディレクトリを vendor/ にしても vendor/src/github.com/... のように src フォルダが作られてしまいます。上の修正では対処療法的に gom install 内で vendor/*vendor/src/* に移動して、終わったら vendor/src/*vendor/* に移動して対応しています。

正確には最初の移動では vendor/ 以下の bin, pkg, src は除外しています。

これで、 export GO15VENDOREXPERIMENT=1 さえしておけば、 gom install$GOPATH 配下は変更せずに直接 vendor/ 以下を更新できるようになりました。

READMEには書いてないですが、 gom lock を実行すれば Gomfile.lock が作られて、以降の gom install では依存ライブラリのバージョンを正確に反映できます。

ということで、gomならバッチリ私の希望を満たしてくれることがわかりました。 mattnさん、便利なツールをありがとうございます!