Goのパッケージマネージャのmanulの使い方 #golang

[manul](https://github.com/kovetskiy/manul)はGoのベンダリングのためのツールです。

manulの特徴は

- 依存パッケージをgit submoduleで管理する。
- ベンダリング用に実行ファイルをダウンロードする必要がない。
- メタファイルの追加が必要ない。
- Go gettable

一言で言えば「git submoduleをGoのために扱いやすくしてくるツール」です。

# 使い方

## インストール

```
go get github.com/kovetskiy/manul
```

`go get`でインストールします。

## 依存パッケージの一覧 manul -Q

依存パッケージの一覧を表示します。

```bash
$ l
total 16
drwxr-xr-x   5 kazu  staff   170B 12  9 14:35 .
drwxr-xr-x  84 kazu  staff   2.8K 12  9 14:34 ..
drwxr-xr-x  12 kazu  staff   408B 12  9 14:44 .git
-rw-r--r--   1 kazu  staff    13B 12  9 14:34 README.md
-rw-r--r--   1 kazu  staff   312B 12  9 14:43 main.go
$ manul -Q
github.com/labstack/echo
github.com/labstack/gommon
github.com/mattn/go-colorable
github.com/mattn/go-isatty
github.com/valyala/fasttemplate
```

## submoduleに追加 manul -I

`manul -Q`で表示されたパッケージを`manul -I`でsubmoduleへ追加します。
`manul -I github.com/labstack/echo`とかするとechoだけを追加することができます。

```bash
$ manul -I
2016/12/09 14:46:20 adding submodule for github.com/labstack/echo
2016/12/09 14:46:27 adding submodule for github.com/labstack/gommon
2016/12/09 14:46:29 adding submodule for github.com/mattn/go-colorable
2016/12/09 14:46:30 adding submodule for github.com/mattn/go-isatty
2016/12/09 14:46:32 adding submodule for github.com/valyala/fasttemplate
added 5 submodules
$ manul -Q
github.com/labstack/echo         95e1bd485f216ceb8d10e9f4cd3f65b49c1130ab
github.com/labstack/gommon       447fe7433567c785af957e549aadae2bf2000071
github.com/mattn/go-colorable    d228849504861217f796da67fae4f6e347643f15
github.com/mattn/go-isatty       30a891c33c7cde7b02a981314b4228ec99380cca
github.com/valyala/fasttemplate  3b874956e03f1636d171bda64b130f9135f42cff
```

# 依存パッケージのアップデート manul -U

`manul -U`で`manul -Q`で表示されるパッケージに対してアップデートをします。
殆どの場合はパッケージを指定してアップデートすると思います。

```bash
$ manul -U github.com/labstack/echo
2016/12/09 16:53:08 updating dependency github.com/labstack/echo
updated 1 dependency
```

# 依存パッケージの削除 manul -R

```bash
$ manul -R
2016/12/09 15:10:02 removing vendor github.com/labstack/echo
2016/12/09 15:10:02 removing vendor github.com/labstack/gommon
2016/12/09 15:10:02 removing vendor github.com/mattn/go-colorable
2016/12/09 15:10:02 removing vendor github.com/mattn/go-isatty
2016/12/09 15:10:02 removing vendor github.com/valyala/fasttemplate
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	modified:   .gitmodules
	deleted:    vendor/github.com/labstack/echo
	deleted:    vendor/github.com/labstack/gommon
	deleted:    vendor/github.com/mattn/go-colorable
	deleted:    vendor/github.com/mattn/go-isatty
	deleted:    vendor/github.com/valyala/fasttemplate
```

# まとめ

依存を取得する側は`go get`するだけなので簡単です。

デモに使った[リポジトリ](https://github.com/k2wanko/manul-demo)です。

最近まではGoでパッケージ管理する気は全然なくて自分の動かしたい環境(App Engine)で動かないアップデートされた時はPRをして対処していました。でも、どんどんバージョンアップしてAPIの互換はなくなるし機能が肥大化してApp Engineで動かないパッケージも入ってくるしで流石に対処しきれなくなってきたので、諸々時間稼ぎにベンダリングを使うようになりました。

Goのパッケージマネージャは色々ありますが僕がmanulの好きなところはメタファイルを増やさなくていいところです。
[GCPのアドベントカレンダー](http://qiita.com/koki_cheese/items/216fe73caf958db34aa2)にも書いたのですがGoを書く時、僕はだいたいJavaScriptも一緒に書いてるのでJavaScript関係のメタファイルがプロジェクトルートにわさわさあります。なので、できるだけメタファイルがないほうが嬉しいです。
もちろんわさわさある方がいいという人もいると思うので好みの問題ですが。
あと、CIにベンダリングのためのツールを追加する必要もないのもポイントが高いです。