depを触ってみたよ

the "official experiment" dependency management tool for the Go languageというdepを触ってみた。
これがgoのライブラリ管理ツールでは公式になっていく模様。
公式ドキュメントを見ながらやってみる。

installation

macの場合、crewで入る。

$ brew install dep
$ brew upgrade dep

その他の場合は下記コマンドで良さそう。
アーキテクチャ、OS、GOPATHなんかに応じてインストールしてくれる模様。

$ curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh

depのコマンドを確認

こんな感じ

bash-3.2$ dep
Dep is a tool for managing dependencies for Go projects

Usage: "dep [command]"

Commands:

  init     Set up a new Go project, or migrate an existing one
  status   Report the status of the project's dependencies
  ensure   Ensure a dependency is safely vendored in the project
  version  Show the dep version information
  check    Check if imports, Gopkg.toml, and Gopkg.lock are in sync

Examples:
  dep init                               set up a new project
  dep ensure                             install the project's dependencies
  dep ensure -update                     update the locked versions of all dependencies
  dep ensure -add github.com/pkg/errors  add a dependency to the project

Use "dep help [command]" for more information about a command.

使ってみる

今回のサンプルに使うプロジェクトを作ってそこに移動する。
このプロジェクトが他の人やプロジェクトに利用されることを想定している場合には下記の場所に作る。

$ mkdir -p $GOPATH/src/github.com/<あなたの名前>/<プロジェクト名>
$ cd $GOPATH/src/github.com/<あなたの名前>/<プロジェクト名>

今回のプロジェクトが他で利用されることはないので、今回はここに作る。

$ mkdir -p $GOPATH/src/<プロジェクト名>
$ cd $GOPATH/src/<プロジェクト名>

dep initコマンドを実行し、現在のプロジェクトを解析して初期化する。

$ dep init
$ ls
Gopkg.lock      Gopkg.toml      vendor

vendorは空のディレクトリで、今後depで入るパッケージはここに。
Gopkg.toml は、現在のプロジェクトの依存関係を記述してあるファイル。

$ cat Gopkg.toml
# Gopkg.toml example
#
# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
# 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"
#
# [prune]
#   non-go = false
#   go-tests = true
#   unused-packages = true


[prune]
  go-tests = true
  unused-packages = true

Gopkg.lock は、プロジェクトが依存しているパッケージの依存関係がバージョンなんかも合わせて記載されている?

$ cat Gopkg.lock
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.


[solve-meta]
  analyzer-name = "dep"
  analyzer-version = 1
  input-imports = []
  solver-name = "gps-cdcl"
  solver-version = 1

ここからどんな作業でどんな変化が生まれるをかを知るためgit管理して進める。
試しに、ginでwebサーバーを構築して進める。
プロジェクトのルートディレクトリにapp.goを作る。(ドキュメント丸写し)

package main

import "github.com/gin-gonic/gin"

func main() {
    r := gin.Default()
    r.GET("/ping", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "pong",
        })
    })
    r.Run() // listen and serve on 0.0.0.0:8080
}

ここでプロジェクトの依存関係をインストールしてくれるというdep ensureを叩くと、、、

$ dep ensure -v
# Gopkg.lock is out of sync with Gopkg.toml and project imports:
github.com/gin-gonic/gin: imported or required, but missing from Gopkg.lock's input-imports

Root project is "dep_sample"
 1 transitively valid internal packages
 1 external packages imported from 1 projects
(0)   ✓ select (root)
(1)     ? attempt github.com/gin-gonic/gin with 1 pkgs; 22 versions to try
(1)         try github.com/gin-gonic/gin@v1.2
(1)     ✓ select github.com/gin-gonic/gin@v1.2 w/3 pkgs
(2)     ? attempt github.com/gin-contrib/sse with 1 pkgs; 1 versions to try
(2)         try github.com/gin-contrib/sse@master
...

# Bringing vendor into sync
(1/8) Wrote gopkg.in/go-playground/validator.v8@v8.18.2: new project
(2/8) Wrote gopkg.in/yaml.v2@v2.2.1: new project
(3/8) Wrote github.com/gin-contrib/sse@master: new project
(4/8) Wrote github.com/gin-gonic/gin@v1.2: new project
(5/8) Wrote github.com/golang/protobuf@v1.1.0: new project
(6/8) Wrote github.com/mattn/go-isatty@v0.0.3: new project
(7/8) Wrote github.com/ugorji/go@v1.1.1: new project
(8/8) Wrote golang.org/x/sys@master: new project

依存関係のあるパッケージをベンダー下にインストールしてきてくれる。
Gopkg.lock にも依存関係がたくさん記述されている。
vendorは重いので、.gitignoreにしておくといいかもしれない。

おわりに

プロジェクトをdep initして、パッケージを追加したらdep ensureする。という方針でなんとなくいいのかな。
Gopkg.tomlについてもちゃんと調べよう。

その他

goまだまだこれからという人はこの記事なんかも読んでみるとよいのかも。