はじめに
Go Modulesによるパッケージ管理についてまとめます。
本記事は公式ブログ「Using Go Modules」を参考に作成しています。
Go Modulesとは?
Go ModulesはGoが公式でサポートする依存関係管理システムです。Go Modulesによって依存関係のバージョン情報を明示的に管理できます。
Go1.11、1.12は予備サポート、1.13以降から正式サポートとなりました。Go Modulesがサポートされる以前は、$GOPATH/src
配下にプロジェクトを配置する必要があり、$GOPATH/src/プロジェクト/vendor/
配下にパッケージを置いて管理する方法や、dep
などの依存関係管理ツールを用いる方法が一般的でした。Go Modulesが登場してからは、プロジェクトは任意の場所に配置できるようになり、Go Modulesで依存関係を管理することがデファクトスタンダードとなっています。
以前の管理モードはGOPATHモード、Go Modulesを用いた管理モードはmoduleモードと呼ばれており、Go1.11以降は環境変数で切り替えることができるようになっています。go env
コマンドで設定を確認することができます。
% go env
GO111MODULE=""
Go111MODULE
という環境変数がGOPATHモードとmoduleモードを切り替える変数となっており、GO111MODULE=off
はGOPATHモード、GO111MODULE=on
はmoduleモードを示します。また、Go1.13以降デフォルトでmoduleモードを示すようになったため、GO111MODULE=auto
とするとmoduleモードになり、Go1.16ではGO111MODULE=""
でもmoduleモードを示すようになりました。
現状は基本的にはmoduleモードでGo Modulesを利用する方法さえ押さえていれば問題ないと思います。
Go Modulesの使い方
go mod init
プロジェクトのフォルダを作成し、その配下でgo mod init
コマンドを実行します。その際、引数にはプロジェクト名(モジュール名)を指定します。
% mkdir gomodules_sample
% cd gomodules_sample
% go mod init gomodules_sample
すると、以下の結果が出力され、go.modファイルが生成されます。go.modファイルには引数で指定したプロジェクト名(モジュール名)と利用しているGoのバージョンが記述されます。
% go mod init gomodules_sample
go: creating new go.mod: module gomodules_sample
go: to add module requirements and sums:
go mod tidy
% cat go.mod
module gomodules_sample
go 1.16
依存関係の追加
次に、Go Modulesによって依存関係がどのように追加されるか確認します。
以下のように”rsc.io/quote”モジュールを利用するコードを記述したとします。このコードを実行するためには、”rsc.io/quote”モジュールを追加する必要があります
package main
import (
"fmt"
"rsc.io/quote"
)
func main() {
fmt.Println(quote.Hello())
}
Go1.15以下ではgo build
やgo run
を実行すると、自動的に依存しているモジュールが追加されるようですが、Go1.16ではそれらのコマンドでは追加されません。Go1.16ではgo get
もしくはgo mod tidy
を実行することで依存関係にあるモジュールが追加されます。
% go mod tidy
go: finding module for package rsc.io/quote
go: downloading rsc.io/quote v1.5.2
go: found rsc.io/quote in rsc.io/quote v1.5.2
go: downloading rsc.io/sampler v1.3.0
go: downloading golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
上記コマンドの出力結果を見ると、rsc.io/quote
に加えてrsc.io/sampler
とgolang.org/x/text
がダウンロードされていることがわかります。これはrsc.io/quote
の中で使用しているモジュールになります。
go.modファイルには、require rsc.io/quote v1.5.2
という依存関係を示す行が追加されました。
module gomodules_sample
go 1.16
require rsc.io/quote v1.5.2
また、go.sum
ファイルも合わせて生成されます。このファイルは、依存関係にあるモジュールのチェックサムを記録したファイルになります。このチェックサムを用いてモジュールに更新があるかどうかをチェックしています。
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:qgOY6WgZOaTkIIMiVjBQcw93ERBE4m30iBm00nkL0i8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3Y=
rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0=
rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
go list -m all
コマンドを実行することで全てのモジュールを確認することができます。
% go list -m all
gomodules_sample
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
rsc.io/quote v1.5.2
rsc.io/sampler v1.3.0
ダウンロードされたモジュールは$GOPATH/pkg
の配下に格納されます。
依存関係のアップグレード – マイナーバージョン
Goのモジュールはセマンティックバージョニングが用いられています。セマンティックバージョニングはX.Y.Z
形式でバージョンを管理し、Xをメジャーバージョン、Yをマイナーバージョン、Zをパッチバージョンと呼びます。後方互換性を保たない大きなリリースを行う場合はXを増やし、後方互換性を保つ機能追加を行う場合はY、バグ修正をリリースする場合はZを増やすというルールでバージョン管理します。詳細は公式ページを参照ください。
ダウンロードされたgolang.org/x/text
のバージョンを見てみるとv0.0.0-20170915032832-14c0d48ead0c
となっており、最新バージョンではありません。そこで、2021/7現時点で最新バージョンである0.3.6バージョンにgo get
コマンドを利用することでマイナーバージョンアップグレードします。go get
コマンドで明示的にバージョンを指定する場合はgo get golang.org/x/text@0.3.6
のように、モジュールの末尾に@バージョン
を付与することでバージョン指定できます。明示的にバージョン指定しない場合はデフォルトで@latest
がダウンロードされます。
また、ダウンロードできるバージョンは以下のコマンドで確認できます。
% go list -m -versions golang.org/x/text
golang.org/x/text v0.1.0 v0.2.0 v0.3.0 v0.3.1 v0.3.2 v0.3.3 v0.3.4 v0.3.5 v0.3.6
% go get golang.org/x/text
go get: upgraded golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c => v0.3.6
バージョン指定してアップグレードしたため、go.modファイルとgo.sumファイルが更新されます。// indirect
コメントは本パッケージ(モジュール)が直接使用していないモジュールであることを表すコメントです。
module gomodules_sample
go 1.16
require (
golang.org/x/text v0.3.6 // indirect
rsc.io/quote v1.5.2
)
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:qgOY6WgZOaTkIIMiVjBQcw93ERBE4m30iBm00nkL0i8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3Y=
rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0=
rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
依存関係のアップグレード – メジャーバージョン
rsc.io/quote
にはv3のバージョンrsc.io/quote/v3
があります。そのバージョンにアップグレードしてみましょう。
% go list -m -versions rsc.io/quote/v3
rsc.io/quote/v3 v3.0.0 v3.1.0
まず、main.go
でv3を利用するようにコードを修正します。その上で、go mod tidy
コマンドを実行することで、利用しなくなったrsc.io/quote
は削除され、rsc.io/quote/v3
が新しくダウンロードされます。
package main
import (
"fmt"
"rsc.io/quote/v3"
)
func main() {
fmt.Println(quote.HelloV3())
}
% go mod tidy
go: finding module for package rsc.io/quote/v3
go: downloading rsc.io/quote/v3 v3.1.0
go: found rsc.io/quote/v3 in rsc.io/quote/v3 v3.1.0
go.modもv3に書き変わりました。
module gomodules_sample
go 1.16
require (
golang.org/x/text v0.3.6 // indirect
rsc.io/quote/v3 v3.1.0
)
まとめ
本記事では公式ブログ「Using Go Modules」を参考にGo Modulesの初期処理から依存モジュールの追加、アップグレード方法までをまとめました。Go Modulesの基本は本記事で一通り抑えられると思います。
閲覧いただきありがとうございました。
コメント