Go 言語の vendoring ツールとして Glide を使い始めました。

vendoring とは

vendoring とは、アプリケーションが依存する 3rd-Party パッケージ/ライブラリのソースコードそのものを自身のレポジトリに含めて管理する試みのこと、を指す用語の模様です(たぶん)。

Node.js における package.json に依存関係が書かれている状態だけでは vendoring ではないです。node_modules ディレクトリ自体をレポジトリの管理対象に含めることで vendoring ができている状態、と言えるようになります。

Node.js (というか npm) に限らず、node_modules 的な役割のディレクトリは .gitignore で無視するのがよくあるプロジェクトの管理方法です。vendoring 自体の厳密な定義の話や、vendoring することの是非については言及の対象外として、Go 言語で vendoring を行う話に進めます。

2点だけ補足をすると、Go 言語は外部パッケージを go get で Github などのレポジトリから直接ソースコードを取得してくる方式になっており、元来 vendoring とは相性がよいものでした。加え、npm の left-pad 問題もあり、多少プロジェクトのレポジトリが肥大化したとしても依存しているコードは自身の責任で保全できていたほうがいいだろうと考えたのが、vendoring を始めた動機です。

Go 1.6 のパッケージ管理について

Go 1.6 からの標準機能として、コンパイラが $GOPATH 以外に ./vendor ディレクトリ配下を探索するようになりました。この点の歴史的経緯については既に情報が多いので割愛します。これから Go を始める方はそうなったことだけ把握していれば問題無いと思います。

この標準機能に、いまでは主要な Go 言語の 3rd-Party パッケージが対応しています。人気があり現在もメンテナンスが続いていそうなパッケージをいくつか列挙します。

今回は Glide を採用しましたが最低限行うだけであればどれを選んで大差はないと思います。決めてとしては設定ファイルが YAML フォーマットだったのとコマンドがシンプルだった点です。

Glide の使い方

公式の glide/README.md に詳しいですので補足のみ行います。

インストール

Mac へのインストールについて、4月9日時点では最新バージョン 1.0.2 に対して brew install glide 可能なのは 1.0.0 でした。かつ、1.0.0 では golang.org/x/crypto など一部のレポジトリ情報の解釈に問題があるようでした(詳細未確認)。1.0.2 ではいまのところ問題がないので、各 OS 向けの最新版の Binary Packages を入手し利用することをお薦めします。

vendoring の開始

プロジェクトのルートディレクトリで以下のコマンドを実行します。

glide create
  • 依存関係の定義ファイルである glide.yaml ファイルが作成されます
  • vendor ディレクトリがなければ作成されます
  • 現在のソースコードの import 情報を元に、3rd-Party パッケージを vendor ディレクトリに向けに go get が行われます。パッケージ情報が glide.yaml に書き込まれます。

結果、以下のようなディレクトリ構成でパッケージが取得されます。go get した場合と同じです。

vendor
├── github.com
│   ├── BurntSushi
│   │   └── toml
│   │       ├── COMPATIBLE
│   │       ├── COPYING

glide.yaml については以下の公式ドキュメントが詳しいです。

各パッケージのアップデートは以下のコマンドを実行します。

glide up

Git submodule 化されてしまう問題への対処

glide create 及び glide up はいずれも対象のレポジトリ全体を取り込みます。Git の場合、.git ディレクトリも含まれます。 .git ディレクトリが存在する場合、Git submodule として認識されてしまい、レポジトリへの参照情報のみが含まれソースコードそのものが含まれません。これでは vendoring にならないので対処が必要になります。

glide up の際にオプションを指定します。

glide up --update-vendored --strip-vcs

コマンドは glide up -u -s と省略できます。--strip-vcs オプションは、 go get の後に各レポジトリの .git ディレクトリを削除するという単純な動作をします。

vendor ディレクトリ配下にある vendor ディレクトリを除外する --strip-vendor オプションもあります。

以上です。