Goのモジュール・依存パッケージの管理について

go get とか go mod、go.modファイルのこととか整理しました。

Go Modules

GoはGo Modulesという仕組みでモジュールを管理しています。

Go 1.11 からは $GO111MODULE という環境変数が用意され、Go Modulesを使うかどうかの切り替えができるようになりました。この環境変数は onoffauto の3つの値を選択できます。

  • on…Go Modules を使う (module-aware mode)
  • off…1.11以前にも採用されていた $GOPATH を使う (GOPATH mode)
  • auto$GOPATH/src 以外の場所にソースコードがあり、かつ go.mod が存在する場合は module-aware mode、そうでない場合は GOPATH mode

デフォルトでは auto となっています。Go1.11~1.12とGo1.13以降では auto の定義が少し異なり、Go1.11~Go1.12は $GOPATH/src 内で go.mod が存在する場合でもmodule-aware mode と認識されません。

cmd/go: default to GO111MODULE=auto (with changes) for Go 1.13 #31857

https://github.com/golang/go/issues/31857

依存パッケージの管理

go.mod ファイルで依存関係のパッケージが管理されます。モジュールはパッケージの集合体です。

A module is a collection of Go packages stored in a file tree with a go.mod file at its root.

https://blog.golang.org/using-go-modules

go.modは次のコマンドで作成します。usernameはgithubのユーザ名です。

# 対象のパッケージディレクトリ内にgo.modを作成するコマンド
go mod init github.com/username/mygoapp

go.modがあると、 go getgo testgo build など、各種goのコマンドを実行した時に、自動でgo.modに記載されている依存関係のパッケージが更新されます。

go.sumというファイルも同時に作成されるのですが、これはパッケージのバージョンをロックするためのファイルです。

依存パッケージの追加

パッケージの追加は go get

# ホットリロードを実装するモジュール「realize」の追加
go get github.com/oxequa/realize

下記のように ... とやると、全てのパッケージを丸ごと持ってくることが出来ます。

# Goの標準パッケージを全部持ってくる
go get golang.org/x/tools/cmd/...

-u オプションをつけると更新してくれます。

# 全部更新
go get -u

# パッチレベルで更新
go get -u=patch

# パッケージごとに更新
go get -u hogehoge

依存パッケージのお掃除

開発を進めていくと、不要なパッケージが出てきたりしてどんどん汚れていきます。

次のコマンドで使われていないパッケージを削除したり、足りないパッケージを追加してお掃除できます。

go mod tidy

まとめ

開発段階でパッケージをどんどんインストールするときは go get

ある程度開発が落ち着いてきたら折を見て go mod tidy でgo.modを整理。

必要なパッケージが go.mod にリストアップされていれば go build で依存パッケージが入るので、Dockerで環境を用意している場合はdockerfileに go get は不要、go.modファイルと go build コマンドがあれば良い。