Skip to content

tools.goを利用したツールのバージョン管理をやめた

Goでは、リポジトリ内で利用するコマンドのバージョン管理をするため、tools.go にコマンドのパッケージパスを書いておいてGo Modulesによって管理させるという手法がある。

//go:build tools
import (
_ "golang.org/x/tools/cmd/stringer"
)

これを転用して、よく使うツールは自分の dotfiles リポジトリでバージョン管理をしていたが、以下の問題があった。

  • 管理するコマンドの量が増えると、アップデートを確認するだけで数分待たされる
  • 管理するコマンドの量が増えると、モジュールのバージョン差異によって壊れる
    • あるコマンドでは v0.xxx の変更を必要とするが、別のコマンドでは古いバージョンに依存している等
    • 特に競合する印象があるのは govulncheckgopls
    • v1 以降ならGo Modulesによって両方参照してくれるが v0 だとできない
  • Dependabotによって依存関係の脆弱性を警告が出たままになる
    • コマンド側が参照しているけれど影響を受けない場合に放置されることがよくある

また、近年ではGoのバイナリにモジュールのバージョンが含まれているので、アップデートを確認したいだけなら埋め込まれている runtime/debug.BuildInfo を使うほうが早いし変化にも強い。加えて、 BuildInfo はバイナリをビルドしたGoのバージョンも持っているので、こちらの方が都合よい。

将来的には go tool サブコマンドがサポートされて tools.go の習慣も消えていくと思われる。なので、上記のような理由から dotfiles でGoツールのバージョン管理をやめた。