2️⃣

Go 1.24: tool directive由来の依存関係はパッケージ配布時に引き連れなくて済むらしい

2025/02/27に公開

はじめに

ドキュメントに以下の記載があり気になったので試してみました

when you depend on a module that itself has a tool dependency, requirements that exist just to satisfy that tool dependency do not usually become requirements of your module.

モジュールがツール依存を持っている場合、そのツール依存を満たすためだけに存在する要件は、通常、依存先のモジュールには引き継がれません。

https://tip.golang.org/doc/modules/managing-dependencies#tools

検証

検証用repoはこちら

https://github.com/miyamo2/go1-24-tool-directive

このリポジトリの構成は以下の通りです

.
├── depends-with-tool-directive # with-tool-directiveに依存
│   ├── go.mod
│   ├── go.sum
│   └── main.go
├── depends-with-tools-go # with-tools-goに依存
│   ├── go.mod
│   ├── go.sum
│   └── main.go
├── with-tool-directive # tool directive で mockgen を管理
│   ├── go.mod
│   ├── go.sum
│   ├── mock_with_tool_directive.go
│   └── with_tool_directive.go
└── with-tools-go # tools.go で mockgen を管理
    ├── go.mod
    ├── go.sum
    ├── tools
    │   └── tools.go
    └── with-tools-go.go

go.mod の比較

with-tools-go、with-tool-directive

まずは、 mockgen を利用している2つの go.mod を比較します

with-tools-go

module github.com/miyamo2/go1-24-tool-directive/withtoolsgo

go 1.24

require go.uber.org/mock v0.5.0

require (
	golang.org/x/mod v0.20.0 // indirect
	golang.org/x/sync v0.8.0 // indirect
	golang.org/x/tools v0.24.0 // indirect
)

with-tool-directive

module github.com/miyamo2/go1-24-tool-directive/withtooldirective

go 1.24

tool go.uber.org/mock/mockgen

require (
	go.uber.org/mock v0.5.0 // indirect
	golang.org/x/mod v0.20.0 // indirect
	golang.org/x/sync v0.8.0 // indirect
	golang.org/x/tools v0.24.0 // indirect
)

特に変わりなし

depends-with-tools-go、depends-with-tool-directive

次に本題、パッケージの利用者側として想定している2つの go.mod を比較していきます

depends-with-tools-go

module github.com/miyamo2/go1-24-tool-directive/depends-with-tools-go

go 1.24

replace github.com/miyamo2/go1-24-tool-directive/withtoolsgo => ../with-tools-go

require github.com/miyamo2/go1-24-tool-directive/withtoolsgo v0.0.0-00010101000000-000000000000

require (
	go.uber.org/mock v0.5.0 // indirect
	golang.org/x/mod v0.20.0 // indirect
	golang.org/x/sync v0.8.0 // indirect
	golang.org/x/tools v0.24.0 // indirect
)

それはそう

depends-with-tool-directive

module github.com/miyamo2/go1-24-tool-directive/depends-with-tool-directive

go 1.24

replace github.com/miyamo2/go1-24-tool-directive/withtooldirective => ../with-tool-directive

require github.com/miyamo2/go1-24-tool-directive/withtooldirective v0.0.0-00010101000000-000000000000

depends-with-tool-directive では mockgen やその依存関係(golang.org/x/tools など)が go.mod に含まれていません!

おわりに

ライブラリ開発時に go.mod で開発ツールを管理しつつも、
利用者のプロジェクトに不要なツールの依存関係を持ち込まずに済む というのはかなり嬉しいのではないでしょうか?

また、コントリビューターの環境構築もより簡潔になっていきそうです

参考

https://future-architect.github.io/articles/20250204a/

https://zenn.dev/uji/articles/adding-tool-dependencies-to-go-mod

GitHubで編集を提案

Discussion