govendorでvendoringしよう

vendoringとは

  • プロジェクト毎にimportするパッケージを保持する機能

vendoringが必要な理由

  • Goのパッケージは$GOPATH単位で共有されるので以下のケースで問題が出る
    • 同じ$GOPATHのプロジェクト同士で必要なパッケージのバージョンが異なる場合
    • 違う$GOPATHの同じプロジェクトでimportするパッケージのバージョンが異なる場合

Go1.5以降vendoringが導入

  • プロジェクト内のvendorディレクトリ以下のパッケージを優先してimportするように

vendoringのためのツール

  • Godep (⭐4087@github)
  • Glide (⭐3321@github)
  • govendor (⭐1310@github)

Godep

  • 古い
    • vendoring以前のツールのため、vendoringのプラクティスと噛み合っていない
    • 最近更新されていない
  • パッケージをアップデートすると$GOPATHが汚染される

Glide

  • パッケージをアップデートすると$GOPATHが汚染される
  • dotfilesをコピーする

govendor

  • 上記2つと比べてややマイナー

なぜgovendorを選んだか

1. 環境を汚染しない

パッケージの追加

$ govendor add {package}

=> $GOPATHからコピーするだけ

パッケージの更新

$ govendor update {package}

=> やっぱり$GOPATHからコピーするだけ

パッケージの取得

$ govendor fetch {package}

直接vendorにダウンロードする

パッケージの再現

$ govendor sync

定義ファイルから直接vendorにパッケージを展開する

2. ステータス

statusでパッケージを分類できる

ステータスの種類

    +local    (l) プロジェクト内にあるパッケージ
    +external (e) importされている、かつGOPATHにあるがvendoringされていないパッケージ
    +vendor   (v) vendoringされているパッケージ
    +std      (s) 標準ライブラリ

    +excluded (x) vendoringを禁止しているパッケージ
    +unused   (u) 使われていないパッケージ
    +missing  (m) importされているが、存在しないパッケージ

    +program  (p) mainパッケージ

    +outside  +external +missing
    +all      +all packages

ステータスは便利

$ cd $GOPATH/src/github.com/fluent/fluent-logger-golang
$ govendor list
 e  github.com/philhofer/fwd
 e  github.com/tinylib/msgp/msgp
 l  github.com/fluent/fluent-logger-golang/fluent
  m github.com/bmizerany/assert
$ govendor add +e # vendoringされていないパッケージをvendoring
$ govendor fetch +m # GOPATHに存在しないパッケージを取得
$ govendor remove +u # 使われていないパッケージをvendorから削除

まとめ

  • 環境 (GOPATH) を汚さない
  • パッケージをステータスで分類し、まとめて管理できる

govendorいいぞ