Go Modulesについて

先日、Go Modulesの操作ミスが重なってリポジトリを1つ失うことになりました。悲しいことが2度と起きないようにGo Modulesの勉強をしました。
この記事はThe Go Blog using go module からピックアップした内容です。

モジュールを作成する

モジュール名はgo mod initコマンドを使って付けます。このコマンドを実行するとgo.modファイルが生成されます。

$ go mod init <module name> 

githubリポジトリを持つ場合は次のような命名規則になると思います。

<module name> = github.com/<account name>/<repository name>

現在自分のモジュールが依存しているパッケージのバージョンはgo.modで確認できます。

go.modを読む

$ cat go.mod
module example.com/hello

go 1.15

require (
    golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c  // indirect
    rsc.io/quote v1.5.2
    rsc.io/sampler v1.3.0  // indirect
)

rsc.io/quote v1.5.2
これは自分のモジュールが依存しているモジュールです。
v1.5.2はモジュールのバージョンを表しています。セマンティックバージョニングのルールに基づいてバージョンをつけます。

rsc.io/sampler v1.3.0 // indirect
indirectコメントが付いている場合は、依存関係にあるモジュールから間接的に依存しているモジュールです。

golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c // indirect
v0.0.0-yyyymmddhhmmss-abcdefabcdefのようになっているのは擬似バージョンです。
コミットタグの付いていないバージョンを使う場合、このようなバージョン構文になります。

また、go.modをみなくてもgo list -mコマンドで依存関係を確認することができます。
ただし、indirectコメントは見ることができません。

$ go list -m all
example.com/hello
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
rsc.io/quote v1.5.2
rsc.io/sampler v1.3.0

依存パッケージのバージョン確認とバージョン変更

依存しているパッケージ(rsc.io/sampler)のバージョン一覧を知りたい場合は、次のコマンドで確認できます。

$ go list -m -versions rsc.io/sampler
rsc.io/sampler v1.0.0 v1.2.0 v1.2.1 v1.3.0 v1.3.1 v1.99.99

依存しているパッケージのバージョンを変えたい場合は次のコマンドで変更します。 こうすることで、go.modのバージョンを書き換えることができます。

$ go get rsc.io/sampler@v1.3.1
go: downloading rsc.io/sampler v1.3.1

$ cat go.mod
module example.com/hello

go 1.15

require (
    golang.org/x/text v0.3.4 // indirect
    rsc.io/quote v1.5.2
    rsc.io/sampler v1.3.1 // indirect
)

依存パッケージのメジャーバージョンアップ

メジャーバージョンをあげる場合はv2, v3 ... のように異なるパスを割り当てます。

rsc.io/quote/v3 v3.1.0

メジャーバージョンアップするとv0, v1とは別のモジュールとして扱われますので、依存しているパッケージをメジャーバージョンアップするには、必要なパッケージをインポートすればOKです。

package hello

import "rsc.io/quote/v3"

依存関係のクリーンナップ

go testなどのビルドコマンドは不要になったパッケージ情報をロードしないので、使用していないパッケージがgo.modに残り続けてしまいます。
クリーンナップするには明示的にgo mod tidyを実行する必要があります。

$ go mod tidy

モジュールを公開する

git tagでタグをつけます。
最初に紹介した通り、セマンティックバージョニングのルールに基づいたバージョンです。
タグをつける前にはgo mod tidyとテストの成功を確認しておくことを忘れずに。

$ go mod tidy
$ go test ./...
ok      example.com/hello       0.015s
$ git add go.mod go.sum hello.go hello_test.go
$ git commit -m "hello: changes for v0.1.0"
$ git tag v0.1.0
$ git push origin v0.1.0

モジュールをメジャーバージョンアップする

v1→v2にバージョンアップする場合、v2ディレクトリを作成して必要なファイルをv2フォルダにコピーします。 go.modも同じくコピーし、モジュールパスにサフィックスを追加します。 ※v2以降はv0, v1と別のモジュールとして扱われることに注意。

$ mkdir v2
$ cp *.go v2/
$ cp go.mod v2/go.mod
$ go mod edit -module <module name/v2> v2/go.mod