Go 1.24の新機能で、Go製ツールのバージョンをGo Modulesで管理できるようになったので、その概要と便利なポイントを紹介していきます。
これまでのGo製ツールのバージョン管理について
これまで、Go製ツールのバージョンを管理する方法として標準的なものはありませんでした。
そのため、仕方なく直接 go install github.com/XXX/cmd/ツール名@バージョン をコマンドとして打たざるを得ないシーンが多々ありました。(過去の方法については今回あまり深堀りしません)
これからのGo製ツールのバージョン管理について
Go 1.24からGo組み込みの機能として提供される新しいツール管理方法は、従来のものよりずっと手軽になっています。
使い方が非常に簡単なので、ここで紹介する内容はGo以外のプロジェクトでも使えると思っています。Go Modulesを既存のプロジェクトに同居させる必要はありますが、それを特に気にしない方にはおすすめできます。
本記事では基本的な使い方についてのみ紹介します。詳しく知りたい方は以下のujiさんの記事などをご覧ください。(※ujiさんの記事執筆時点ではGo 1.24は未リリースでしたが、本記事の執筆時点ではリリース済みとなります)
使い方
Go製ツールのバージョン管理は、Go Modulesの機能の一部として提供されるため、まずはプロジェクトのルートでGo Modulesの初期化を行います。
go mod init
続いて、必要なツールを取得します。 例として、筆者の作った絵文字を検索するためのemoというツールを入れてみます。
go get -tool github.com/syumai/emo/cmd/emo
バージョンを明示したい場合は、ツール名の後ろに @バージョン を付けて実行します。
go get -tool github.com/syumai/emo/cmd/emo@v0.2.2
あとは、プロジェクト配下で以下のように呼び出すだけでインストールしたツールを使うことができます。
go tool emo
新しいツール管理機能の何がいいのか?
この機能のいいところをいくつか挙げてみます。
- 標準の機能である
- Go Modulesの機能である
- ツールを明示的にインストールしなくていい
標準の機能である
まず、この機能はGo標準の機能なので、サードパーティのツールを導入する必要がありません。必要なのはGoだけです。Goさえインストールされていれば動きます。
Go Modulesの機能である
この機能はGo Modulesの提供する機能の一部でしかないので、既存の仕組みを流用できます。たとえば、DependabotやRenovateによってツールの更新を自動で行えます。
また、あるGoのモジュールを、ライブラリとして使い、コマンドとしても使うようなケースで、必ずこれら2つのバージョンが揃うようにできます。ライブラリ側とコマンド側のバージョンが合わなくて面倒になるケースがたまにあるので、地味に助かります。
ツールを明示的にインストールしなくていい
Go Modulesで管理されているツールを go tool ツール名 で実行する際に、明示的なインストール操作は不要で、自動的にインストールが走ります。これがかなり便利です。誰かが事前に go get -tool でツールをGo Modules管理下に追加する必要はありますが、既存のチームメンバーのツール導入コストや、新メンバー加入時のオンボーディングコストを減らしてくれると思います。
また、Go Modulesで管理されているツールのバージョンが更新されていたら、手元のツールを明示的にインストールし直さなくても更新されます。例えば、もともと手元で使っていた emo@v0.2.0 をDependabotが emo@v0.2.1 に更新していたとしたら、手元の emo はインストールし直さなくても勝手に v0.2.1 になります。
不便な点
個人的には非常に満足していますが、go tool のPrefixが実行に必要となるのでたまに取り回しに困ります。
例えば、protocのプラグインは、特定の名前のパターンのコマンドを期待していて、Goのコードを生成する用のプラグインはprotoc-gen-goとなっています。
protoc-gen-goはGo製のツールなので、Go Modulesで管理したくなりますが、実行に go tool のPrefixが必要になるとうまく組み合わせて使えません。
protocのケースに関してだけ言うと、Twitterで紹介されていた、Bufを使う手法で回避できました。
Messing around with protocol buffers and the new tools directive in Go 1.24. It works pretty nicely with @bufbuild pic.twitter.com/GVnX9iEYfJ
— David Bond (@dsb_dev) 2025年2月13日
しかしながら、絶妙にユースケースを満たさないような場合もあるかもしれません(あまり想像はついていないですが)
最後に
非常に便利なので、個人的には積極的に使っていきたいと思っています。
Go製のツール以外のバージョンの管理も合わせて行いたいような場合はaquaなどを使った方がいいケースもあると思います。当然ですが、必ずGo Modulesを使った方がいいとまでは思っていません。
これくらい手軽に使える方法であれば、Go製ツールのバージョン管理のためだけに、Go以外のプロジェクトでも使ってみていいのではないでしょうか?賛否が分かれるかもしれませんが、例えば、npm scriptsに go tool ツール名 を直接書いてもいいと思っています。よかったら、Twitterなどで感想をお待ちしています。