TL;DR

Minimal version selection の略で、Go がビルドに使うモジュールのバージョンを決めるアルゴリズム。各モジュールについて、要求されている最小バージョンのうち最も高いものを選ぶ。

なぜ必要か

MVS は go.mod に書かれた最小要求だけをたどるので、依存の新しいバージョンが公開されても結果は変わらない。結果が決定的なので、ほかのパッケージ管理のようにビルドリストをロックファイルに保存する必要がない。Go のコマンドは、モジュールを扱うたびに MVS でビルドリストを計算し直す。

仕組み

MVS は、go.mod で表されたモジュールの有向グラフを対象にする。頂点はモジュールのバージョン、辺は require ディレクティブで指定された依存関係の最小バージョンである。MVS はメインモジュールからグラフをたどり、モジュールごとに要求された最も高いバージョンを記録する。たどり終えたときの各モジュールのバージョンの集まりがビルドリストで、すべての要求を満たす最小のバージョンになっている。

メインモジュールの replace と exclude は、MVS を実行する前にグラフを書き換える。exclude されたバージョンへの要求は、次に高いバージョンへの要求として扱われる。go get でアップグレードするときは、新しいバージョンへの辺を足してから MVS を実行する。ダウングレードするときは、指定より高いバージョンと、それに依存するバージョンをグラフから取り除いてから実行する。

例

メインモジュールが A 1.2 と B 1.2 を要求し、A 1.2 が C 1.3 を、B 1.2 が C 1.4 を要求し、C 1.3 と C 1.4 がどちらも D 1.2 を要求しているとする。このときのビルドリストは次のようになる。

A 1.2, B 1.2, C 1.4, D 1.2

B や D に新しいバージョンがあっても、それを要求するモジュールがないので選ばれない。

関連

出典