go vendoring
tldr;
- golang でコンパイル時に
GO15VENDOREXPERIMENT
という環境変数を設定すると vendoring が有効になる。 - 1.6 でデフォルト有効になるので、配置を変更するだけで透過的に使える
- 今は周辺ツールの対応中で実用は厳しいが 1.6 が出るタイミングには出そろうはず。
vendoring?
vendoring とは依存ライブラリを自分のリポジトリに取り込むこと。
不意に依存ライブラリが変更されるような場合に強くなる。
一方で追従を意図的に行わない限りずっと古いバージョンを使うことになるというデメリットもある。
主には長期メンテナンスが必要でリポジトリのビルドを安定的に行いたいような場合に行われる。
google の内部リポジトリではこの方式の vendoring を行っているらしい。 (参考)
実践
Source
main.go を以下内容で ~/go/src/github.com/yoru9zine/vendoring-test に置く。
package main import ( "github.com/yoru9zine/somelib" ) func main() { somelib.Something() }
自リポジトリの somelib に依存している。
somelib はとりあえず動けばいいので以下。
package somelib func Something() { }
Directory
普通の配置ならこうなる。
~/go/src/github.com/yoru9zine ├── vendoring-test └── somelib
vendoring するならこう。
~/go/src/github.com/yoru9zine └── vendoring-test └── vendor/github.com/yoru9zine/somelib
リポジトリ内に vendor というディレクトリを作成し、その下で GOPATH と同じような配置を行う。 vendor ディレクトリに取り込むような形になる。
Build
このままビルドしてもエラーになるので、GO15VENDOREXPERIMENT
を使う必要がある。
といっても環境変数を有効にしてビルドするだけなので以下でOK。
GO15VENDOREXPERIMENT=1 go build
問題点
vendoring 自体の機能ではなく周辺ツールの話になるが、コーディング時のツール対応がまだ完全でない。
具体的には goimports 等が vendoring を理解しないので書くのがつらい。
GO15VENDOREXPERIMENT
は 1.6 でデフォルト有効になるので、各ツールは絶賛対応中という状態 (参考)
もう少しすれば対応も終わると思われるが、普及の壁として大きい。
これ以外にもサイズの大きいリポジトリを取り込むのに抵抗があるというケースもあると思うが、これについては納得して使うしかない。
その他
vendoring の仕組みは GOPATH 以外においたディレクトリではうまく動かないので注意。
書き捨てだと /tmp とかに置いてしまうんだけど、こういうケースでは vendoring は機能しない。