Go modulesとは?Goの依存関係管理を解説
Go modulesはGoの組み込みの依存関係システムです。go.modはモジュールとその要件を宣言し、go.sumはそれらを固定して再現性のあるbuildを実現します。
Go modulesは古いGOPATHのワークスペースモデルを置き換え、Goにバージョン管理された再現性のある依存関係をもたらしました。modulesがあれば、go.modを含む任意のディレクトリがbuild可能なプロジェクトとなり、Goツールチェーンが必要なものすべての取得と検証を行います。
Go modulesとは
Go moduleは、ルートにgo.modファイルを持つパッケージの集合で、そのファイルはモジュールのパス、Goのバージョン、必要な依存関係を宣言します。対になるgo.sumファイルは各依存関係の暗号学的checksumを記録し、ツールチェーンがそれらが変更されていないことを検証できるようにします。
仕組み
パッケージをインポートしてbuildすると、Goは最小バージョン選択を用いて必要なバージョンを解決し、モジュールproxyを介してそれらをダウンロードし、ローカルにcacheします。go.modは要件で、go.sumはそれらのchecksumで更新されます。これによりbuildが再現可能になります。同じgo.modとgo.sumはどこでも同じ依存関係のセットを生み出します。
使用例
モジュールを初期化し、インポートしてtidyすることで依存関係を追加します。
# create a module
go mod init example.com/myapp
# add or prune dependencies to match the code
go mod tidy
# build and test
go build ./...
go test ./...CI/CDでの役割
CIでは、「go build」と「go test」がgo.modから依存関係を解決し、go.sumの検証が改ざんから守ります。「go mod verify」を実行したり、「go mod tidy」がdiffを生じないことを確認したりすると、依存関係のdriftを検出できます。Goのモジュールcacheとbuild cacheを実行間でcacheすると、再ダウンロードと再コンパイルを避けられ、すべてのjobが高速化されます。
代替ツール
modules以前、GoはGOPATHに加えてdepやglideといったサードパーティのツールを使っていましたが、modulesがそれらを時代遅れにしました。modulesの時代の中では、唯一の選択肢はどのモジュールproxyを使うかといった設定の細部です。非常に大規模なmonorepoでは、一部のチームがBazelを上に重ねますが、go.modは依然として土台であり続けます。
重要なポイント
- Go modulesはgo.mod (要件) とgo.sum (checksum) を介して依存関係を管理します。
- buildを再現可能にし、古いGOPATHモデルを置き換えました。
- CIではモジュールcacheとbuild cacheをcacheし、driftを防ぐためにgo.sumを検証します。