Goオフィシャルチーム作成の依存関係管理ツール dep を試してみた

go lang

dep とは

Goでは依存関係管理ツールとして、glideなどが有名ですが、depはGoオフィシャルチームによって作成中の依存関係管理ツールです。将来的に go dep のように go コマンドのサブコマンドとして取り込まれる可能性も期待できるツールです。

長い間 Pre-alpha となっていましたが、いつの間にか dep is safe for production useとなってましたので試してみたいと思います。

インストール

# go get でインストール
go get -u github.com/golang/dep/cmd/dep

# Macの場合brewも用意されています
brew install dep

使い方

# 最初の一回のみ行います。現在の構成を解析し`Gopkg.toml`、`Gopkg.lock`が生成されます。
dep init

# パッケージをvendorディレクトリ以下にインストールします
dep ensure

# 新しいパッケージを依存関係に追加しインストールを行う
dep ensure -add github.com/foo/bar

# パッケージをアップデートする
dep ensure -update github.com/foo/bar

# 現在の状態を出力する
dep status

Gopkg.toml

# Gopkg.toml example
#
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
# for detailed Gopkg.toml documentation.
#
# required = ["github.com/user/thing/cmd/thing"]
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
#
# [[constraint]]
#   name = "github.com/user/project"
#   version = "1.0.0"
#
# [[constraint]]
#   name = "github.com/user/project2"
#   branch = "dev"
#   source = "github.com/myfork/project2"
#
# [[override]]
#  name = "github.com/x/y"
#  version = "2.4.0"

[[constraint]]
  name = "github.com/spf13/cobra"
  revision = "cb731b898346822cc0c225c28550a8a29d93c732"

参考 docs/Gopkg.toml.md

required

required = ["github.com/user/thing/cmd/thing"]

transitivery dependency(プロジェクトのコードから直接参照されていないが、必要)なパッケージを記述します。

dep ensure ではsrcを取得してくるのみで実行ファイルをコンパイルしません。  

実行ファイルをインストールしたい場合はパッケージのインストールディレクトリ(mainパッケージが置かれているディレクトリ)に移動し(cd vendor/github.com/user/thing/cmd/thing) go install . でインストールする必要があります。

ignored

ignored = ["github.com/user/project/badpkg"]

プロジェクトのソースからの静的解析で無視するパッケージを指定します。既にインストールされているパッケージが更にインストールされるのを抑制できます。

metadata

[metadata]
key1 = "value that convey data to other systems"
system1-data = "value that is used by a system"
system2-data = "value that is used by another system"

depによって使われないデータを設定できます。(具体的な使用例はわかりませんでした)

constraint

[[constraint]]
  # パッケージの import パスです。
  name = "github.com/user/project"

  # version、branch、revisionのいずれかでパッケージを指定できます
  version = "1.0.0"
  branch = "master"
  revision = "cb731b898346822cc0c225c28550a8a29d93c732"

  # パッケージの取得先を変更できます。取得先を変更してもimportにはnameのパスを書きます。
  # (vendorディレクトリ以下のパスは変わりません)
  source = "https://github.com/myfork/package.git"

  # メタデータは constraint の下にもかけます。
  [metadata]
  key1 = "value that convey data to other systems"
  system1-data = "value that is used by a system"
  system2-data = "value that is used by another system"

direct dependency(プロジェクトのコードから直接されている)依存関係を記載します。

override

[[override]]
  name = "github.com/user/project"
  branch = "master"
  source = "https://github.com/myfork/package.git"

  [metadata]
  key1 = "value that convey data to other systems"
  system1-data = "value that is used by a system"
  system2-data = "value that is used by another system"

[[constraint]] と同じ構造です。すべての設定に優先して適用されます。

version

[[constraint]]
  name = "github.com/pkg/errors"
  version = "=0.8.0"

semver で使えるバージョニングが使えます。

参考: https://github.com/Masterminds/semver#basic-comparisons

オペレーター 説明
= 指定したバージョンを固定 1.2.3(1.2.3)
>= 指定したバージョン以上 1.2.3(1.2.3〜)
<= 指定したバージョン以下 1.2.3(〜1.2.3)
- 指定したバージョンの間 1.2.3 - 1.3(1.2.3〜1.3)
*(x) ワイルドカード 1.2.*(1.2.0〜 <1.3)
~ パッチレベルの範囲指定。末尾以外の数値が固定され末尾の数値が上がっていきます。 ~1.2.3(1.2.3〜 <1.3)
^ メジャーレベルの範囲指定。先頭の数値のみが固定され、それ以外の数値が上がっていきます ^1.2.3(1.2.3〜 <2)

※ 一部のオペレーターを抜粋してます

dep initの動き

ソースや既存の依存関係管理ツールからパッケージの利用状況を解析します。対応しているツールは(glide, godep, vndr, govend)です。

既存のvendor/ディレクトリを_vendor-${TIMESTAMP}にリネームし退避させ、新しくvendor/ディレクトリ以下に依存しているパッケージをインストールします。

まとめ

metadata fileのフォーマットがJSONからtomlになったり、かなり大きな変更があったそうですが、現状有効なmetadata file は将来にも有効であるとREADMEにも書かれているので、metadata fileについては今後大きな変更はないと思われます(たぶん)

ただ、現在も絶賛開発中で、特に API については 1.0.0 のリリースまでに下位互換性を崩していくと示唆されているので注意が必要です。