はじめに
これまでのGoプロジェクトでは、tools.go を用いて開発用ツールのバージョン管理を行うのが一般的でした。しかし、Go 1.24から公式に tools directive が導入されたので、備忘録も兼ねて今更ながら試してみます。
tools.goについて
golangci-lint や oapi-codegen などのGo製ツールをローカル環境を汚さずに管理するため、ビルドタグを用いた空importを利用しバージョン管理をgo.modで実施できるようにしていました。
tools.go
//go:build tools
package tools
import (
_ "github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen"
)
Go 1.24 からの新しい管理方法
go get に -tool フラグを渡すだけで、直接 go.mod にツールとして登録できるようになりました。
ツールの追加方法
go get -tool github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@latest
これを実行すると、go.mod に以下のように tool ディレクティブが追加されます。
ツールの実行方法
登録したツールを実行する時は、go tool コマンドを使います。ツール名はパスの最後の部分が自動で認識されます。
(※もし同名のツールが複数ある場合は、パッケージパス全体を記載する必要があります)
go tool oapi-codegen -config cfg.yaml api.yaml
go:generate での活用
実際の開発では、CLIから直接叩くよりも go:generate に組み込んで利用するケースが多いと思います。
これまで go run で長々とパッケージパスを指定していた箇所が、非常にスッキリ書けるようになります。
【修正前】(tools.go 時代)
//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen -config cfg.yaml api.yaml
【修正後】(Go 1.24 以降)
//go:generate go tool oapi-codegen -config cfg.yaml api.yaml
ただ、 go run を使った記述でもそのまま動くので、既存プロジェクトで急いで書き直す必要はなさそうです。
まとめ
今回はGo 1.24で導入された tools directive を試してみました。
長らくハック的な手法だった tools.go が公式にサポートされ、go.mod だけで完結するようになったのは非常に嬉しいアップデートです。
既存コードの go run も引き続き動くため無理に移行する必要はありませんが、新規プロジェクトやツールの追加・更新のタイミングで少しずつ新しい記法へ移行していくのが良いかなと思いました。

