Go Modules リファレンス

はじめに

モジュールは、Goが依存関係を管理する方法です。

このドキュメントは、Goのモジュールシステムに関する詳細なリファレンスマニュアルです。Goプロジェクトの作成に関する入門については、Goコードの書き方を参照してください。モジュールの使用方法、プロジェクトのモジュールへの移行、その他のトピックに関する情報については、Go Modulesの使用方法から始まるブログシリーズを参照してください。

モジュール、パッケージ、バージョン

モジュールは、一緒にリリース、バージョン管理、配布されるパッケージのコレクションです。モジュールは、バージョン管理リポジトリから直接、またはモジュールプロキシサーバーからダウンロードできます。

モジュールは、モジュールパスによって識別され、これはgo.modファイルで宣言され、モジュールの依存関係に関する情報とともに提供されます。モジュールルートディレクトリは、go.modファイルを含むディレクトリです。メインモジュールは、goコマンドが呼び出されるディレクトリを含むモジュールです。

モジュール内の各パッケージは、同じディレクトリにあるソースファイルのコレクションであり、まとめてコンパイルされます。パッケージパスは、モジュールパスと、パッケージを含むサブディレクトリ(モジュールルートからの相対パス)を結合したものです。たとえば、モジュール"golang.org/x/net"には、"html"ディレクトリにパッケージが含まれています。そのパッケージのパスは"golang.org/x/net/html"です。

モジュールパス

モジュールパスは、モジュールの標準名であり、モジュールのgo.modファイルmoduleディレクティブで宣言されます。モジュールのパスは、モジュール内のパッケージパスのプレフィックスです。

モジュールパスは、モジュールの機能と場所の両方を記述する必要があります。通常、モジュールパスは、リポジトリのルートパス、リポジトリ内のディレクトリ(通常は空)、およびメジャーバージョンサフィックス(メジャーバージョン2以上の場合のみ)で構成されます。

他のモジュールによって依存される可能性のあるモジュールの場合、これらの規則に従う必要があります。これにより、goコマンドはモジュールを見つけ、ダウンロードできます。また、モジュールパスで使用できる文字に関するいくつかの字句上の制限もあります。

他のモジュールの依存関係として取得されることがないモジュールは、有効なパッケージパスをモジュールパスとして使用できますが、モジュールの依存関係またはGo標準ライブラリで使用される可能性のあるパスと競合しないように注意する必要があります。Go標準ライブラリは、最初のパス要素にドットを含まないパッケージパスを使用し、goコマンドはネットワークサーバーからそのようなパスを解決しようとしません。パスexampletestはユーザー用に予約されています。これらは標準ライブラリでは使用されず、チュートリアルやサンプルコードで定義されているモジュール、またはテストの一部として作成および操作されるモジュールなど、自己完結型のモジュールで使用できます。

バージョン

バージョンは、モジュールの不変のスナップショットを識別し、リリースまたはプレリリースのいずれかになります。各バージョンは文字vで始まり、その後にセマンティックバージョンが続きます。バージョンがどのようにフォーマットされ、解釈され、比較されるかについての詳細は、Semantic Versioning 2.0.0を参照してください。

要約すると、セマンティックバージョンは、3つの非負の整数(メジャーバージョン、マイナーバージョン、パッチバージョン、左から右)で構成され、ドットで区切られています。パッチバージョンには、ハイフンで始まるオプションのプレリリース文字列が続く場合があります。プレリリース文字列またはパッチバージョンには、プラスで始まるビルドメタデータ文字列が続く場合があります。たとえば、v0.0.0v1.12.134v8.0.5-prev2.0.9+metaは有効なバージョンです。

バージョンの各部分は、バージョンが安定しているかどうか、以前のバージョンと互換性があるかどうかを示します。

メジャーバージョンが0であるか、プレリリースサフィックスがある場合、バージョンは不安定と見なされます。不安定なバージョンは、互換性要件の対象ではありません。たとえば、v0.2.0v0.1.0と互換性がない可能性があり、v1.5.0-betav1.5.0と互換性がない可能性があります。

Goは、これらの規則に従わないタグ、ブランチ、またはリビジョンを使用して、バージョン管理システム内のモジュールにアクセスできます。ただし、メインモジュール内では、goコマンドは、この標準に従わないリビジョン名を自動的に標準的なバージョンに変換します。goコマンドは、このプロセスの一部としてビルドメタデータサフィックス(+incompatibleを除く)も削除します。これにより、擬似バージョン、つまりリビジョン識別子(Gitコミットハッシュなど)とバージョン管理システムからのタイムスタンプをエンコードしたプレリリースバージョンが生成される可能性があります。たとえば、コマンドgo get golang.org/x/net@daa7c041は、コミットハッシュdaa7c041を擬似バージョンv0.0.0-20191109021931-daa7c04131f5に変換します。標準バージョンの使用はメインモジュール以外でも必要であり、goコマンドは、masterのような標準ではないバージョンがgo.modファイルに存在する場合、エラーを報告します。

擬似バージョン

擬似バージョンは、バージョン管理リポジトリの特定のリビジョンに関する情報をエンコードした、特別にフォーマットされたプレリリースバージョンです。たとえば、v0.0.0-20191109021931-daa7c04131f5は擬似バージョンです。

擬似バージョンは、セマンティックバージョンのタグが利用できないリビジョンを参照する場合があります。たとえば、開発ブランチでバージョンタグを作成する前に、コミットをテストするために使用できます。

各擬似バージョンには3つの部分があります。

各擬似バージョンは、ベースバージョンに応じて3つの形式のいずれかになります。これらの形式により、擬似バージョンはベースバージョンよりも高く、次のタグ付きバージョンよりも低く比較されます。

複数の擬似バージョンが、異なるベースバージョンを使用して同じコミットを参照する場合があります。これは、下位のバージョンが擬似バージョンが記述された後にタグ付けされるときに自然に発生します。

これらの形式により、擬似バージョンには2つの便利な特性が与えられます。

goコマンドは、モジュール作成者が擬似バージョンを他のバージョンとどのように比較するかを制御し、擬似バージョンが実際にモジュールのコミット履歴の一部であるリビジョンを参照するようにするためのいくつかのチェックを実行します。

擬似バージョンを手動で入力する必要はありません。多くのコマンドはコミットハッシュまたはブランチ名を受け入れ、それを擬似バージョン(または利用可能な場合はタグ付きバージョン)に自動的に変換します。例えば

go get example.com/mod@master
go list -m -json example.com/mod@abcd1234

メジャーバージョン接尾辞

メジャーバージョン2以降、モジュールパスには、メジャーバージョンと一致する/v2のようなメジャーバージョン接尾辞が必要です。例えば、モジュールがバージョンv1.0.0でパスexample.com/modを持つ場合、バージョンv2.0.0ではパスexample.com/mod/v2を持つ必要があります。

メジャーバージョン接尾辞は、インポート互換性ルールを実装します。

古いパッケージと新しいパッケージが同じインポートパスを持つ場合、新しいパッケージは古いパッケージと後方互換性がある必要があります。

定義上、モジュールの新しいメジャーバージョンにあるパッケージは、前のメジャーバージョンにある対応するパッケージと後方互換性はありません。その結果、v2以降のパッケージには新しいインポートパスが必要です。これは、モジュールパスにメジャーバージョン接尾辞を追加することで実現されます。モジュールパスはモジュール内の各パッケージのインポートパスのプレフィックスであるため、モジュールパスにメジャーバージョン接尾辞を追加することで、各非互換バージョンに対して個別のインポートパスが提供されます。

メジャーバージョン接尾辞は、メジャーバージョンv0またはv1では許可されません。v0バージョンは不安定であり、互換性の保証がないため、v0v1の間でモジュールパスを変更する必要はありません。さらに、ほとんどのモジュールでは、v1は最後のv0バージョンと後方互換性があります。v1バージョンは、v0と比較した非互換な変更を示すのではなく、互換性へのコミットメントとして機能します。

特別なケースとして、gopkg.in/で始まるモジュールパスは、v0およびv1でも常にメジャーバージョン接尾辞が必要です。接尾辞はスラッシュではなくドットで始める必要があります(例:gopkg.in/yaml.v2)。

メジャーバージョン接尾辞により、同じビルドでモジュールの複数のメジャーバージョンを共存させることができます。これは、ダイヤモンド依存関係の問題のために必要になる場合があります。通常、モジュールが推移的依存関係によって2つの異なるバージョンで必要とされる場合、より高いバージョンが使用されます。しかし、2つのバージョンが非互換である場合、どちらのバージョンもすべてのクライアントを満たすことはできません。非互換バージョンは異なるメジャーバージョン番号を持つ必要があるため、メジャーバージョン接尾辞のために異なるモジュールパスも持つ必要があります。これにより、競合が解決されます。異なる接尾辞を持つモジュールは個別のモジュールとして扱われ、それらのパッケージ(モジュールルートに対する同じサブディレクトリにあるパッケージも含む)は個別のものになります。

多くのGoプロジェクトは、モジュールに移行する前(モジュールが導入される前かもしれません)に、メジャーバージョン接尾辞を使用せずにv2以降でバージョンをリリースしていました。これらのバージョンには、+incompatibleビルドタグ(例:v2.0.0+incompatible)が付加されています。詳細については、非モジュールリポジトリとの互換性を参照してください。

パッケージをモジュールに解決する

goコマンドがパッケージパスを使用してパッケージをロードする場合、パッケージを提供するモジュールを決定する必要があります。

goコマンドは、パッケージパスのプレフィックスであるパスを持つモジュールについて、ビルドリストを最初に検索します。例えば、パッケージexample.com/a/bがインポートされ、モジュールexample.com/aがビルドリストにある場合、goコマンドは、example.com/aがディレクトリbにパッケージを含んでいるかどうかをチェックします。ディレクトリには、少なくとも.go拡張子のファイルが1つ存在する必要があります。この目的では、ビルド制約は適用されません。ビルドリスト内のモジュールがパッケージを正確に1つ提供する場合、そのモジュールが使用されます。パッケージを提供するモジュールがない場合、または2つ以上のモジュールがパッケージを提供する場合、goコマンドはエラーを報告します。-mod=modフラグは、goコマンドに、不足しているパッケージを提供する新しいモジュールを見つけること、およびgo.modgo.sumを更新することを指示します。go getコマンドとgo mod tidyコマンドはこれを自動的に実行します。

goコマンドがパッケージパスに対して新しいモジュールを検索する場合、プロキシURLのコンマ区切りリスト、またはキーワードdirectまたはoffであるGOPROXY環境変数をチェックします。プロキシURLは、goコマンドがGOPROXYプロトコルを使用してモジュールプロキシに連絡する必要があることを示します。directは、goコマンドがバージョン管理システムと通信する必要があることを示します。offは、通信を試行しないことを示します。GOPRIVATEおよびGONOPROXY環境変数を使用して、この動作を制御することもできます。

GOPROXYリストの各エントリについて、goコマンドは、パッケージを提供する可能性のある各モジュールパスの最新バージョン(つまり、パッケージパスの各プレフィックス)を要求します。正常に要求されたモジュールパスごとに、goコマンドは最新バージョンのモジュールをダウンロードし、モジュールが要求されたパッケージを含んでいるかどうかをチェックします。1つ以上のモジュールが要求されたパッケージを含む場合、パスが最も長いモジュールが使用されます。1つ以上のモジュールが見つかったが、要求されたパッケージを含んでいないモジュールがない場合、エラーが報告されます。モジュールが見つからない場合、goコマンドはGOPROXYリストの次のエントリを試行します。エントリが残っていない場合、エラーが報告されます。

例えば、goコマンドがパッケージgolang.org/x/net/htmlを提供するモジュールを探しており、GOPROXYhttps://corp.example.com,https://proxy.golang.orgに設定されているとします。goコマンドは以下のリクエストを行う可能性があります。

適切なモジュールが見つかった後、goコマンドは、新しいモジュールのパスとバージョンを含む新しい要件をメインモジュールのgo.modファイルに追加します。これにより、将来同じパッケージがロードされた場合、同じモジュールが同じバージョンで使用されるようになります。解決されたパッケージがメインモジュールのいかなるパッケージによってもインポートされていない場合、新しい要件には// indirectコメントが付きます。

go.modファイル

モジュールは、ルートディレクトリにあるgo.modという名前のUTF-8エンコードテキストファイルによって定義されます。go.modファイルは、行指向です。各行は、キーワードとそれに続く引数で構成される単一のディレクティブを保持します。例えば

module example.com/my/thing

go 1.12

require example.com/other/thing v1.0.2
require example.com/new/thing/v2 v2.3.4
exclude example.com/old/thing v1.2.3
replace example.com/bad/thing v1.4.5 => example.com/good/thing v1.4.5
retract [v1.9.0, v1.9.5]

先頭のキーワードは、隣接する行から要因化して、Goのインポートのようにブロックを作成できます。

require (
    example.com/new/thing/v2 v2.3.4
    example.com/old/thing v1.2.3
)

go.modファイルは、人間が読みやすく、機械が書き込み可能になるように設計されています。goコマンドは、go.modファイルを変更するいくつかのサブコマンドを提供します。例えば、go getは、特定の依存関係をアップグレードまたはダウングレードできます。モジュールグラフをロードするコマンドは、必要に応じて自動的にgo.modを更新しますgo mod editは、低レベルの編集を実行できます。golang.org/x/mod/modfileパッケージは、Goプログラムがプログラムで同じ変更を行うために使用できます。

メインモジュールと、ローカルファイルパスで指定された置換モジュールには、go.modファイルが必要です。しかし、明示的なgo.modファイルがないモジュールでも、依存関係として必要とされる可能性があり、モジュールパスとバージョンで指定された置換として使用される可能性があります。非モジュールリポジトリとの互換性を参照してください。

字句要素

go.modファイルが解析されると、その内容はトークンのシーケンスに分割されます。いくつかの種類のトークンがあります。空白、コメント、句読点、キーワード、識別子、文字列です。

空白は、スペース(U+0020)、タブ(U+0009)、キャリッジリターン(U+000D)、改行(U+000A)で構成されます。改行以外の空白文字は、それ以外の場合に結合されるトークンを分離すること以外には効果がありません。改行は重要なトークンです。

コメント//で始まり、行末まで続きます。/* */コメントは許可されていません。

句読点トークンには、()=>が含まれます。

キーワードは、go.modファイル内のさまざまな種類のディレクティブを区別します。許可されるキーワードは、modulegorequirereplaceexcluderetractです。

識別子は、モジュールパスやセマンティックバージョンなどの空白以外の文字のシーケンスです。

文字列は、引用符で囲まれた文字のシーケンスです。2種類の文字列があります。引用符("、U+0022)で始まり、引用符で終わる解釈された文字列と、アクセント記号(`、U+0060)で始まり、アクセント記号で終わる生の文字列です。解釈された文字列には、バックスラッシュ(\、U+005C)の後に別の文字が続くエスケープシーケンスを含めることができます。エスケープされた引用符(\")は、解釈された文字列を終了しません。解釈された文字列の引用符なしの値は、引用符の間の文字のシーケンスであり、各エスケープシーケンスはバックスラッシュの後の文字に置き換えられます(例:\""に置き換えられ、\nnに置き換えられます)。これとは対照的に、生の文字列の引用符なしの値は、単にアクセント記号の間の文字のシーケンスです。バックスラッシュは生の文字列内では特別な意味を持ちません。

識別子と文字列は、go.mod文法では互換性があります。

モジュールパスとバージョン

go.modファイルのほとんどの識別子と文字列は、モジュールパスまたはバージョンです。

モジュールパスは、次の要件を満たす必要があります。

モジュールパスがrequireディレクティブに表示され、置換されていない場合、またはモジュールパスがreplaceディレクティブの右側にある場合、goコマンドは、そのパスを持つモジュールをダウンロードする必要がある可能性があり、さらにいくつかの要件を満たす必要があります。

go.modファイルのバージョンは、正規のバージョンまたは正規でないバージョンです。

標準バージョンは、vという文字で始まり、Semantic Versioning 2.0.0仕様に従ったセマンティックバージョンが続きます。バージョンに関する詳細については、そちらを参照してください。

ファイルシステム、リポジトリ、モジュールプロキシの問題を避けるためのいくつかの制限はありますが、ほとんどの他の識別子と文字列は標準以外のバージョンとして使用できます。標準以外のバージョンは、メインモジュールのgo.modファイルでのみ許可されます。goコマンドは、go.modファイルを自動的に更新する際に、標準以外のバージョンを同等の標準バージョンに置き換えることを試みます。

モジュールパスがバージョンに関連付けられている場所(requirereplaceexcludeディレクティブなど)、最終パス要素はバージョンと一致する必要があります。メジャーバージョンサフィックスを参照してください。

文法

go.mod構文は、拡張バッカス・ナウア記法(EBNF)を使用して以下に指定されています。EBNF構文の詳細については、Go言語仕様の表記セクションを参照してください。

GoMod = { Directive } .
Directive = ModuleDirective |
            GoDirective |
            RequireDirective |
            ExcludeDirective |
            ReplaceDirective |
            RetractDirective .

改行、識別子、文字列は、それぞれnewlineidentstringで示されます。

モジュールパスとバージョンは、ModulePathVersionで示されます。

ModulePath = ident | string . /* see restrictions above */
Version = ident | string .    /* see restrictions above */

moduleディレクティブ

moduleディレクティブは、メインモジュールのパスを定義します。go.modファイルには、正確に1つのmoduleディレクティブが含まれている必要があります。

ModuleDirective = "module" ( ModulePath | "(" newline ModulePath newline ")" ) newline .

module golang.org/x/net

非推奨化

モジュールは、段落の先頭に文字列Deprecated:(大文字と小文字が区別される)を含むコメントブロックで非推奨としてマークできます。非推奨メッセージは大文字と小文字を区別してコロンの後に始まり、段落の最後まで続きます。コメントは、moduleディレクティブの直前に、または同じ行の後に出現する可能性があります。

// Deprecated: use example.com/mod/v2 instead.
module example.com/mod

Go 1.17以降、go list -m -uビルドリスト内のすべての非推奨モジュールに関する情報をチェックします。go getは、コマンドラインで指定されたパッケージをビルドするために必要な非推奨モジュールをチェックします。

goコマンドがモジュールの非推奨情報を取得すると、バージョン照会@latestに一致するバージョンからgo.modファイルを読み込みます。リトラクト除外は考慮されません。goコマンドは、同じgo.modファイルからリトラクトされたバージョンのリストを読み込みます。

モジュールを非推奨にするには、作成者は// Deprecated:コメントを追加し、新しいリリースにタグを付けます。作成者は、上位のリリースで非推奨メッセージを変更または削除できます。

非推奨化は、モジュールのすべてのマイナーバージョンに適用されます。v2より大きいメジャーバージョンは、メジャーバージョンサフィックスによって異なるモジュールパスが与えられるため、この目的では個別のモジュールと見なされます。

非推奨メッセージは、モジュールがもうサポートされていないことをユーザーに知らせ、最新のメジャーバージョンなどへの移行手順を提供することを目的としています。個々のマイナーバージョンとパッチバージョンは非推奨にすることはできません。retractの方が適切な場合があります。

goディレクティブ

goディレクティブは、特定のバージョンのGoのセマンティクスを想定してモジュールが記述されたことを示します。バージョンは、1.91.141.21rc1など、有効なGoバージョンである必要があります。

goディレクティブは、このモジュールを使用するために必要なGoの最小バージョンを設定します。Go 1.21より前は、ディレクティブは助言のみでしたが、現在は必須要件です。Goツールチェーンは、新しいGoバージョンを宣言するモジュールを使用することを拒否します。

goディレクティブは、実行するGoツールチェーンの選択への入力となります。詳細は「Goツールチェーン」を参照してください。

goディレクティブは、新しい言語機能の使用に影響します

goディレクティブは、goコマンドの動作にも影響します

go.modファイルには、最大で1つのgoディレクティブを含めることができます。ほとんどのコマンドは、存在しない場合は現在のGoバージョンでgoディレクティブを追加します。

goディレクティブが存在しない場合、go 1.16が想定されます。

GoDirective = "go" GoVersion newline .
GoVersion = string | ident .  /* valid release version; see above */

go 1.14

toolchainディレクティブ

toolchainディレクティブは、モジュールで使用することを推奨するGoツールチェーンを宣言します。推奨されるGoツールチェーンのバージョンは、goディレクティブで宣言された必須Goバージョンより小さいことはできません。toolchainディレクティブは、モジュールがメインモジュールであり、デフォルトのツールチェーンのバージョンが推奨されるツールチェーンのバージョンより小さい場合にのみ効果があります。

再現性を確保するために、goコマンドは、go.modファイルのgoバージョンを更新するたびに(通常はgo get中に)、独自のツールチェーン名をtoolchain行に書き込みます。

詳細については、「Goツールチェーン」を参照してください。

ToolchainDirective = "toolchain" ToolchainName newline .
ToolchainName = string | ident .  /* valid toolchain name; see “Go toolchains” */

toolchain go1.21.0

godebugディレクティブ

godebugディレクティブは、このモジュールがメインモジュールである場合に適用する単一のGODEBUG設定を宣言します。このような行は複数存在でき、それらはファクタリングできます。メインモジュールが存在しないGODEBUGキーを指定することはエラーです。godebug key=valueの効果は、コンパイルされているすべてのメインパッケージに、//go:debug key=valueをリストしたソースファイルが含まれている場合と同じです。

GodebugDirective = "godebug" ( GodebugSpec | "(" newline { GodebugSpec } ")" newline ) .
GodebugSpec = GodebugKey "=" GodebugValue newline.
GodebugKey = GodebugChar { GodebugChar }.
GodebugValue = GodebugChar { GodebugChar }.
GodebugChar = any non-space character except , " ` ' (comma and quotes).

godebug default=go1.21
godebug (
    panicnil=1
    asynctimerchan=0
)

requireディレクティブ

requireディレクティブは、指定されたモジュール依存関係の最小必要なバージョンを宣言します。必要なモジュールバージョンごとに、goコマンドはそのバージョンのgo.modファイルを読み込み、そのファイルからの要件を組み込みます。すべての要件が読み込まれると、goコマンドは最小バージョン選択(MVS)を使用してそれらを解決し、ビルドリストを生成します。

goコマンドは、一部の要件に対して// indirectコメントを自動的に追加します。// indirectコメントは、必要なモジュールのパッケージがメインモジュールのどのパッケージによっても直接インポートされていないことを示します。

goディレクティブgo 1.16以下を指定している場合、goコマンドは、モジュールの選択されたバージョンがメインモジュールの他の依存関係によって既に暗示されているもの(推移的に)よりも高い場合に、間接的な要件を追加します。これは、明示的なアップグレード(go get -u ./...)、以前は要件を課していた他の依存関係の削除(go mod tidy)、または対応する要件が独自のgo.modファイルにないパッケージをインポートする依存関係(go.modファイルがまったくない依存関係など)のために発生する可能性があります。

go 1.17以降では、goコマンドは、メインモジュールのパッケージまたはテストによって(間接的にでも)インポートされたパッケージ、またはgo getに渡された引数によってインポートされたパッケージを提供する各モジュールに対して、間接的な要件を追加します。これらのより包括的な要件により、モジュールグラフの削減遅延モジュール読み込みが可能になります。

RequireDirective = "require" ( RequireSpec | "(" newline { RequireSpec } ")" newline ) .
RequireSpec = ModulePath Version newline .

require golang.org/x/net v1.2.3

require (
    golang.org/x/crypto v1.4.5 // indirect
    golang.org/x/text v1.6.7
)

excludeディレクティブ

excludeディレクティブは、goコマンドによってモジュールバージョンが読み込まれるのを防ぎます。

Go 1.16以降、任意のgo.modファイルのrequireディレクティブによって参照されるバージョンが、メインモジュールのgo.modファイルのexcludeディレクティブによって除外されている場合、その要件は無視されます。これにより、go getgo mod tidyなどのコマンドが、必要に応じて// indirectコメント付きで、より高いバージョンの新しい要件をgo.modに追加する可能性があります。

Go 1.16以前は、除外されたバージョンがrequireディレクティブによって参照されている場合、goコマンドはモジュールの使用可能なバージョンをリストし(go list -m -versionsで表示されるように)、代わりに次の高い除外されていないバージョンを読み込みました。次の高いバージョンは時間の経過とともに変化する可能性があるため、これは非決定的なバージョン選択につながる可能性があります。この目的では、リリースバージョンとプレリリースバージョンの両方が考慮されましたが、擬似バージョンは考慮されませんでした。上位バージョンがない場合、goコマンドはエラーを報告しました。

excludeディレクティブは、メインモジュールのgo.modファイルでのみ適用され、他のモジュールでは無視されます。詳細については、最小バージョン選択を参照してください。

ExcludeDirective = "exclude" ( ExcludeSpec | "(" newline { ExcludeSpec } ")" newline ) .
ExcludeSpec = ModulePath Version newline .

exclude golang.org/x/net v1.2.3

exclude (
    golang.org/x/crypto v1.4.5
    golang.org/x/text v1.6.7
)

replaceディレクティブ

replace ディレクティブは、モジュールの特定のバージョン、またはモジュールのすべてのバージョンの内容を、他の場所にある内容で置き換えます。置換先は、別のモジュールパスとバージョン、またはプラットフォーム固有のファイルパスで指定できます。

矢印 (=>) の左側バージョンが指定されている場合、モジュールのその特定のバージョンのみが置き換えられ、他のバージョンは通常どおりアクセスされます。左側のバージョンが省略されている場合、モジュールのすべてのバージョンが置き換えられます。

矢印の右側のパスが絶対パスまたは相対パス (./ または ../ で始まる) の場合、置換モジュールのルートディレクトリへのローカルファイルパスとして解釈されます。このディレクトリには、go.mod ファイルが含まれている必要があります。この場合、置換バージョンは省略する必要があります。

矢印の右側のパスがローカルパスでない場合、有効なモジュールパスである必要があります。この場合、バージョンが必要です。同じモジュールバージョンがビルドリストにも含まれていてはいけません。

ローカルパスまたはモジュールパスで置換が指定されているかに関わらず、置換モジュールにgo.modファイルがある場合、そのmoduleディレクティブは、置き換えられるモジュールパスと一致する必要があります。

replace ディレクティブは、メインモジュールの go.mod ファイルでのみ適用され、他のモジュールでは無視されます。詳細は最小バージョン選択を参照してください。

複数のメインモジュールがある場合、すべてのメインモジュールの go.mod ファイルが適用されます。メインモジュール間での replace ディレクティブの競合は許可されず、削除するか、go.work ファイルの replace で上書きする必要があります。

replace ディレクティブだけでは、モジュールグラフにモジュールが追加されるわけではないことに注意してください。置換されたモジュールバージョンを参照するrequire ディレクティブも必要です。これは、メインモジュールの go.mod ファイルまたは依存関係の go.mod ファイルのいずれかに存在する必要があります。左側のモジュールバージョンが要求されていない場合、replace ディレクティブは効果がありません。

ReplaceDirective = "replace" ( ReplaceSpec | "(" newline { ReplaceSpec } ")" newline ) .
ReplaceSpec = ModulePath [ Version ] "=>" FilePath newline
            | ModulePath [ Version ] "=>" ModulePath Version newline .
FilePath = /* platform-specific relative or absolute file path */

replace golang.org/x/net v1.2.3 => example.com/fork/net v1.4.5

replace (
    golang.org/x/net v1.2.3 => example.com/fork/net v1.4.5
    golang.org/x/net => example.com/fork/net v1.4.5
    golang.org/x/net v1.2.3 => ./fork/net
    golang.org/x/net => ./fork/net
)

retract ディレクティブ

retract ディレクティブは、go.mod で定義されたモジュールのバージョンまたはバージョンの範囲が依存すべきではないことを示します。retract ディレクティブは、バージョンが時期尚早に公開された場合、またはバージョンが公開された後に重大な問題が発見された場合に役立ちます。取り消されたバージョンは、バージョン管理リポジトリおよびモジュールプロキシで引き続き利用可能にする必要があります。これにより、それらに依存するビルドが中断されないようにします。「retract」という単語は、学術文献から借用したものです。取り消された研究論文は依然として入手可能ですが、問題があり、今後の作業の基礎としては使用すべきではありません。

モジュールバージョンが取り消された場合、ユーザーはgo getgo mod tidy、またはその他のコマンドを使用して自動的にアップグレードされません。取り消されたバージョンに依存するビルドは引き続き機能しますが、ユーザーはgo list -m -uで更新を確認するか、go getで関連モジュールを更新すると、取り消しについて通知されます。

バージョンを取り消すには、モジュール作成者は go.modretract ディレクティブを追加してから、そのディレクティブを含む新しいバージョンを公開する必要があります。新しいバージョンは、他のリリースバージョンまたはプレリリースバージョンよりも高いバージョンである必要があります。つまり、@latest バージョン照会 は、取り消しが考慮される前に新しいバージョンを解決する必要があります。go コマンドは、go list -m -retracted $modpath@latest (ここで $modpath はモジュールパス) で表示されるバージョンから取り消しを読み込んで適用します。

取り消されたバージョンは、-retracted フラグを使用しない限り、go list -m -versions で出力されるバージョンリストには表示されません。取り消されたバージョンは、@>=v1.2.3@latest のようなバージョン照会を解決する際には除外されます。

取り消しを含むバージョンは、それ自体を取り消すことができます。モジュールの最新のリリースバージョンまたはプレリリースバージョンがそれ自体を取り消す場合、取り消されたバージョンを除外した後、@latest クエリはより低いバージョンを解決します。

例として、モジュール example.com/m の作成者が誤ってバージョン v1.0.0 を公開した場合を考えます。ユーザーが v1.0.0 にアップグレードするのを防ぐために、作成者は go.mod に 2 つの retract ディレクティブを追加してから、取り消しを含む v1.0.1 をタグ付けできます。

retract (
    v1.0.0 // Published accidentally.
    v1.0.1 // Contains retractions only.
)

ユーザーが go get example.com/m@latest を実行すると、go コマンドは v1.0.1 から取り消しを読み取ります。これは現在最高のバージョンです。v1.0.0v1.0.1 の両方が取り消されているため、go コマンドは次の最高のバージョン(おそらく v0.9.5)にアップグレード(またはダウングレード)します。

retract ディレクティブは、単一のバージョン (v1.0.0 など) または、[] で区切られた上限と下限を持つバージョンの閉区間 ([v1.1.0, v1.2.0] など) で記述できます。単一のバージョンは、上限と下限が同じである区間と同等です。他のディレクティブと同様に、複数の retract ディレクティブを、行末の ( とその行だけの ) で区切られたブロックにグループ化できます。

retract ディレクティブには、取り消しの理由を説明するコメントを含める必要がありますが、これは必須ではありません。go コマンドは、取り消されたバージョンに関する警告や go list の出力で、理由のコメントを表示する場合があります。理由のコメントは、retract ディレクティブの直上に(空白行を挟まずに)記述するか、同じ行の後に記述できます。コメントがブロックの上部に表示される場合、そのコメントはそのブロック内の独自のコメントを持たないすべての retract ディレクティブに適用されます。理由のコメントは複数行にわたる場合があります。

RetractDirective = "retract" ( RetractSpec | "(" newline { RetractSpec } ")" newline ) .
RetractSpec = ( Version | "[" Version "," Version "]" ) newline .

retract v1.0.0
retract [v1.0.0, v1.9.9]
retract (
    v1.0.0
    [v1.0.0, v1.9.9]
)
retract [v0.0.0, v1.0.1] // assuming v1.0.1 contains this retraction.
retract [v0.0.0-0, v0.15.2]  // assuming v0.15.2 contains this retraction.

retract ディレクティブは Go 1.16 で追加されました。Go 1.15 以前では、メインモジュールの go.mod ファイルに retract ディレクティブが記述されている場合、エラーが報告され、依存関係の go.mod ファイル内の retract ディレクティブは無視されます。

自動更新

ほとんどのコマンドは、go.mod に情報が不足している場合、または現実を正確に反映していない場合にエラーを報告します。これらの問題のほとんどは、go getgo mod tidy コマンドを使用して修正できます。さらに、ほとんどのモジュール認識コマンド (go buildgo test など) では、-mod=mod フラグを使用して、go コマンドに go.modgo.sum の問題を自動的に修正するように指示できます。

例として、次の go.mod ファイルを考えてみます。

module example.com/M

go 1.16

require (
    example.com/A v1
    example.com/B v1.0.0
    example.com/C v1.0.0
    example.com/D v1.2.3
    example.com/E dev
)

exclude example.com/D v1.2.3

-mod=mod でトリガーされた更新では、非標準のバージョン識別子が標準の semver 形式に書き換えられるため、example.com/Av1v1.0.0 になり、example.com/Edev は、dev ブランチの最新のコミットの疑似バージョン(おそらく v0.0.0-20180523231146-b3f5c0f6e5f1)になります。

更新により、要件が除外を尊重するように変更されるため、除外された example.com/D v1.2.3 の要件は、使用可能な次の example.com/D のバージョン(おそらく v1.2.4 または v1.3.0)を使用するように更新されます。

更新により、冗長な要件または誤解を招く要件が削除されます。たとえば、example.com/A v1.0.0 自体が example.com/B v1.2.0example.com/C v1.0.0 を必要とする場合、go.modexample.com/B v1.0.0 の要件は誤解を招きます (example.com/Av1.2.0 を必要とすることで上書きされるため)、example.com/C v1.0.0 の要件は冗長です (example.com/A が同じバージョンを必要とすることで暗黙的に示されるため)。そのため、どちらも削除されます。メインモジュールに、example.com/B または example.com/C からパッケージを直接インポートするパッケージが含まれている場合、要件は保持されますが、実際に使用されているバージョンに更新されます。

最後に、更新により go.mod が標準の書式でフォーマットされるため、将来の機械的な変更による差分が最小限になります。書式変更のみが必要な場合、go コマンドは go.mod を更新しません。

モジュールグラフはインポートステートメントの意味を定義するため、パッケージを読み込むコマンドはすべて go.mod を使用し、更新できます。これには、go buildgo getgo installgo listgo testgo mod tidy が含まれます。

Go 1.15 以前では、-mod=mod フラグがデフォルトで有効になっていたため、更新が自動的に実行されていました。Go 1.16 以降では、go コマンドは -mod=readonly が設定されているかのように動作します。つまり、go.mod の変更が必要な場合、go コマンドはエラーを報告し、修正を提案します。

最小バージョン選択 (MVS)

Go は、パッケージをビルドする際に使用するモジュールバージョンのセットを選択するために、「最小バージョン選択 (MVS)」と呼ばれるアルゴリズムを使用します。MVS の詳細は、Russ Cox による最小バージョン選択で詳しく説明されています。

概念的には、MVS は、go.mod ファイルで指定されたモジュールの有向グラフで動作します。グラフの各頂点はモジュールバージョンを表し、各エッジは、require ディレクティブを使用して指定された、依存関係の最小必要なバージョンを表します。グラフは、メインモジュール(複数)の go.mod ファイル内の excludereplace ディレクティブ、および go.work ファイル内の replace ディレクティブによって変更できます。

MVS は、ビルド出力としてビルドリスト(ビルドに使用されるモジュールバージョンのリスト)を生成します。

MVS はメインモジュール(バージョンを持たないグラフ内の特別な頂点)から開始し、グラフをトラバースして、各モジュールの最高必要なバージョンを追跡します。トラバースの終了時に、最高必要なバージョンがビルドリストを構成します。これらは、すべての要件を満たす最小バージョンです。

ビルドリストは、go list -m all コマンドで確認できます。他の依存関係管理システムとは異なり、ビルドリストは「ロック」ファイルに保存されません。MVS は決定論的であり、依存関係の新しいバージョンがリリースされてもビルドリストは変更されないため、MVS はすべてのモジュール認識コマンドの開始時に使用されます。

以下の図の例を考えてみましょう。メインモジュールは、バージョン 1.2 以上のモジュール A と、バージョン 1.2 以上のモジュール B を必要とします。A 1.2 と B 1.2 はそれぞれ C 1.3 と C 1.4 を必要とします。C 1.3 と C 1.4 はどちらも D 1.2 を必要とします。

Module version graph with visited versions highlighted

MVS は、青で強調表示されたモジュールバージョンの go.mod ファイルにアクセスして読み込みます。グラフのトラバーサルが終了すると、MVS は太字で示されたバージョン(A 1.2、B 1.2、C 1.4、および D 1.2)を含むビルドリストを返します。B と D の上位バージョンは使用可能ですが、MVS はそれらを必要とするものがないため選択しません。

置換

モジュールの内容(go.mod ファイルを含む)は、メインモジュールの go.mod ファイルまたはワークスペースの go.work ファイルの replace ディレクティブ を使用して置き換えることができます。replace ディレクティブは、モジュールの特定のバージョンまたはモジュールのすべてのバージョンに適用できます。

置換によってモジュールグラフは変化します。置換されたモジュールは、置換前のバージョンとは異なる依存関係を持つ可能性があるためです。

以下の例を考えてみましょう。C 1.4がRに置換されています。RはD 1.2ではなくD 1.3に依存しているため、MVSはA 1.2、B 1.2、C 1.4(Rに置換)、D 1.3を含むビルドリストを返します。

Module version graph with a replacement

除外

特定のバージョンでモジュールを除外することもできます。メインモジュールのgo.modファイルでexcludeディレクティブを使用します。

除外もモジュールグラフを変更します。バージョンが除外されると、モジュールグラフから削除され、そのバージョンへの依存関係は次の上位バージョンにリダイレクトされます。

以下の例を考えてみましょう。C 1.3が除外されています。MVSは、A 1.2がC 1.3ではなくC 1.4(次の上位バージョン)を必要としているかのように動作します。

Module version graph with an exclusion

アップグレード

go getコマンドを使用して、モジュールのセットをアップグレードできます。アップグレードを実行するために、goコマンドはMVSを実行する前に、訪問されたバージョンからアップグレードされたバージョンへのエッジを追加することでモジュールグラフを変更します。

以下の例を考えてみましょう。モジュールBは1.2から1.3に、Cは1.3から1.4に、Dは1.2から1.3にアップグレードできます。

Module version graph with upgrades

アップグレード(およびダウングレード)によって、間接的な依存関係が追加または削除される場合があります。この場合、E 1.1とF 1.1は、E 1.1がB 1.3によって必要とされているため、アップグレード後にビルドリストに表示されます。

アップグレードを維持するために、goコマンドはgo.modの要件を更新します。Bに対する要件をバージョン1.3に変更します。また、それらのバージョンはそうでなければ選択されないため、C 1.4とD 1.3に対する要件を// indirectコメントと共に追加します。

ダウングレード

go getコマンドを使用して、モジュールのセットをダウングレードすることもできます。ダウングレードを実行するために、goコマンドは、ダウングレードされたバージョンより上のバージョンを削除することでモジュールグラフを変更します。また、削除されたバージョンに依存する他のモジュールのバージョンも削除します。それらは、依存関係のダウングレードされたバージョンと互換性がない可能性があるためです。メインモジュールがダウングレードによって削除されたモジュールバージョンを必要とする場合、要件は削除されていない以前のバージョンに変更されます。以前のバージョンがない場合、要件は削除されます。

以下の例を考えてみましょう。C 1.4に問題が見つかったため、C 1.3にダウングレードするとします。C 1.4はモジュールグラフから削除されます。B 1.2も、C 1.4以上を必要とするため削除されます。メインモジュールのBに対する要件は1.1に変更されます。

Module version graph with downgrade

go getは、引数の後に@noneサフィックスを使用して、依存関係を完全に削除することもできます。これはダウングレードと同様に機能します。指定されたモジュールのすべてのバージョンがモジュールグラフから削除されます。

モジュールグラフのプルーニング

メインモジュールがgo 1.17以上の場合、最小バージョン選択(MVS)に使用されるモジュールグラフには、独自のgo.modファイルでgo 1.17以上を指定する各モジュール依存関係の直接的な要件のみが含まれます。ただし、そのモジュールのバージョンが、他の依存関係go 1.16以下)によっても(推移的に)必要とされている場合を除きます。(go 1.17依存関係の推移的な依存関係は、モジュールグラフからプルーニングされます。)

go 1.17go.modファイルには、そのモジュール内の任意のパッケージまたはテストをビルドするために必要なすべての依存関係に対するrequireディレクティブが含まれているため、プルーニングされたモジュールグラフには、メインモジュールによって明示的に要求された任意の依存関係内のパッケージをgo buildまたはgo testするために必要なすべての依存関係が含まれます。特定のモジュールのパッケージまたはテストをビルドするために必要ないモジュールは、そのパッケージの実行時動作に影響を与えることはできないため、モジュールグラフからプルーニングされた依存関係は、そうでなければ無関係なモジュール間の干渉を引き起こすだけです。

要件がプルーニングされたモジュールは、モジュールグラフにまだ表示され、go list -m allによってまだ報告されます。それらの選択されたバージョンは既知であり、明確に定義されており、パッケージはそれらのモジュールからロードできます(たとえば、他のモジュールからロードされたテストの推移的な依存関係として)。ただし、goコマンドはこれらのモジュールのどの依存関係が満たされているかを容易に識別できないため、go buildおよびgo testの引数には、要件がプルーニングされたモジュールからのパッケージを含めることができません。go getは、名前付きパッケージを含むモジュールを明示的な依存関係に昇格させることで、そのパッケージでgo buildまたはgo testを呼び出すことができます。

Go 1.16以前はモジュールグラフのプルーニングをサポートしていなかったため、推移的なgo 1.17依存関係を含む依存関係の完全な推移的閉包は、go 1.16以下のものを指定する各モジュールに対してまだ含まれています。(go 1.16以下では、go.modファイルには直接的な依存関係のみが含まれているため、すべての間接的な依存関係が含まれるようにするには、はるかに大きなグラフをロードする必要があります。)

go mod tidyによってモジュールに対して記録されたgo.sumファイルには、そのgoディレクティブで指定されたバージョンより1つ下のGoバージョンが必要とするチェックサムがデフォルトで含まれています。そのため、go 1.17モジュールには、Go 1.16によってロードされた完全なモジュールグラフに必要なチェックサムが含まれていますが、go 1.18モジュールには、Go 1.17によってロードされたプルーニングされたモジュールグラフに必要なチェックサムのみが含まれます。-compatフラグを使用して、デフォルトのバージョンを上書きできます(たとえば、go 1.17モジュールでgo.sumファイルをより積極的にプルーニングする場合)。

詳細については、設計文書を参照してください。

遅延モジュール読み込み

モジュールグラフのプルーニングに追加されたより包括的な要件により、モジュール内で作業する場合にも別の最適化が可能になります。メインモジュールがgo 1.17以上の場合、goコマンドは、必要になるまで(そして、必要ない限り)完全なモジュールグラフのロードを回避します。代わりに、メインモジュールのgo.modファイルのみをロードし、その後、それらの要件のみを使用してビルドするパッケージのロードを試みます。インポートするパッケージ(たとえば、メインモジュール外のpackageのテストの依存関係)がそれらの要件に見つからない場合、モジュールグラフの残りの部分がオンデマンドでロードされます。

モジュールグラフをロードせずにすべてのインポートされたパッケージが見つかった場合、goコマンドはそれらのパッケージを含むモジュールのgo.modファイルのみをロードし、それらの要件はメインモジュールの要件に対してチェックされて、ローカルで整合性があることを確認します。(整合性の不一致は、バージョン管理のマージ、手動編集、およびローカルファイルシステムパスを使用して置換されたモジュールの変更によって発生する可能性があります。)

ワークスペース

ワークスペースとは、ディスク上のモジュールの集合であり、最小バージョン選択(MVS)を実行するときにメインモジュールとして使用されます。

ワークスペースは、ワークスペース内の各モジュールのモジュールディレクトリへの相対パスを指定するgo.workファイルで宣言できます。go.workファイルが存在しない場合、ワークスペースは現在のディレクトリを含む単一のモジュールで構成されます。

モジュールを操作するほとんどのgoサブコマンドは、現在のワークスペースによって決定されたモジュールのセットに対して動作します。go mod initgo mod whygo mod editgo mod tidygo mod vendor、およびgo getは常に単一のメインモジュールに対して動作します。

コマンドは、最初にGOWORK環境変数を調べて、ワークスペースコンテキスト内にあるかどうかを判断します。GOWORKoffに設定されている場合、コマンドは単一モジュールコンテキストになります。空の場合、または提供されていない場合、コマンドは現在の作業ディレクトリ、次に連続する親ディレクトリを検索して、go.workファイルを探します。ファイルが見つかった場合、コマンドはそれが定義するワークスペースで動作します。そうでない場合、ワークスペースには作業ディレクトリを含むモジュールのみが含まれます。GOWORKが`.work`で終わる既存のファイルへのパスを指定する場合、ワークスペースモードが有効になります。それ以外の値はエラーです。go env GOWORKコマンドを使用して、goコマンドが使用しているgo.workファイルを確認できます。goコマンドがワークスペースモードでない場合、go env GOWORKは空になります。

go.workファイル

ワークスペースは、UTF-8でエンコードされたテキストファイル(go.workという名前)によって定義されます。go.workファイルは行指向です。各行は、キーワードと引数で構成される単一のディレクティブを保持します。たとえば

go 1.18

use ./my/first/thing
use ./my/second/thing

replace example.com/bad/thing v1.4.5 => example.com/good/thing v1.4.5

go.modファイルと同様に、先行するキーワードを隣接する行から要因分解してブロックを作成できます。

use (
    ./my/first/thing
    ./my/second/thing
)

goコマンドは、go.workファイルを操作するためのいくつかのサブコマンドを提供します。go work initは新しいgo.workファイルを作成します。go work useはモジュールディレクトリをgo.workファイルに追加します。go work editは低レベルの編集を実行します。golang.org/x/mod/modfileパッケージは、Goプログラムが同じ変更をプログラム的に行うために使用できます。

goコマンドは、集合ワークスペースモジュールのgo.sumファイルにないワークスペースで使用されるハッシュを追跡するgo.work.sumファイルを維持します。

一般的に、2つの理由から、go.workファイルをバージョン管理システムにコミットすることはお勧めできません。

とはいえ、go.workファイルをコミットすることが理にかなう場合もあります。たとえば、リポジトリ内のモジュールが互いに排他的に開発され、外部モジュールと同時に開発されない場合、開発者がワークスペースで異なるモジュールの組み合わせを使用したい理由がない場合があります。その場合、モジュール作成者は、個々のモジュールが正しくテストされ、リリースされていることを確認する必要があります。

字句要素

go.workファイル内の字句要素は、go.modファイルとまったく同じ方法で定義されています。

文法

go.work構文は、拡張バッカス・ナウア記法(EBNF)を使用して以下に指定されています。EBNF構文の詳細については、Go言語仕様の表記セクションを参照してください。

GoWork = { Directive } .
Directive = GoDirective |
            ToolchainDirective |
            UseDirective |
            ReplaceDirective .

改行、識別子、文字列は、それぞれnewlineidentstringで示されます。

モジュールパスとバージョンは、ModulePathVersionで表されます。モジュールパスとバージョンは、go.modファイルとまったく同じ方法で指定されています。

ModulePath = ident | string . /* see restrictions above */
Version = ident | string .    /* see restrictions above */

goディレクティブ

有効なgo.workファイルには、goディレクティブが必要です。バージョンは有効なGoリリースバージョンである必要があります。正の整数にドットと非負の整数が続きます(たとえば、1.181.19)。

goディレクティブは、go.workファイルが動作することを意図するGoツールチェーンのバージョンを示します。go.workファイルの形式に変更が加えられた場合、将来のバージョンのツールチェーンは、その指定されたバージョンに従ってファイルを解釈します。

go.workファイルには、goディレクティブを最大1つ含めることができます。

GoDirective = "go" GoVersion newline .
GoVersion = string | ident .  /* valid release version; see above */

go 1.18

toolchainディレクティブ

toolchainディレクティブは、ワークスペースで使用することを推奨するGoツールチェーンを宣言します。これは、デフォルトのツールチェーンが推奨されるツールチェーンより古い場合にのみ効果があります。

詳細については、「Goツールチェーン」を参照してください。

ToolchainDirective = "toolchain" ToolchainName newline .
ToolchainName = string | ident .  /* valid toolchain name; see “Go toolchains” */

toolchain go1.21.0

godebugディレクティブ

godebug ディレクティブは、このワークスペースで作業する際に適用する単一のGODEBUG 設定を宣言します。構文と効果は、go.mod ファイルの godebug ディレクティブ と同じです。ワークスペースが使用されている場合、go.mod ファイル内の godebug ディレクティブは無視されます。

use ディレクティブ

use は、ディスク上のモジュールをワークスペースのメインモジュールのセットに追加します。その引数は、モジュールの go.mod ファイルを含むディレクトリへの相対パスです。use ディレクティブは、その引数ディレクトリのサブディレクトリに含まれるモジュールを追加しません。これらのモジュールは、個別の use ディレクティブで、それらの go.mod ファイルを含むディレクトリによって追加できます。

UseDirective = "use" ( UseSpec | "(" newline { UseSpec } ")" newline ) .
UseSpec = FilePath newline .
FilePath = /* platform-specific relative or absolute file path */

use ./mymod  // example.com/mymod

use (
    ../othermod
    ./subdir/thirdmod
)

replaceディレクティブ

go.mod ファイルの replace ディレクティブと同様に、go.work ファイルの replace ディレクティブは、モジュールの特定のバージョン、またはモジュールのすべてのバージョンの内容を、別の場所に存在する内容に置き換えます。go.work のワイルドカード置換は、go.mod ファイルのバージョン固有の replace をオーバーライドします。

go.work ファイルの replace ディレクティブは、ワークスペースモジュール内の同じモジュールまたはモジュールバージョンの置換をオーバーライドします。

ReplaceDirective = "replace" ( ReplaceSpec | "(" newline { ReplaceSpec } ")" newline ) .
ReplaceSpec = ModulePath [ Version ] "=>" FilePath newline
            | ModulePath [ Version ] "=>" ModulePath Version newline .
FilePath = /* platform-specific relative or absolute file path */

replace golang.org/x/net v1.2.3 => example.com/fork/net v1.4.5

replace (
    golang.org/x/net v1.2.3 => example.com/fork/net v1.4.5
    golang.org/x/net => example.com/fork/net v1.4.5
    golang.org/x/net v1.2.3 => ./fork/net
    golang.org/x/net => ./fork/net
)

非モジュールリポジトリとの互換性

GOPATH からモジュールへのスムーズな移行を保証するために、go コマンドは、go.mod ファイル を追加することで、モジュールに移行していないリポジトリからモジュール認識モードでパッケージをダウンロードしてビルドできます。

go コマンドが特定のバージョンでモジュールを直接リポジトリからダウンロードする場合、モジュールパスのリポジトリURLを検索し、バージョンをリポジトリ内のリビジョンにマップしてから、そのリビジョンでのリポジトリのアーカイブを抽出します。モジュールのパスリポジトリのルートパスと等しく、リポジトリのルートディレクトリに go.mod ファイルが含まれていない場合、go コマンドは、module ディレクティブのみを含む go.mod ファイルをモジュールキャッシュに合成します。合成された go.mod ファイルには、その依存関係に対するrequire ディレクティブが含まれていないため、それらに依存する他のモジュールは、追加の require ディレクティブ(// indirect コメント付き)が必要になる場合があります。これは、すべてのビルドで各依存関係が同じバージョンでフェッチされるようにするためです。

go コマンドがプロキシからモジュールをダウンロードする場合、モジュールの残りのコンテンツとは別に go.mod ファイルをダウンロードします。プロキシは、元のモジュールに go.mod ファイルがない場合、合成された go.mod ファイルを提供することが期待されます。

+incompatible バージョン

メジャーバージョン2以上でリリースされたモジュールは、そのモジュールパスに一致するメジャーバージョンサフィックスが必要です。たとえば、モジュールが v2.0.0 でリリースされた場合、そのパスには /v2 サフィックスが必要です。これにより、go コマンドは、同じリポジトリで開発されている場合でも、プロジェクトの複数のメジャーバージョンを別々のモジュールとして扱うことができます。

メジャーバージョンサフィックスの要件は、モジュールサポートが go コマンドに追加されたときに導入されました。多くのリポジトリは、それより前にメジャーバージョン 2 以上でリリースをタグ付けしていました。これらのリポジトリとの互換性を維持するために、go コマンドは、go.mod ファイルを持たないメジャーバージョン2以上のバージョンに +incompatible サフィックスを追加します。+incompatible は、バージョンがより低いメジャーバージョン番号を持つバージョンと同じモジュールの一部であることを示しています。その結果、ビルドが中断される可能性がある場合でも、go コマンドはより高い +incompatible バージョンに自動的にアップグレードすることがあります。

以下の要件の例を考えてみましょう。

require example.com/m v4.1.2+incompatible

バージョン v4.1.2+incompatible は、モジュール example.com/m を提供するリポジトリのセマンティックバージョンタグ v4.1.2 を参照します。モジュールはリポジトリのルートディレクトリに存在する必要があり(つまり、リポジトリのルートパスexample.com/m である必要があります)、go.mod ファイルが存在してはなりません。モジュールには、v1.5.2 のようなより低いメジャーバージョン番号を持つバージョンが存在し、go コマンドはこれらのバージョンから v4.1.2+incompatible に自動的にアップグレードすることがあります(アップグレードのしくみについては、最小バージョン選択(MVS)を参照してください)。

バージョン v2.0.0 がタグ付けされた後にモジュールに移行するリポジトリは、通常、新しいメジャーバージョンをリリースする必要があります。上記の例では、作成者は example.com/m/v5 というパスを持つモジュールを作成し、バージョン v5.0.0 をリリースする必要があります。作成者は、モジュール内のパッケージのインポートを更新して、example.com/m の代わりに example.com/m/v5 というプレフィックスを使用する必要があります。より詳細な例については、Go Modules: v2 and Beyond を参照してください。

+incompatible サフィックスは、リポジトリのタグには表示されないことに注意してください。v4.1.2+incompatible のようなタグは無視されます。サフィックスは、go コマンドで使用されるバージョンにのみ表示されます。バージョンとタグの違いの詳細については、バージョンとコミットのマッピング を参照してください。

また、+incompatible サフィックスは疑似バージョンに表示される場合があることにも注意してください。たとえば、v2.0.1-20200722182040-012345abcdef+incompatible は有効な疑似バージョンです。

最小モジュール互換性

メジャーバージョン2以上でリリースされたモジュールは、そのモジュールパスメジャーバージョンサフィックスが必要です。モジュールは、リポジトリ内のメジャーバージョンサブディレクトリで開発されている場合とされていない場合があります。これは、GOPATH モードでビルドする際に、モジュール内のパッケージをインポートするパッケージに影響を与えます。

通常、GOPATH モードでは、パッケージは、そのリポジトリのルートパスとリポジトリ内のディレクトリを結合したディレクトリに格納されます。たとえば、ルートパスが example.com/repo で、サブディレクトリが sub であるリポジトリのパッケージは、$GOPATH/src/example.com/repo/sub に格納され、example.com/repo/sub としてインポートされます。

メジャーバージョンサフィックスを持つモジュールの場合、パッケージ example.com/repo/v2/sub はディレクトリ $GOPATH/src/example.com/repo/v2/sub にあることが予想されます。そのためには、モジュールをリポジトリの v2 サブディレクトリで開発する必要があります。go コマンドはこれをサポートしますが、要求しません(バージョンとコミットのマッピングを参照してください)。

モジュールがメジャーバージョンサブディレクトリで開発されていない場合、GOPATH 内のそのディレクトリにはメジャーバージョンサフィックスが含まれず、そのパッケージはメジャーバージョンサフィックスなしでインポートできます。上記の例では、パッケージはディレクトリ $GOPATH/src/example.com/repo/sub にあり、example.com/repo/sub としてインポートされます。

これにより、モジュールモードと GOPATH モードの両方でビルドされることを意図したパッケージに問題が発生します。モジュールモードにはサフィックスが必要ですが、GOPATH モードには必要ありません。

これを修正するために、Go 1.11 で最小モジュール互換性が追加され、Go 1.9.7 および 1.10.3 にバックポートされました。インポートパスが GOPATH モードでディレクトリに解決されるとき

これらのルールにより、メジャーバージョンサブディレクトリが使用されていない場合でも、GOPATH モードでビルドするときに、モジュールに移行されたパッケージが、他のモジュールに移行されたパッケージをインポートできるようになります。

モジュール認識コマンド

ほとんどの go コマンドは、モジュール認識モードまたはGOPATH モードで実行できます。モジュール認識モードでは、go コマンドは go.mod ファイルを使用してバージョン付きの依存関係を見つけ、通常はモジュールキャッシュからパッケージを読み込み、不足しているモジュールをダウンロードします。GOPATH モードでは、go コマンドはモジュールを無視し、依存関係を見つけるためにvendor ディレクトリGOPATH を検索します。

Go 1.16 以降、go.mod ファイルが存在するかに関係なく、モジュール認識モードがデフォルトで有効になっています。それ以前のバージョンでは、モジュール認識モードは、現在のディレクトリまたは任意の親ディレクトリに go.mod ファイルが存在する場合に有効になっていました。

モジュール認識モードは、GO111MODULE 環境変数で制御できます。この変数は、onoff、または auto に設定できます。

モジュール認識モードでは、GOPATH はビルド中のインポートの意味を定義しなくなりましたが、ダウンロードされた依存関係(GOPATH/pkg/mod にあります。モジュールキャッシュを参照)とインストールされたコマンド(GOBIN が設定されていない限り、GOPATH/bin にあります)は引き続き格納します。

ビルドコマンド

パッケージに関する情報をロードするすべてのコマンドは、モジュール認識機能を備えています。これには以下が含まれます。

モジュール認識モードで実行されると、これらのコマンドは go.mod ファイルを使用して、コマンドラインにリストされているか、Go ソースファイルに記述されているインポートパスを解釈します。これらのコマンドは、すべてのモジュールコマンドに共通する次のフラグを受け入れます。

ベンダーリング

モジュールを使用する場合、go コマンドは通常、モジュールキャッシュにソースからモジュールをダウンロードしてから、ダウンロードしたコピーからパッケージを読み込むことで、依存関係を満たします。 ベンダーリング は、古いバージョンの Go との相互運用を許可したり、ビルドに使用されるすべてのファイルが単一のファイルツリーに格納されるようにするために使用できます。

go mod vendor コマンドは、メインモジュールのルートディレクトリvendor という名前のディレクトリを作成し、メインモジュール内のパッケージをビルドおよびテストするために必要なすべてのパッケージのコピーを含みます。メインモジュール外の他のパッケージのテストによってのみインポートされるパッケージは含まれません。go mod tidy などの他のモジュールコマンドと同様に、ビルド制約ignore を除く)は、vendor ディレクトリを作成する際に考慮されません。

go mod vendor は、ベンダーされたパッケージとそのコピー元のモジュールバージョンの一覧を含む vendor/modules.txt ファイルも作成します。ベンダーリングが有効になっている場合、このマニフェストは、go list -mgo version -m によって報告されるモジュールバージョン情報のソースとして使用されます。go コマンドが vendor/modules.txt を読み取ると、モジュールバージョンが go.mod と一致しているかどうかを確認します。vendor/modules.txt が生成されてから go.mod が変更された場合、go コマンドはエラーを報告します。vendor ディレクトリを更新するには、go mod vendor を再度実行する必要があります。

メインモジュールのルートディレクトリに vendor ディレクトリが存在する場合、メインモジュールのgo.mod ファイル内のgo バージョン1.14 以上であれば、自動的に使用されます。ベンダーリングを明示的に有効にするには、-mod=vendor フラグを付けて go コマンドを呼び出します。ベンダーリングを無効にするには、-mod=readonly または -mod=mod フラグを使用します。

ベンダーリングが有効になっている場合、go buildgo test などのビルドコマンドは、ネットワークまたはローカルモジュールキャッシュにアクセスする代わりに、vendor ディレクトリからパッケージを読み込みます。go list -m コマンドは、go.mod にリストされているモジュールに関する情報のみを出力します。go mod downloadgo mod tidy などの go mod コマンドは、ベンダーリングが有効になっている場合でも動作が変わりません。モジュールをダウンロードし、モジュールキャッシュにアクセスします。go get も、ベンダーリングが有効になっている場合でも動作が変わりません。

GOPATH モードでのベンダーリングとは異なり、go コマンドは、メインモジュールのルートディレクトリ以外の場所にあるベンダーディレクトリを無視します。さらに、他のモジュール内のベンダーディレクトリは使用されないため、go コマンドはモジュールzipファイルをビルドするときにベンダーディレクトリを含めません(ただし、既知のバグ#31562#37397を参照)。

go get

使用方法

go get [-d] [-t] [-u] [build flags] [packages]

# Upgrade a specific module.
$ go get golang.org/x/net

# Upgrade modules that provide packages imported by packages in the main module.
$ go get -u ./...

# Upgrade or downgrade to a specific version of a module.
$ go get golang.org/x/text@v0.3.2

# Update to the commit on the module's master branch.
$ go get golang.org/x/text@master

# Remove a dependency on a module and downgrade modules that require it
# to versions that don't require it.
$ go get golang.org/x/text@none

# Upgrade the minimum required Go version for the main module.
$ go get go

# Upgrade the suggested Go toolchain, leaving the minimum Go version alone.
$ go get toolchain

# Upgrade to the latest patch release of the suggested Go toolchain.
$ go get toolchain@patch

go get コマンドは、メインモジュールgo.mod ファイルのモジュール依存関係を更新し、その後、コマンドラインにリストされているパッケージをビルドしてインストールします。

最初のステップは、更新するモジュールを決定することです。go get は、パッケージ、パッケージパターン、モジュールパスのリストを引数として受け入れます。パッケージ引数が指定されている場合、go get はそのパッケージを提供するモジュールを更新します。パッケージパターンが指定されている場合(たとえば、all... ワイルドカード付きのパス)、go get はパターンをパッケージのセットに展開し、パッケージを提供するモジュールを更新します。引数がモジュールを名前付けしているがパッケージを名前付けていない場合(たとえば、モジュール golang.org/x/net にはルートディレクトリにパッケージがありません)、go get はモジュールを更新しますが、パッケージはビルドしません。引数が指定されていない場合、go get. が指定されたものとして動作します(現在のディレクトリのパッケージ)。これは、-u フラグと組み合わせて、インポートされたパッケージを提供するモジュールを更新するために使用できます。

各引数には、目的のバージョンを示すバージョン照会サフィックスを含めることができます(例:go get golang.org/x/text@v0.3.0)。バージョン照会サフィックスは、@ 記号に続いてバージョン照会で構成され、特定のバージョン(v0.3.0)、バージョン接頭辞(v0.3)、ブランチ名またはタグ名(master)、リビジョン(1234abcd)、または特別な照会 latestupgradepatchnone のいずれかを指定できます。バージョンが指定されていない場合、go get@upgrade 照会を使用します。

go get が引数を特定のモジュールとバージョンに解決すると、go get は、メインモジュールの go.mod ファイルのrequire ディレクティブを追加、変更、または削除して、モジュールが将来も目的のバージョンを維持するようにします。go.mod ファイルの必須バージョンは最小バージョンであり、新しい依存関係が追加されると自動的に増加する可能性があることに注意してください。バージョンがどのように選択され、モジュール認識コマンドによって競合がどのように解決されるかについては、最小バージョン選択(MVS)を参照してください。

コマンドラインで名前付けされたモジュールが追加、アップグレード、またはダウングレードされると、他のモジュールがアップグレードされる場合があります。新しいバージョンの名前付きモジュールが他のモジュールをより高いバージョンで要求する場合です。たとえば、モジュール example.com/a がバージョン v1.5.0 にアップグレードされ、そのバージョンがモジュール example.com/b をバージョン v1.2.0 で要求するとします。モジュール example.com/b が現在バージョン v1.1.0 で要求されている場合、go get example.com/a@v1.5.0example.com/bv1.2.0 にアップグレードします。

go get upgrading a transitive requirement

コマンドラインで名前付けされたモジュールがダウングレードまたは削除されると、他のモジュールがダウングレードされる場合があります。上記の例を続けると、モジュール example.com/bv1.1.0 にダウングレードされるとします。モジュール example.com/a も、バージョン v1.1.0 以下で example.com/b を必要とするバージョンにダウングレードされます。

go get downgrading a transitive requirement

バージョンサフィックス @none を使用して、モジュールの要件を削除できます。これは一種の特別なダウングレードです。削除されたモジュールに依存するモジュールは、必要に応じてダウングレードまたは削除されます。そのパッケージの1つ以上がメインモジュールのパッケージによってインポートされている場合でも、モジュールの要件を削除できます。この場合、次のビルドコマンドで新しいモジュールの要件が追加される可能性があります。

モジュールが2つの異なるバージョン(コマンドライン引数で明示的に指定するか、アップグレードとダウングレードを満たすために指定)で必要とされる場合、go get はエラーを報告します。

go get が新しいバージョンのセットを選択した後、新しく選択されたモジュールバージョン、またはコマンドラインで名前付けされたパッケージを提供するモジュールがリトラクトされているか非推奨かどうかを確認します。go get は、検出されたリトラクトされたバージョンまたは非推奨のモジュールごとに警告を出力します。go list -m -u all を使用して、すべての依存関係のリトラクションと非推奨を確認できます。

go getgo.mod ファイルを更新した後、コマンドラインで名前付けされたパッケージをビルドします。実行ファイルは、GOBIN 環境変数によって名前付けされたディレクトリにインストールされます。これは、GOPATH 環境変数が設定されていない場合、$GOPATH/bin または $HOME/go/bin をデフォルトとします。

go get は次のフラグをサポートします。

Go 1.16 以降、go install はプログラムのビルドとインストールに推奨されるコマンドです。バージョンサフィックス(@latest@v1.4.6 など)と一緒に使用すると、go install はモジュール認識モードでパッケージをビルドし、現在のディレクトリまたは親ディレクトリ(存在する場合)の go.mod ファイルを無視します。

go get は、go.mod の要件の管理に重点を置いています。-d フラグは非推奨であり、Go 1.18 では常に有効になります。

go install

使用方法

go install [build flags] [packages]

# Install the latest version of a program,
# ignoring go.mod in the current directory (if any).
$ go install golang.org/x/tools/gopls@latest

# Install a specific version of a program.
$ go install golang.org/x/tools/gopls@v0.6.4

# Install a program at the version selected by the module in the current directory.
$ go install golang.org/x/tools/gopls

# Install all programs in a directory.
$ go install ./cmd/...

go install コマンドは、コマンドラインのパスによって名前付けされたパッケージをビルドしてインストールします。実行ファイル(main パッケージ)は、GOBIN 環境変数によって名前付けされたディレクトリにインストールされます。これは、GOPATH 環境変数が設定されていない場合、$GOPATH/bin または $HOME/go/bin をデフォルトとします。$GOROOT 内の実行ファイルは、$GOBIN の代わりに $GOROOT/bin または $GOTOOLDIR にインストールされます。実行可能ではないパッケージはビルドされキャッシュされますが、インストールされません。

Go 1.16 以降、引数にバージョンサフィックス(@latest@v1.0.0 など)がある場合、go install はモジュール認識モードでパッケージをビルドし、現在のディレクトリまたは親ディレクトリ(存在する場合)の go.mod ファイルを無視します。これは、メインモジュールの依存関係に影響を与えることなく実行ファイルをインストールする場合に役立ちます。

ビルドで使用されるモジュールバージョンに関する曖昧さを排除するために、引数は以下の制約を満たす必要があります。

サポートされているバージョン問い合わせ構文については、バージョン問い合わせを参照してください。Go 1.15以前では、go installでバージョン問い合わせを使用することができませんでした。

引数にバージョンサフィックスがない場合、go installは、GO111MODULE環境変数とgo.modファイルの存在に応じて、モジュール認識モードまたはGOPATHモードで実行される場合があります。詳細については、モジュール認識コマンドを参照してください。モジュール認識モードが有効になっている場合、go installはメインモジュールのコンテキストで実行されますが、これはインストールされているパッケージを含むモジュールとは異なる場合があります。

go list -m

使用方法

go list -m [-u] [-retracted] [-versions] [list flags] [modules]

$ go list -m all
$ go list -m -versions example.com/m
$ go list -m -json example.com/m@latest

-mフラグにより、go listはパッケージではなくモジュールを一覧表示します。このモードでは、go listへの引数は、モジュール、モジュールパターン(...ワイルドカードを含む)、バージョン問い合わせ、またはビルドリスト内のすべてのモジュールに一致する特殊パターンallですることができます。引数を指定しない場合、メインモジュールが一覧表示されます。

モジュールを一覧表示する場合、-fフラグはGo構造体に適用されるフォーマットテンプレートを指定しますが、現在はModule構造体になります。

type Module struct {
    Path       string        // module path
    Version    string        // module version
    Versions   []string      // available module versions
    Replace    *Module       // replaced by this module
    Time       *time.Time    // time version was created
    Update     *Module       // available update (with -u)
    Main       bool          // is this the main module?
    Indirect   bool          // module is only indirectly needed by main module
    Dir        string        // directory holding local copy of files, if any
    GoMod      string        // path to go.mod file describing module, if any
    GoVersion  string        // go version used in module
    Retracted  []string      // retraction information, if any (with -retracted or -u)
    Deprecated string        // deprecation message, if any (with -u)
    Error      *ModuleError  // error loading module
}

type ModuleError struct {
    Err string // the error itself
}

デフォルトの出力は、モジュールパスを出力し、次にバージョンと置換に関する情報を表示することです。たとえば、go list -m allは次のように出力される場合があります。

example.com/main/module
golang.org/x/net v0.1.0
golang.org/x/text v0.3.0 => /tmp/text
rsc.io/pdf v0.1.1

Module構造体には、この出力行をフォーマットするStringメソッドがあるため、デフォルトのフォーマットは-f '{{.String}}'と同じになります。

モジュールが置換されている場合、そのReplaceフィールドは置換モジュールを記述し、Dirフィールドは、存在する場合は置換モジュールのソースコードに設定されます。(つまり、Replaceがnull以外の場合、DirReplace.Dirに設定され、置換されたソースコードにはアクセスできません。)

-uフラグは、利用可能なアップグレードに関する情報を追加します。特定のモジュールの最新バージョンが現在のバージョンよりも新しい場合、list -uはモジュールのUpdateフィールドを新しいモジュールに関する情報に設定します。list -uは、現在選択されているバージョンがリトラクトされているか、モジュールが非推奨であるかも出力します。モジュールのStringメソッドは、現在のバージョンの後に新しいバージョンを括弧で囲んでフォーマットすることにより、利用可能なアップグレードを示します。たとえば、go list -m -u allは次のように出力される場合があります。

example.com/main/module
golang.org/x/old v1.9.9 (deprecated)
golang.org/x/net v0.1.0 (retracted) [v0.2.0]
golang.org/x/text v0.3.0 [v0.4.0] => /tmp/text
rsc.io/pdf v0.1.1 [v0.1.2]

(ツールの場合、go list -m -u -json allの方が解析が容易です。)

-versionsフラグにより、listはモジュールのVersionsフィールドを、そのモジュールのすべての既知のバージョン(セマンティックバージョニングに従って、最も低い順に並べ替えられたもの)のリストに設定します。このフラグは、デフォルトの出力形式も変更し、モジュールパスにスペースで区切られたバージョンリストを続けて表示します。リトラクトされたバージョンはこのリストから省略されますが、-retractedフラグも指定されている場合は除きます。

-retractedフラグは、-versionsフラグで出力されるリストにリトラクトされたバージョンを表示し、バージョン問い合わせを解決する際にリトラクトされたバージョンを考慮するようにlistに指示します。たとえば、go list -m -retracted example.com/m@latestは、そのバージョンがリトラクトされている場合でも、モジュールexample.com/mの最も高いリリースバージョンまたはプレリリースバージョンを表示します。retractディレクティブ非推奨はこのバージョンのgo.modファイルから読み込まれます。-retractedフラグはGo 1.16で追加されました。

テンプレート関数moduleは、モジュールパスまたはクエリでなければならない単一の文字列引数を取り、指定されたモジュールをModule構造体として返します。エラーが発生した場合、結果はErrorフィールドがnull以外であるModule構造体になります。

go mod download

使用方法

go mod download [-x] [-json] [-reuse=old.json] [modules]

$ go mod download
$ go mod download golang.org/x/mod@v0.2.0

go mod downloadコマンドは、指定されたモジュールをモジュールキャッシュにダウンロードします。引数は、メインモジュールの依存関係を選択するモジュールパスまたはモジュールパターン、またはpath@version形式のバージョン問い合わせです。引数を指定しないと、downloadメインモジュールのすべての依存関係に適用されます。

goコマンドは、通常の操作中に必要に応じて自動的にモジュールをダウンロードします。go mod downloadコマンドは、主にモジュールキャッシュを事前に埋めたり、モジュールプロキシによって提供されるデータをロードするために役立ちます。

デフォルトでは、downloadは標準出力に何も書き込みません。進行状況メッセージとエラーは標準エラーに出力されます。

-jsonフラグにより、downloadは標準出力にJSONオブジェクトのシーケンスを出力し、ダウンロードされた各モジュール(またはエラー)を記述します。これは、このGo構造体に相当します。

type Module struct {
    Path     string // module path
    Query    string // version query corresponding to this version
    Version  string // module version
    Error    string // error loading module
    Info     string // absolute path to cached .info file
    GoMod    string // absolute path to cached .mod file
    Zip      string // absolute path to cached .zip file
    Dir      string // absolute path to cached source root directory
    Sum      string // checksum for path, version (as in go.sum)
    GoModSum string // checksum for go.mod (as in go.sum)
    Origin   any    // provenance of module
    Reuse    bool   // reuse of old module info is safe
}

-xフラグにより、downloaddownloadが実行するコマンドを標準エラーに出力します。

-reuseフラグは、以前の「go mod download -json」呼び出しのJSON出力を含むファイルの名前を受け入れます。goコマンドはこのファイルを使用して、モジュールが以前の呼び出し以降に変更されていないことを判断し、再ダウンロードを回避できます。再ダウンロードされないモジュールは、Reuseフィールドをtrueに設定することで、新しい出力でマークされます。通常、モジュールキャッシュはこの種の再利用を自動的に提供します。-reuseフラグは、モジュールキャッシュを保持しないシステムで役立ちます。

go mod edit

使用方法

go mod edit [editing flags] [-fmt|-print|-json] [go.mod]

# Add a replace directive.
$ go mod edit -replace example.com/a@v1.0.0=./a

# Remove a replace directive.
$ go mod edit -dropreplace example.com/a@v1.0.0

# Set the go version, add a requirement, and print the file
# instead of writing it to disk.
$ go mod edit -go=1.14 -require=example.com/m@v1.0.0 -print

# Format the go.mod file.
$ go mod edit -fmt

# Format and print a different .mod file.
$ go mod edit -print tools.mod

# Print a JSON representation of the go.mod file.
$ go mod edit -json

go mod editコマンドは、主にツールやスクリプトで使用するために、go.modファイルの編集とフォーマットのためのコマンドラインインターフェースを提供します。go mod editは1つのgo.modファイルのみを読み取ります。他のモジュールに関する情報は参照しません。デフォルトでは、go mod editはメインモジュールのgo.modファイルを読み書きしますが、編集フラグの後に異なるターゲットファイルを指定できます。

編集フラグは、一連の編集操作を指定します。

編集フラグは複数回繰り返すことができます。変更は指定された順序で適用されます。

go mod editには、出力を制御する追加のフラグがあります。

type Module struct {
    Path    string
    Version string
}

type GoMod struct {
    Module  ModPath
    Go      string
    Require []Require
    Exclude []Module
    Replace []Replace
    Retract []Retract
}

type ModPath struct {
    Path       string
    Deprecated string
}

type Require struct {
    Path     string
    Version  string
    Indirect bool
}

type Replace struct {
    Old Module
    New Module
}

type Retract struct {
    Low       string
    High      string
    Rationale string
}

これは、間接的に参照される他のモジュールではなく、go.modファイル自体のみを説明していることに注意してください。ビルドで使用できるモジュールの完全なセットについては、go list -m -json allを使用してください。go list -mを参照してください。

たとえば、ツールはgo mod edit -jsonの出力を解析することでgo.modファイルをデータ構造として取得し、-require-excludeなどを用いてgo mod editを呼び出すことで変更を加えることができます。

ツールは、golang.org/x/mod/modfileパッケージを使用して、go.modファイルの解析、編集、およびフォーマットを行うこともできます。

go mod graph

使用方法

go mod graph [-go=version]

go mod graphコマンドは、モジュール要件グラフ(置換が適用されたもの)をテキスト形式で出力します。例:

example.com/main example.com/a@v1.1.0
example.com/main example.com/b@v1.2.0
example.com/a@v1.1.0 example.com/b@v1.1.1
example.com/a@v1.1.0 example.com/c@v1.3.0
example.com/b@v1.1.0 example.com/c@v1.1.0
example.com/b@v1.2.0 example.com/c@v1.2.0

モジュールグラフの各頂点は、モジュールの特定のバージョンを表します。グラフの各エッジは、依存関係の最小バージョンに対する要件を表します。

go mod graph はグラフのエッジを1行ずつ出力します。各行には、スペースで区切られた2つのフィールドがあります。1つはモジュールバージョン、もう1つはモジュールの依存関係の1つです。各モジュールバージョンは、path@version形式の文字列として識別されます。メインモジュールには@versionサフィックスがありません。バージョンがないためです。

-goフラグを使用すると、go mod graphは、go.modファイルのgoディレクティブで示されたバージョンではなく、指定されたGoバージョンによってロードされたモジュールグラフを報告します。

バージョンの選択方法の詳細については、最小バージョン選択(MVS)を参照してください。go list -mで選択されたバージョンを出力する方法、およびgo mod whyでモジュールが必要な理由を理解する方法についても参照してください。

go mod init

使用方法

go mod init [module-path]

go mod init
go mod init example.com/m

go mod initコマンドは、新しいgo.modファイルを現在のディレクトリに初期化して書き込みます。これにより、現在のディレクトリにルートを持つ新しいモジュールが作成されます。go.modファイルは既に存在してはなりません。

initは、新しいモジュールのモジュールパスをオプションの引数として1つ受け付けます。モジュールパスの選択方法については、指示を参照してください。モジュールパスの引数が省略された場合、init.goファイルのインポートコメント、ベンダーツール設定ファイル、現在のディレクトリ(GOPATH内にある場合)を使用してモジュールパスを推測しようとします。

ベンダーツールの設定ファイルが存在する場合、initはそのファイルからモジュールの要件をインポートしようとします。initは次の設定ファイルに対応しています。

ベンダーツール設定ファイルは、常に完璧な忠実度で変換できるとは限りません。たとえば、同じリポジトリ内の複数のパッケージが異なるバージョンでインポートされ、リポジトリにモジュールが1つだけ含まれている場合、インポートされたgo.modはモジュールを1つのバージョンでのみ要求できます。go list -m allを実行してビルドリストのすべてのバージョンを確認し、go mod tidyを実行して不足している要件を追加し、不要な要件を削除することをお勧めします。

go mod tidy

使用方法

go mod tidy [-e] [-v] [-go=version] [-compat=version]

go mod tidyは、go.modファイルがモジュールのソースコードと一致することを確認します。現在のモジュールのパッケージと依存関係をビルドするために必要なモジュール要件を追加し、関連するパッケージを提供しないモジュールへの要件を削除します。また、go.sumに不足しているエントリを追加し、不要なエントリを削除します。

-eフラグ(Go 1.16で追加)を使用すると、パッケージの読み込み中に発生したエラーにもかかわらず、go mod tidyが続行しようとします。

-vフラグを使用すると、go mod tidyは削除されたモジュールに関する情報を標準エラーに出力します。

go mod tidyは、メインモジュール内のすべてのパッケージとそのパッケージが再帰的にインポートするすべてのパッケージを読み込むことによって機能します。これには、テストによってインポートされたパッケージ(他のモジュール内のテストを含む)も含まれます。go mod tidyは、すべてのビルドタグが有効になっているかのように動作するため、プラットフォーム固有のソースファイルやカスタムビルドタグを必要とするファイルも考慮します(通常はこれらのソースファイルがビルドされない場合でも)。ただし、例外が1つあります。ignoreビルドタグは無効になっているため、ビルド制約// +build ignoreを持つファイルは考慮されません。go mod tidyは、他のパッケージによって明示的にインポートされていない限り、testdataという名前のディレクトリ内にあるパッケージ、または名前が.または_で始まるパッケージをメインモジュールで考慮しません。

go mod tidyがこのパッケージのセットを読み込んだ後、1つ以上のパッケージを提供する各モジュールに、メインモジュールのgo.modファイルにrequireディレクティブがあることを確認します(メインモジュールがgo 1.16以下である場合)または、別の必要なモジュールによって必要とされます。go mod tidyは、不足している各モジュールの最新バージョンへの要件を追加します(latestバージョンの定義については、バージョン照会を参照してください)。go mod tidyは、上記で説明したセットにパッケージを提供しないモジュールのrequireディレクティブを削除します。

go mod tidyは、requireディレクティブの// indirectコメントを追加または削除する場合もあります。// indirectコメントは、メインモジュールのpackageによってインポートされていないパッケージを提供するモジュールを示します。(// indirect依存関係とコメントが追加されるタイミングの詳細については、requireディレクティブを参照してください。)

-goフラグが設定されている場合、go mod tidygoディレクティブを指定されたバージョンに更新し、そのバージョンに従ってモジュールグラフのプルーニング遅延モジュール読み込みを有効または無効にし(必要に応じて間接的な要件を追加または削除します)。

デフォルトでは、go mod tidyは、モジュールグラフがgoディレクティブに示されているバージョンに先行するGoバージョンによってロードされた場合、モジュールの選択されたバージョンが変更されないことを確認します。互換性のためにチェックされるバージョンは、-compatフラグを使用して明示的に指定することもできます。

go mod vendor

使用方法

go mod vendor [-e] [-v] [-o]

go mod vendorコマンドは、メインモジュールのルートディレクトリにvendorという名前のディレクトリを作成します。このディレクトリには、メインモジュールのpackageのビルドとテストをサポートするために必要なすべてのパッケージのコピーが含まれています。メインモジュール外のpackageのテストによってのみインポートされるpackageは含まれません。go mod tidyや他のモジュールコマンドと同様に、ignoreを除くビルド制約は、vendorディレクトリを作成する際には考慮されません。

ベンダー機能が有効になっている場合、goコマンドは、モジュールキャッシュにモジュールをソースからダウンロードしてダウンロードされたコピーのパッケージを使用する代わりに、vendorディレクトリからパッケージを読み込みます。詳細については、ベンダー機能を参照してください。

go mod vendorは、ベンダーされたパッケージと、それらがコピーされたモジュールバージョンの一覧を含むvendor/modules.txtファイルも作成します。ベンダー機能が有効になっている場合、このマニフェストは、go list -mおよびgo version -mによって報告されるモジュールバージョンの情報ソースとして使用されます。goコマンドがvendor/modules.txtを読み取ると、モジュールバージョンがgo.modと一致していることを確認します。vendor/modules.txtが生成されてからgo.modが変更された場合、go mod vendorを再度実行する必要があります。

go mod vendorは、存在するvendorディレクトリを削除してから再構築することに注意してください。ベンダーされたpackageにはローカル変更を加えてはいけません。goコマンドは、vendorディレクトリ内のpackageが変更されていないことを確認しませんが、go mod vendorを実行して変更が加えられていないことを確認することで、vendorディレクトリの整合性を検証できます。

-eフラグ(Go 1.16で追加)を使用すると、パッケージの読み込み中に発生したエラーにもかかわらず、go mod vendorが続行しようとします。

-vフラグを使用すると、go mod vendorはベンダーされたモジュールとパッケージの名前を標準エラーに出力します。

-oフラグ(Go 1.18で追加)を使用すると、go mod vendorは、vendorの代わりに指定されたディレクトリにベンダーツリーを出力します。引数は、絶対パスまたはモジュールルートに対する相対パスのいずれかになります。

go mod verify

使用方法

go mod verify

go mod verifyは、モジュールキャッシュに格納されているメインモジュールの依存関係がダウンロード以降変更されていないことを確認します。このチェックを実行するために、go mod verifyはダウンロードされた各モジュールの.zipファイルと抽出されたディレクトリをハッシュ化し、それらのハッシュをモジュールが最初にダウンロードされたときに記録されたハッシュと比較します。go mod verifyは、ビルドリストgo list -m allで出力できます)の各モジュールをチェックします。

すべてのモジュールが変更されていない場合、go mod verifyは「すべてのモジュールが検証されました」と出力します。そうでない場合は、変更されたモジュールを報告し、ゼロ以外のステータスで終了します。

すべてのモジュール認識コマンドは、メインモジュールのgo.sumファイルのハッシュが、モジュールキャッシュにダウンロードされたモジュールに対して記録されたハッシュと一致することを確認することに注意してください。ハッシュがgo.sumにない場合(たとえば、モジュールが初めて使用されるため)、goコマンドはチェックサムデータベースを使用してそのハッシュを検証します(モジュールパスがGOPRIVATEまたはGONOSUMDBと一致する場合を除く)。詳細については、モジュールの認証を参照してください。

対照的に、go mod verifyは、モジュールの.zipファイルとその抽出されたディレクトリが、最初にダウンロードされたときにモジュールキャッシュに記録されたハッシュと一致するハッシュを持っていることを確認します。これは、モジュールがダウンロードおよび検証された後にモジュールキャッシュ内のファイルの変更を検出するために役立ちます。go mod verifyは、キャッシュにないモジュールのコンテンツをダウンロードせず、モジュールコンテンツの検証にgo.sumファイルを使用しません。ただし、go mod verify最小バージョン選択を実行するためにgo.modファイルをダウンロードする場合があります。go.sumを使用してこれらのファイルを検証し、不足しているハッシュのgo.sumエントリを追加する場合があります。

go mod why

使用方法

go mod why [-m] [-vendor] packages...

go mod whyは、メインモジュールからリストされたパッケージまでのインポートグラフ内の最短パスを表示します。

出力は、空白行で区切られた、コマンドラインで指定された各パッケージまたはモジュールに対するスタンザのシーケンスです。各スタンザは、ターゲットパッケージまたはモジュールを示す#で始まるコメント行で始まります。後続の行には、インポートグラフを通るパスが1パッケージずつ表示されます。パッケージまたはモジュールがメインモジュールから参照されていない場合、スタンザには、その事実を示す単一の括弧付きの注記が表示されます。

例:

$ go mod why golang.org/x/text/language golang.org/x/text/encoding
# golang.org/x/text/language
rsc.io/quote
rsc.io/sampler
golang.org/x/text/language

# golang.org/x/text/encoding
(main module does not need package golang.org/x/text/encoding)

-mフラグを使用すると、go mod whyは引数をモジュールのリストとして扱います。go mod whyは、各モジュールの任意のパッケージへのパスを出力します。-mが使用されている場合でも、go mod whygo mod graphによって出力されるモジュールグラフではなく、パッケージグラフを照会することに注意してください。

-vendorフラグを使用すると、go mod whyはメインモジュール外のpackageのテストのインポートを無視します(go mod vendorと同様です)。デフォルトでは、go mod whyallパターンと一致するpackageのグラフを考慮します。このフラグは、go 1.16以降を宣言するモジュール(go.modgoディレクティブを使用)ではGo 1.16以降では効果がありません。これは、allの意味がgo mod vendorによって一致するパッケージのセットと一致するように変更されたためです。

go version -m

使用方法

go version [-m] [-v] [file ...]

# Print Go version used to build go.
$ go version

# Print Go version used to build a specific executable.
$ go version ~/go/bin/gopls

# Print Go version and module versions used to build a specific executable.
$ go version -m ~/go/bin/gopls

# Print Go version and module versions used to build executables in a directory.
$ go version -m ~/go/bin/

go version は、コマンドラインで指定された各実行ファイルのビルドに使用された Go のバージョンを報告します。

コマンドラインでファイルが指定されていない場合、go version は自身のバージョン情報を表示します。

ディレクトリが指定された場合、go version はそのディレクトリを再帰的に走査し、認識された Go バイナリを探してそのバージョンを報告します。デフォルトでは、go version はディレクトリのスキャン中に検出された認識されないファイルは報告しません。-v フラグを指定すると、認識されないファイルも報告されます。

-m フラグを指定すると、go version は、利用可能な場合、各実行ファイルに埋め込まれたモジュールのバージョン情報を表示します。各実行ファイルに対して、go version -m は下記のようなタブ区切りの列を持つ表を出力します。

$ go version -m ~/go/bin/goimports
/home/jrgopher/go/bin/goimports: go1.14.3
        path    golang.org/x/tools/cmd/goimports
        mod     golang.org/x/tools      v0.0.0-20200518203908-8018eb2c26ba      h1:0Lcy64USfQQL6GAJma8BdHCgeofcchQj+Z7j0SXYAzU=
        dep     golang.org/x/mod        v0.2.0          h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
        dep     golang.org/x/xerrors    v0.0.0-20191204190536-9bdfabe68543      h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=

表の形式は将来変更される可能性があります。同じ情報は、runtime/debug.ReadBuildInfo から取得できます。

表の各行の意味は、最初の列の単語によって決まります。

go clean -modcache

使用方法

go clean [-modcache]

-modcacheフラグは、go clean により、バージョン管理された依存関係の展開されたソースコードを含む、モジュールキャッシュ全体を削除させます。

これは通常、モジュールキャッシュを削除する最適な方法です。デフォルトでは、モジュールキャッシュ内のほとんどのファイルとディレクトリは、テストやエディタが認証された後に意図せずファイルを変更することを防ぐために、読み取り専用になっています。残念ながら、これにより、親ディレクトリを書き込み可能にする前にファイルが削除できないため、rm -rなどのコマンドが失敗します。

-modcacherwフラグ(go buildおよびその他のモジュール認識コマンドで受け入れられます)は、モジュールキャッシュ内の新しいディレクトリを書き込み可能にします。すべてのモジュール認識コマンドに-modcacherwを渡すには、GOFLAGS変数に追加します。GOFLAGSは、環境変数またはgo env -wで設定できます。例えば、下記のコマンドはそれを永続的に設定します。

go env -w GOFLAGS=-modcacherw

-modcacherwは注意して使用する必要があります。開発者は、モジュールキャッシュ内のファイルを変更しないように注意する必要があります。go mod verifyを使用して、キャッシュ内のファイルがメインモジュールのgo.sumファイルのハッシュと一致することを確認できます。

バージョン照会

いくつかのコマンドでは、コマンドラインのモジュールまたはパッケージパスの後に続く@文字の後に表示される、バージョン照会を使用してモジュールのバージョンを指定できます。

go get example.com/m@latest
go mod download example.com/m@master
go list -m -json example.com/m@e3702bed2

バージョン照会は、次のいずれかになります。

特定の名前付きバージョンまたはリビジョンに対する照会を除き、すべての照会はgo list -m -versionsgo list -mを参照)によって報告された利用可能なバージョンを考慮します。このリストには、擬似バージョンではなく、タグ付きバージョンのみが含まれています。メインモジュールのgo.modファイルexcludeディレクティブによって許可されていないモジュールバージョンは考慮されません。latestバージョンの同じモジュールからのgo.modファイルのretractディレクティブによって網羅されているバージョンも、go list -m-retractedフラグが使用されている場合、およびretractディレクティブのロード時を除いて無視されます。

リリースバージョンはプレリリースバージョンよりも優先されます。たとえば、バージョンv1.2.2v1.2.3-preが利用可能な場合、latest照会はv1.2.3-preの方が高いにもかかわらず、v1.2.2を選択します。<v1.2.4照会も、v1.2.3-preの方がv1.2.4に近いにもかかわらず、v1.2.2を選択します。リリースバージョンまたはプレリリースバージョンが利用できない場合、latestupgrade、およびpatch照会は、リポジトリのデフォルトブランチの先端にあるコミットの擬似バージョンを選択します。他の照会はエラーを報告します。

モジュール外のモジュールコマンド

モジュール認識Goコマンドは通常、作業ディレクトリまたは親ディレクトリにあるgo.modファイルによって定義されたメインモジュールのコンテキストで実行されます。一部のコマンドはgo.modファイルなしでモジュール認識モードで実行できますが、ほとんどのコマンドはgo.modファイルが存在しない場合、動作が異なったり、エラーを報告したりします。

モジュール認識コマンドを参照して、モジュール認識モードの有効化と無効化に関する情報を確認してください。

コマンド 動作
go build
go doc
go fix
go fmt
go generate
go install
go list
go run
go test
go vet
標準ライブラリのパッケージと、コマンドラインで.goファイルとして指定されたパッケージのみをロード、インポート、およびビルドできます。他のモジュールからのパッケージは、モジュールの要件を記録して決定的なビルドを保証する場所がないため、ビルドできません。
go get パッケージと実行ファイルは通常どおりビルドしてインストールできます。go getgo.modファイルなしで実行されるとメインモジュールが存在しないため、replaceおよびexcludeディレクティブは適用されないことに注意してください。
go list -m -versionsフラグが使用されている場合を除き、ほとんどの引数には明示的なバージョン照会が必要です。
go mod download ほとんどの引数には明示的なバージョン照会が必要です。
go mod edit 明示的なファイル引数が必要です。
go mod graph
go mod tidy
go mod vendor
go mod verify
go mod why
これらのコマンドにはgo.modファイルが必要であり、存在しない場合はエラーを報告します。

go work init

使用方法

go work init [moddirs]

init は、現在のディレクトリに新しい go.work ファイルを初期化して書き込み、現在のディレクトリに新しいワークスペースを作成します。

go work init は、ワークスペースモジュールのパスを引数としてオプションで受け入れます。引数を省略した場合、モジュールのない空のワークスペースが作成されます。

各引数パスは、go.work ファイルの use ディレクティブに追加されます。現在の go バージョンも go.work ファイルにリストされます。

go work edit

使用方法

go work edit [editing flags] [go.work]

go work editコマンドは、主にツールやスクリプトで使用するための、go.workを編集するためのコマンドラインインターフェースを提供します。go.workのみを読み込み、関係するモジュールに関する情報は参照しません。ファイルが指定されていない場合、Edit は現在のディレクトリとその親ディレクトリでgo.workファイルを探します。

編集フラグは、一連の編集操作を指定します。

編集フラグは複数回繰り返すことができます。変更は指定された順序で適用されます。

go work editには、出力を制御する追加のフラグがあります。

type Module struct {
    Path    string
    Version string
}

type GoWork struct {
    Go        string
    Directory []Directory
    Replace   []Replace
}

type Use struct {
    Path       string
    ModulePath string
}

type Replace struct {
    Old Module
    New Module
}

go work use

使用方法

go work use [-r] [moddirs]

go work useコマンドは、ディレクトリを(オプションで再帰的に)go.workファイルに追加するためのコマンドラインインターフェースを提供します。

コマンドラインにリストされている各引数ディレクトリに対して、go.workファイルにuseディレクティブが追加され、ディスク上に存在する場合はgo.workファイルに追加され、ディスク上に存在しない場合はgo.workファイルから削除されます。

-rフラグは、引数ディレクトリ内でモジュールを再帰的に検索し、useコマンドは各ディレクトリが引数として指定されているかのように動作します。

go work sync

使用方法

go work sync

go work syncコマンドは、ワークスペースのビルドリストをワークスペースのモジュールに同期します。

ワークスペースのビルドリストは、ワークスペースでビルドを実行するために使用されるすべての(推移的な)依存モジュールのバージョンのセットです。go work syncは、最小バージョン選択(MVS)アルゴリズムを使用してそのビルドリストを生成し、それらのバージョンをワークスペース(useディレクティブ付き)で指定された各モジュールに同期します。

ワークスペースのビルドリストが計算されると、ワークスペース内の各モジュールのgo.modファイルが書き換えられ、そのモジュールに関連する依存関係がワークスペースのビルドリストに一致するようにアップグレードされます。最小バージョン選択により、ビルドリストの各モジュールのバージョンは、常に各ワークスペースモジュール内のバージョンと同じかそれ以上であることが保証されます。

モジュールプロキシ

GOPROXYプロトコル

モジュールプロキシは、下記に指定されたパスに対するGETリクエストに応答できるHTTPサーバーです。リクエストにはクエリパラメータがなく、特定のヘッダーも必要ありません。そのため、固定ファイルシステム(file:// URLを含む)から提供するサイトでもモジュールプロキシになることができます。

成功したHTTPレスポンスのステータスコードは200(OK)でなければなりません。リダイレクト(3xx)は追従されます。ステータスコード4xxと5xxのレスポンスはエラーとして扱われます。エラーコード404(Not Found)と410(Gone)は、要求されたモジュールまたはバージョンがプロキシでは利用できないことを示しますが、他の場所で見つかる可能性があります。エラーレスポンスのコンテンツタイプはtext/plainで、charsetutf-8またはus-asciiのいずれかである必要があります。

goコマンドは、プロキシまたはソース管理サーバーに接続するように、プロキシURLのリストを受け入れるGOPROXY環境変数を使用して設定できます。環境変数の詳細については、リストにキーワードdirectまたはoffを含めることができます。リストの要素はコンマ(,)またはパイプ(|)で区切ることができ、これによりエラーのフォールバック動作が決まります。URLの後にコンマが続く場合、goコマンドは、404(Not Found)または410(Gone)レスポンスの後でのみ、後のソースにフォールバックします。URLの後にパイプが続く場合、goコマンドは、タイムアウトなどの非HTTPエラーを含むあらゆるエラーの後で、後のソースにフォールバックします。このエラー処理動作により、プロキシは未知のモジュールのゲートキーパーとして機能できます。たとえば、プロキシは、承認されていないリストにないモジュールに対してエラー403(Forbidden)で応答できます(プライベートモジュールを提供するプライベートプロキシを参照)。

下の表は、モジュールプロキシが応答しなければならないクエリを指定しています。各パスについて、$baseはプロキシURLのパス部分、$moduleはモジュールパス、$versionはバージョンです。たとえば、プロキシURLがhttps://example.com/modで、クライアントがバージョンv0.3.2のモジュールgolang.org/x/textgo.modファイルを要求している場合、クライアントはhttps://example.com/mod/golang.org/x/text/@v/v0.3.2.modに対するGETリクエストを送信します。

大文字と小文字を区別しないファイルシステムから提供する場合のあいまいさを避けるため、$module要素と$version要素は大文字の文字を感嘆符とそれに対応する小文字の文字に置き換えることで、ケースエンコードされます。これにより、モジュールexample.com/Mexample.com/mの両方をディスクに保存できます(前者はexample.com/!mとしてエンコードされるため)。

パス 説明
$base/$module/@v/list 指定されたモジュールの既知のバージョンの一覧をプレーンテキストで、1行に1つずつ返します。このリストには疑似バージョンを含めるべきではありません。
$base/$module/@v/$version.info

モジュールの特定のバージョンのJSON形式のメタデータを返します。レスポンスは、以下のGoデータ構造に対応するJSONオブジェクトでなければなりません。

type Info struct {
    Version string    // version string
    Time    time.Time // commit time
}

Versionフィールドは必須であり、有効な標準バージョンを含んでいなければなりません(バージョンを参照)。リクエストパスの$versionは、同じバージョンである必要はなく、有効なバージョンである必要もありません。このエンドポイントは、ブランチ名またはリビジョン識別子のバージョンを見つけるために使用できます。ただし、$version$moduleと互換性のあるメジャーバージョンを持つ標準バージョンである場合、成功したレスポンスのVersionフィールドは同じでなければなりません。

Timeフィールドはオプションです。存在する場合は、RFC 3339形式の文字列でなければなりません。これは、バージョンが作成された時刻を示します。

将来的にさらにフィールドが追加される可能性があるため、他の名前は予約されています。

$base/$module/@v/$version.mod モジュールの特定のバージョンのgo.modファイルを返します。モジュールが要求されたバージョンにgo.modファイルを持っていない場合、要求されたモジュールパスを持つmoduleステートメントのみを含むファイルが返される必要があります。それ以外の場合は、元の変更されていないgo.modファイルが返されます。
$base/$module/@v/$version.zip モジュールの特定のバージョンの内容を含むzipファイルを返します。このzipファイルのフォーマット方法については、モジュールzipファイルを参照してください。
$base/$module/@latest $base/$module/@v/$version.infoと同じ形式で、モジュールの最新の既知のバージョンのJSON形式のメタデータを返します。最新のバージョンは、$base/$module/@v/listが空の場合、またはリストされたバージョンが適切でない場合に、goコマンドが使用する必要があるモジュールのバージョンである必要があります。このエンドポイントはオプションであり、モジュールプロキシはこれを実装する必要はありません。

モジュールの最新バージョンを解決する場合、goコマンドはまず$base/$module/@v/listを要求し、適切なバージョンが見つからない場合は、$base/$module/@latestを要求します。goコマンドは、意味的に最も高いリリースバージョン、意味的に最も高いプリリリースバージョン、そして時系列的に最も新しい疑似バージョンの順に優先します。Go 1.12以前では、goコマンドは$base/$module/@v/list内の疑似バージョンをプリリリースバージョンと見なしていましたが、Go 1.13以降はそうではなくなりました。

モジュールプロキシは、$base/$module/$version.modおよび$base/$module/$version.zipクエリに対する成功したレスポンスに対して、常に同じコンテンツを提供する必要があります。このコンテンツは、go.sumファイルと、デフォルトではチェックサムデータベースを使用して暗号化的に認証されます。

goコマンドは、モジュールプロキシからダウンロードしたほとんどのコンテンツを、$GOPATH/pkg/mod/cache/downloadにあるモジュールキャッシュにキャッシュします。バージョン管理システムから直接ダウンロードする場合でも、goコマンドは明示的なinfomodzipファイルを合成し、プロキシから直接ダウンロードした場合と同様にこのディレクトリに保存します。キャッシュのレイアウトはプロキシURL空間と同じなので、$GOPATH/pkg/mod/cache/downloadhttps://example.com/proxyで提供する(またはそこにコピーする)ことで、ユーザーはGOPROXYhttps://example.com/proxyに設定することで、キャッシュされたモジュールバージョンにアクセスできます。

プロキシとの通信

goコマンドは、モジュールプロキシからモジュールソースコードとメタデータをダウンロードできます。環境変数GOPROXYを使用して、goコマンドが接続できるプロキシと、バージョン管理システムと直接通信できるかどうかを設定できます。ダウンロードされたモジュールデータはモジュールキャッシュに保存されます。goコマンドは、キャッシュにない情報が必要な場合にのみプロキシに接続します。

GOPROXYプロトコルセクションでは、GOPROXYサーバーに送信できるリクエストについて説明しています。しかし、goコマンドがいつこれらのリクエストを行うのかを理解することも役立ちます。たとえば、go buildは次の手順に従います。

goコマンドがビルドリストを計算すると、モジュールグラフ内の各モジュールのgo.modファイルを読み込みます。go.modファイルがキャッシュにない場合、goコマンドは$module/@v/$version.modリクエスト($moduleはモジュールパス、$versionはバージョン)を使用してプロキシからダウンロードします。これらのリクエストは、curlなどのツールでテストできます。たとえば、以下のコマンドは、バージョンv0.2.0golang.org/x/modgo.modファイルをダウンロードします。

$ curl https://proxy.golang.org/golang.org/x/mod/@v/v0.2.0.mod
module golang.org/x/mod

go 1.12

require (
    golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
    golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e
    golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898
)

パッケージをロードするために、goコマンドは、それを提供するモジュールのソースコードを必要とします。モジュールソースコードは.zipファイルで配布され、モジュールキャッシュに展開されます。モジュールの.zipがキャッシュにない場合、goコマンドは$module/@v/$version.zipリクエストを使用してダウンロードします。

$ curl -O https://proxy.golang.org/golang.org/x/mod/@v/v0.2.0.zip
$ unzip -l v0.2.0.zip | head
Archive:  v0.2.0.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
     1479  00-00-1980 00:00   golang.org/x/mod@v0.2.0/LICENSE
     1303  00-00-1980 00:00   golang.org/x/mod@v0.2.0/PATENTS
      559  00-00-1980 00:00   golang.org/x/mod@v0.2.0/README
       21  00-00-1980 00:00   golang.org/x/mod@v0.2.0/codereview.cfg
      214  00-00-1980 00:00   golang.org/x/mod@v0.2.0/go.mod
     1476  00-00-1980 00:00   golang.org/x/mod@v0.2.0/go.sum
     5224  00-00-1980 00:00   golang.org/x/mod@v0.2.0/gosumcheck/main.go

go.modファイルは通常.zipファイルに含まれていますが、.modリクエストと.zipリクエストは別々であることに注意してください。goコマンドは、多くの異なるモジュールのgo.modファイルをダウンロードする必要がある場合があり、.modファイルは.zipファイルよりもはるかに小さいです。さらに、Goプロジェクトにgo.modファイルがない場合、プロキシはmoduleディレクティブのみを含む合成go.modファイルを返します。合成go.modファイルは、バージョン管理システムからダウンロードするときにgoコマンドによって生成されます。

goコマンドがビルドリストのどのモジュールからも提供されていないパッケージをロードする必要がある場合、それを提供する新しいモジュールを見つけようとします。パッケージをモジュールに解決するセクションでは、このプロセスについて説明しています。要約すると、goコマンドは、パッケージを含みうる可能性のある各モジュールパスの最新バージョンの情報を要求します。たとえば、パッケージgolang.org/x/net/htmlの場合、goコマンドはモジュールgolang.org/x/net/htmlgolang.org/x/netgolang.org/x/golang.orgの最新バージョンを見つけようとします。実際にはgolang.org/x/netのみが存在し、そのパッケージを提供するため、goコマンドはそのモジュールの最新バージョンを使用します。複数のモジュールがパッケージを提供する場合、goコマンドはパスが最も長いモジュールを使用します。

goコマンドがモジュールの最新バージョンを要求する場合、最初に$module/@v/listのリクエストを送信します。リストが空の場合、または返されたバージョンのいずれも使用できない場合、$module/@latestのリクエストを送信します。バージョンが選択されると、goコマンドはメタデータの$module/@v/$version.infoリクエストを送信します。その後、$module/@v/$version.modおよび$module/@v/$version.zipリクエストを送信して、go.modファイルとソースコードをロードする場合があります。

$ curl https://proxy.golang.org/golang.org/x/mod/@v/list
v0.1.0
v0.2.0

$ curl https://proxy.golang.org/golang.org/x/mod/@v/v0.2.0.info
{"Version":"v0.2.0","Time":"2020-01-02T17:33:45Z"}

.modまたは.zipファイルをダウンロードした後、goコマンドは暗号化ハッシュを計算し、それがメインモジュールのgo.sumファイルのハッシュと一致するかどうかを確認します。ハッシュがgo.sumに存在しない場合、デフォルトでは、goコマンドはチェックサムデータベースから取得します。計算されたハッシュが一致しない場合、goコマンドはセキュリティエラーを報告し、ファイルをモジュールキャッシュにインストールしません。GOPRIVATEおよびGONOSUMDB環境変数を使用して、特定のモジュールのチェックサムデータベースへのリクエストを無効にすることができます。GOSUMDB環境変数をoffに設定して、チェックサムデータベースへのリクエストを完全に無効にすることもできます。モジュールの認証の詳細を参照してください。.infoリクエストで返されるバージョンリストとバージョンメタデータは認証されず、時間の経過とともに変更される可能性があることに注意してください。

プロキシからモジュールを直接提供する

ほとんどのモジュールは、バージョン管理リポジトリから開発および提供されます。ダイレクトモードでは、goコマンドはバージョン管理ツールを使用してそのようなモジュールをダウンロードします(バージョン管理システムを参照)。モジュールプロキシからモジュールを直接提供することも可能です。これは、バージョン管理サーバーを公開せずにモジュールを提供したい組織や、goコマンドがサポートしていないバージョン管理ツールを使用している組織にとって役立ちます。

goコマンドがダイレクトモードでモジュールをダウンロードする場合、まずモジュールパスに基づいてHTTP GETリクエストでモジュールサーバーのURLを検索します。HTMLレスポンス内で、名前が<meta>で、`go-import`であるタグを探します。このタグの内容には、リポジトリルートパス、バージョン管理システム、およびURLがスペースで区切られて含まれている必要があります。詳細はモジュールパスのリポジトリの検索を参照してください。

バージョン管理システムがmodの場合、goコマンドはGOPROXYプロトコルを使用して指定されたURLからモジュールをダウンロードします。

たとえば、goコマンドがバージョンv1.0.0でモジュールexample.com/gopherをダウンロードしようとしているとします。この場合、https://example.com/gopher?go-get=1にリクエストを送信します。サーバーは、次のタグを含むHTMLドキュメントで応答します。

<meta name="go-import" content="example.com/gopher mod https://modproxy.example.com">

このレスポンスに基づいて、goコマンドはhttps://modproxy.example.com/example.com/gopher/@v/v1.0.0.infov1.0.0.modv1.0.0.zipのリクエストを送信してモジュールをダウンロードします。

プロキシから直接提供されるモジュールは、GOPATHモードでgo getを使用してダウンロードできないことに注意してください。

バージョン管理システム

goコマンドは、バージョン管理リポジトリからモジュールのソースコードとメタデータを直接ダウンロードする場合があります。プロキシからモジュールをダウンロードする方が通常は高速ですが、プロキシが使用できない場合、またはモジュールのリポジトリがプロキシからアクセスできない場合(プライベートリポジトリではよくあること)、リポジトリに直接接続する必要があります。Git、Subversion、Mercurial、Bazaar、Fossilがサポートされています。goコマンドで使用するには、バージョン管理ツールをPATH内のディレクトリにインストールする必要があります。

プロキシではなくソースリポジトリから特定のモジュールをダウンロードするには、GOPRIVATEまたはGONOPROXY環境変数を設定します。すべてのモジュールをソースリポジトリから直接ダウンロードするようにgoコマンドを構成するには、GOPROXYdirectに設定します。詳細については、環境変数を参照してください。

モジュールパスのリポジトリの検索

goコマンドがdirectモードでモジュールをダウンロードする場合、最初にモジュールを含むリポジトリの場所を特定します。

モジュールパスがパスコンポーネントの最後にVCS修飾子(.bzr.fossil.git.hg.svnのいずれか)を持つ場合、goコマンドは、そのパス修飾子までの部分をリポジトリURLとして使用します。たとえば、モジュールexample.com/foo.git/barの場合、goコマンドはexample.com/foo.gitのリポジトリをgitを使用してダウンロードし、barサブディレクトリにモジュールがあると想定します。goコマンドは、バージョン管理ツールのサポートするプロトコルに基づいて使用するプロトコルを推測します。

モジュールパスに修飾子がない場合、goコマンドは、?go-get=1クエリ文字列を使用してモジュールパスから導出されたURLにHTTP GETリクエストを送信します。たとえば、モジュールgolang.org/x/modの場合、goコマンドは次のリクエストを送信する場合があります。

https://go.dokyumento.jp/x/mod?go-get=1 (preferred)
https://go.dokyumento.jp/x/mod?go-get=1  (fallback, only with GOINSECURE)

goコマンドはリダイレクトに従いますが、それ以外のレスポンスステータスコードは無視するため、サーバーは404またはその他のエラーステータスで応答する場合があります。GOINSECURE環境変数を設定して、特定のモジュールに対して暗号化されていないHTTPへのフォールバックとリダイレクトを許可できます。

サーバーは、ドキュメントの<head>内に<meta>タグを含むHTMLドキュメントで応答する必要があります。goコマンドの制限されたパーサーを混乱させないために、<meta>タグはドキュメントの先頭に表示する必要があります。特に、生のJavaScriptやCSSの前に表示する必要があります。<meta>タグは次の形式である必要があります。

<meta name="go-import" content="root-path vcs repo-url">

root-pathはリポジトリルートパスであり、リポジトリのルートディレクトリに対応するモジュールパスの部分です。リクエストされたモジュールパスのプレフィックスまたは完全一致である必要があります。完全一致でない場合、プレフィックスに対して別のリクエストが行われ、<meta>タグの一致が検証されます。

vcsはバージョン管理システムです。これは、以下の表にリストされているツールのいずれか、またはキーワードmodである必要があります。modは、GOPROXYプロトコルを使用して指定されたURLからモジュールをダウンロードするようにgoコマンドに指示します。詳細はプロキシからモジュールを直接提供するを参照してください。

repo-urlはリポジトリのURLです。URLにスキームが含まれていない場合(モジュールパスにVCS修飾子があるため、または<meta>タグにスキームがないため)、goコマンドはバージョン管理システムでサポートされている各プロトコルを試行します。たとえば、Gitの場合、goコマンドはhttps://を試してからgit+ssh://を試します。安全でないプロトコル(http://git://など)は、モジュールパスがGOINSECURE環境変数によって一致する場合にのみ使用できます。

名前 コマンド GOVCSデフォルト セキュアなスキーム
Bazaar bzr プライベートのみ httpsbzr+ssh
Fossil fossil プライベートのみ https
Git git パブリックとプライベート httpsgit+sshssh
Mercurial hg パブリックとプライベート httpsssh
Subversion svn プライベートのみ httpssvn+ssh

例として、もう一度golang.org/x/modを考えてみましょう。goコマンドはhttps://go.dokyumento.jp/x/mod?go-get=1にリクエストを送信します。サーバーは、次のタグを含むHTMLドキュメントで応答します。

<meta name="go-import" content="golang.org/x/mod git https://go.googlesource.com/mod">

このレスポンスから、goコマンドはリモートURLhttps://go.googlesource.com/modにあるGitリポジトリを使用します。

GitHubやその他の一般的なホスティングサービスは、すべてのリポジトリの?go-get=1クエリに応答するため、通常、これらのサイトでホストされているモジュールにはサーバー構成は必要ありません。

リポジトリURLが見つかった後、goコマンドはリポジトリをモジュールキャッシュにクローンします。一般的に、goコマンドはリポジトリから不要なデータのフェッチを避けるように試みます。ただし、使用される実際のコマンドはバージョン管理システムによって異なり、時間の経過とともに変更される可能性があります。Gitの場合、goコマンドはコミットをダウンロードせずに利用可能なほとんどのバージョンをリストできます。通常は祖先コミットをダウンロードせずにコミットをフェッチしますが、場合によっては必要になることもあります。

バージョンとコミットのマッピング

goコマンドは、v1.2.3v2.4.0-betav3.0.0+incompatibleなど、特定の標準バージョンでリポジトリ内のモジュールをチェックアウトする場合があります。各モジュールバージョンには、どのリビジョンをチェックアウトするべきかを示すリポジトリ内にセマンティックバージョンのタグが必要です。

モジュールがリポジトリのルートディレクトリまたはルートディレクトリのメジャーバージョンサブディレクトリで定義されている場合、各バージョンのタグ名は対応するバージョンと同じになります。たとえば、モジュールgolang.org/x/textはリポジトリのルートディレクトリで定義されているため、バージョンv0.3.2にはそのリポジトリにv0.3.2というタグがあります。これはほとんどのモジュールに当てはまります。

モジュールがリポジトリ内のサブディレクトリで定義されている場合、つまり、モジュールパスのモジュールサブディレクトリ部分が空でない場合、各タグ名にはモジュールサブディレクトリをプレフィックスとして付けて、スラッシュを付ける必要があります。たとえば、モジュールgolang.org/x/tools/goplsは、ルートパスgolang.org/x/toolsのリポジトリのgoplsサブディレクトリで定義されています。そのモジュールのバージョンv0.4.0には、そのリポジトリにgopls/v0.4.0という名前のタグが必要です。

セマンティックバージョンのタグのメジャーバージョン番号は、モジュールパスのメジャーバージョンのサフィックス(存在する場合)と一致する必要があります。たとえば、タグv1.0.0はモジュールexample.com/modに属する可能性がありますが、タグv2.0.0を持つexample.com/mod/v2には属しません。

go.modファイルが存在せず、モジュールがリポジトリのルートディレクトリにある場合、メジャーバージョンv2以上のタグは、メジャーバージョンのサフィックスがないモジュールに属する可能性があります。この種のバージョンは、サフィックス+incompatibleで示されます。バージョンのタグ自体にはサフィックスを含めるべきではありません。非モジュールリポジトリとの互換性を参照してください。

タグが作成された後、削除したり、別のリビジョンに変更したりすることはできません。バージョンは認証され、安全で再現性のあるビルドが保証されます。タグが変更された場合、クライアントはダウンロード時にセキュリティエラーが発生する可能性があります。タグが削除された後も、そのコンテンツはモジュールプロキシで使用可能な場合があります。

疑似バージョンとコミットのマッピング

goコマンドは、v1.3.2-0.20191109021931-daa7c04131f5などの疑似バージョンとしてエンコードされた特定のリビジョンでリポジトリ内のモジュールをチェックアウトする場合があります。

疑似バージョンの最後の12文字(上記の例ではdaa7c04131f5)は、チェックアウトするリポジトリのリビジョンを示しています。その意味はバージョン管理システムによって異なります。GitとMercurialでは、これはコミットハッシュのプレフィックスです。Subversionでは、これはゼロパディングされたリビジョン番号です。

コミットをチェックアウトする前に、goコマンドはタイムスタンプ(上記では20191109021931)がコミット日と一致することを検証します。また、ベースバージョン(上記の例ではv1.3.1v1.3.2の前バージョン)が、コミットの祖先であるセマンティックバージョンのタグに対応することを検証します。これらのチェックにより、モジュール作成者は、疑似バージョンが他のリリース済みバージョンとどのように比較されるかを完全に制御できます。

詳細については、疑似バージョンを参照してください。

ブランチとコミットのバージョンのマッピング

モジュールは、バージョン照会を使用して、特定のブランチ、タグ、またはリビジョンでチェックアウトできます。

go get example.com/mod@master

goコマンドは、これらの名前を標準バージョンに変換します。これは最小バージョン選択(MVS)で使用できます。MVSは、バージョンを一意にソートできる機能に依存します。ブランチ名とリビジョンは、リポジトリの構造が変更される可能性があるため、時間の経過とともに確実に比較できません。

リビジョンがv1.2.3などの1つ以上のセマンティックバージョンのタグでタグ付けされている場合、最も高い有効なバージョンのタグが使用されます。goコマンドは、ターゲットモジュールに属する可能性のあるセマンティックバージョンのタグのみを考慮します。たとえば、タグv1.5.2は、メジャーバージョンがモジュールパスのサフィックスと一致しないため、example.com/mod/v2には考慮されません。

リビジョンが有効なセマンティックバージョンのタグでタグ付けされていない場合、goコマンドは疑似バージョンを生成します。リビジョンに有効なセマンティックバージョンのタグを持つ祖先がある場合、最も高い祖先のバージョンが疑似バージョンのベースとして使用されます。疑似バージョンを参照してください。

リポジトリ内のモジュールディレクトリ

モジュールのリポジトリが特定のリビジョンでチェックアウトされると、goコマンドはモジュールのgo.modファイル(モジュールのルートディレクトリ)を含むディレクトリの場所を特定する必要があります。

モジュールパスは、リポジトリルートパス(リポジトリのルートディレクトリに対応)、モジュールサブディレクトリ、およびメジャーバージョンサフィックス(v2以降のモジュールのみ)の3つの部分から構成されていることを思い出してください。

ほとんどのモジュールでは、モジュールパスはリポジトリルートパスと等しいため、モジュールのルートディレクトリはリポジトリのルートディレクトリになります。

モジュールは、リポジトリのサブディレクトリで定義されることがあります。これは通常、独立してリリースおよびバージョン管理する必要がある複数のコンポーネントを持つ大規模なリポジトリに対して行われます。このようなモジュールは、リポジトリルートパスの後にモジュールパスの部分が続くサブディレクトリにあることが期待されます。たとえば、モジュールexample.com/monorepo/foo/barがルートパスexample.com/monorepoのリポジトリにあるとします。そのgo.modファイルはfoo/barサブディレクトリに存在する必要があります。

モジュールがメジャーバージョンv2以降でリリースされている場合、そのパスにはメジャーバージョンサフィックスが必要です。メジャーバージョンサフィックスを持つモジュールは、サフィックス付きのサブディレクトリとサフィックスなしのサブディレクトリのいずれかに定義できます。たとえば、上記のモジュールの新しいバージョンがパスexample.com/monorepo/foo/bar/v2でリリースされたとします。そのgo.modファイルはfoo/barまたはfoo/bar/v2のいずれかに存在する可能性があります。

メジャーバージョンサフィックスを持つサブディレクトリは、メジャーバージョンサブディレクトリです。これらは、単一のブランチでモジュールの複数のメジャーバージョンを開発するために使用できます。複数のメジャーバージョンの開発が別々のブランチで行われる場合は、不要になる可能性があります。ただし、メジャーバージョンサブディレクトリには重要な特性があります。GOPATHモードでは、パッケージのインポートパスはGOPATH/srcの下のディレクトリと正確に一致します。goコマンドはGOPATHモードで最小限のモジュール互換性を提供します(非モジュールリポジトリとの互換性を参照)。そのため、GOPATHモードでビルドされたプロジェクトとの互換性のために、メジャーバージョンサブディレクトリが常に必要というわけではありません。ただし、最小限のモジュール互換性をサポートしていない古いツールは問題が発生する可能性があります。

goコマンドがモジュールのルートディレクトリを見つけると、ディレクトリのコンテンツの.zipファイルを作成し、その.zipファイルをモジュールキャッシュに展開します。.zipファイルに含めることができるファイルの詳細については、ファイルパスとサイズに関する制約を参照してください。.zipファイルのコンテンツは、.zipファイルがプロキシからダウンロードされた場合と同じ方法で、モジュールキャッシュへの展開前に認証されます。

モジュールのzipファイルには、vendorディレクトリの内容や入れ子になったモジュール(go.modファイルを含むサブディレクトリ)の内容は含まれません。つまり、モジュールは、そのディレクトリ外または他のモジュールにあるファイルを参照しないように注意する必要があります。たとえば、//go:embedパターンは、入れ子になったモジュール内のファイルと一致してはなりません。この動作は、ファイルがモジュールに含まれるべきでない状況における便利な回避策として機能する場合があります。たとえば、リポジトリにtestdataディレクトリにチェックインされた大きなファイルがある場合、モジュール作成者はtestdataに空のgo.modファイルを追加することで、ユーザーがこれらのファイルをダウンロードする必要がなくなります。もちろん、これにより、依存関係をテストするユーザーの範囲が狭くなる可能性があります。

LICENSEファイルの特別なケース

goコマンドがリポジトリのルートディレクトリにないモジュールの.zipファイルを作成する場合、モジュールにルートディレクトリ(go.modと並んで)にLICENSEという名前のファイルがない場合、goコマンドは同じリビジョンに存在する場合はリポジトリのルートディレクトリからLICENSEという名前のファイルをコピーします。

この特別なケースにより、同じLICENSEファイルをリポジトリ内のすべてのモジュールに適用できます。これは、.txtなどの拡張子なしのLICENSEという名前のファイルのみに適用されます。残念ながら、既存のモジュールの暗号化された合計を壊すことなく拡張することはできません。モジュールの認証を参照してください。 pkg.go.devなどの他のツールやWebサイトは、他の名前のファイルも認識する可能性があります。

また、goコマンドはモジュールの.zipファイルを作成する際にシンボリックリンクを含めません。ファイルパスとサイズに関する制約を参照してください。したがって、リポジトリのルートディレクトリにLICENSEファイルがない場合は、作成者は代わりにサブディレクトリで定義されたモジュールにライセンスファイルのコピーを作成して、これらのファイルがモジュールの.zipファイルに含まれるようにする必要があります。

GOVCSを使用したバージョン管理ツールの制御

gitなどのバージョン管理コマンドを使用してモジュールをダウンロードするgoコマンドの機能は、コードを任意のサーバーからインポートできる分散型パッケージエコシステムにとって重要です。悪意のあるサーバーが呼び出されたバージョン管理コマンドに意図しないコードを実行させる方法を見つけた場合、セキュリティ上の問題にもなります。

機能とセキュリティ上の懸念のバランスを取るために、goコマンドはデフォルトで、パブリックサーバーからのコードのダウンロードにgithgのみを使用します。GOPRIVATE環境変数と一致するパッケージをホスティングするサーバー(プライベートサーバーとして定義)からのコードのダウンロードには、任意の既知のバージョン管理システムを使用します。GitとMercurialのみを許可する理由としては、これら2つのシステムが、信頼できないサーバーのクライアントとして実行される問題に最も多くの注意が払われてきた点が挙げられます。対照的に、Bazaar、Fossil、Subversionは主に信頼できる認証済みの環境で使用されており、攻撃対象領域としてそれほど綿密に調査されていません。

バージョン管理コマンドの制限は、コードをダウンロードするために直接バージョン管理アクセスを使用する場合にのみ適用されます。プロキシからモジュールをダウンロードする場合、goコマンドは代わりにGOPROXYプロトコルを使用し、これは常に許可されます。デフォルトでは、goコマンドはパブリックモジュールにGoモジュールミラー(proxy.golang.org)を使用し、プライベートモジュールの場合、またはミラーがパブリックパッケージを提供することを拒否した場合(通常は法的理由による)にのみ、バージョン管理にフォールバックします。そのため、クライアントは、これらのダウンロードがカスタムサンドボックスを使用してバージョン管理コマンドを実行するセキュリティリスクを引き受けるGoモジュールミラーを使用するため、デフォルトでBazaar、Fossil、またはSubversionリポジトリから提供されるパブリックコードにアクセスできます。

GOVCS変数を使用して、特定のモジュールについて許可されるバージョン管理システムを変更できます。GOVCS変数は、モジュール対応モードとGOPATHモードの両方でパッケージをビルドする場合に適用されます。モジュールを使用する場合、パターンはモジュールパスと一致します。GOPATHを使用する場合、パターンはバージョン管理リポジトリのルートに対応するインポートパスと一致します。

GOVCS変数の一般的な形式は、コンマ区切りのpattern:vcslistルールのリストです。パターンはglobパターンであり、モジュールまたはインポートパスの先頭要素の1つ以上と一致する必要があります。vcslistは、許可されるバージョン管理コマンドのパイプ区切りのリスト、または任意の既知のコマンドの使用を許可するall、または何も許可しないoffです。モジュールがvcslist offのパターンと一致する場合でも、元のサーバーがmodスキームを使用している場合(goコマンドにGOPROXYプロトコルを使用してモジュールをダウンロードするように指示する)は、ダウンロードされる可能性があります。リスト内の最も早い一致パターンが適用され、後のパターンも一致する可能性があっても同様です。

たとえば、以下を考えてみてください。

GOVCS=github.com:git,evil.com:off,*:git|hg

この設定では、github.com/で始まるモジュールまたはインポートパスを持つコードはgitのみを使用できます。evil.comのパスはバージョン管理コマンドを使用できず、その他のすべてのパス(*はすべてに一致します)はgitまたはhgのみを使用できます。

特別なパターンpublicprivateは、パブリックとプライベートのモジュールまたはインポートパスと一致します。パスがGOPRIVATE変数と一致する場合、そのパスはプライベートです。それ以外の場合はパブリックです。

GOVCS変数のルールが特定のモジュールまたはインポートパスと一致しない場合、goコマンドはデフォルトルールを適用します。これは、GOVCS表記ではpublic:git|hg,private:allと要約できます。

任意のパッケージで任意のバージョン管理システムを自由に使用できるようにするには、以下を使用します。

GOVCS=*:all

バージョン管理のすべての使用を無効にするには、以下を使用します。

GOVCS=*:off

go env -wコマンドを使用して、将来のgoコマンドの呼び出しのためにGOVCS変数を設定できます。

GOVCSはGo 1.16で導入されました。それ以前のバージョンのGoでは、任意のモジュールに任意の既知のバージョン管理ツールを使用できます。

モジュールのzipファイル

モジュールバージョンは.zipファイルとして配布されます。goコマンドはモジュールプロキシおよびバージョン管理リポジトリから自動的に作成、ダウンロード、および展開するため、これらのファイルと直接やり取りする必要はほとんどありません。ただし、クロスプラットフォームの互換性の制約を理解する場合や、モジュールプロキシを実装する場合には、これらのファイルについて知っておくと役立ちます。

go mod downloadコマンドは、1つ以上のモジュールのzipファイルをダウンロードし、それらのファイルをモジュールキャッシュに展開します。GOPROXYおよびその他の環境変数に応じて、goコマンドはプロキシからzipファイルをダウンロードするか、ソース管理リポジトリを複製してzipファイルを作成します。-jsonフラグを使用して、ダウンロードしたzipファイルとそのモジュールキャッシュ内の展開済みコンテンツの場所を見つけることができます。

golang.org/x/mod/zipパッケージを使用して、zipファイルの作成、展開、またはコンテンツのプログラムによるチェックを行うことができます。

ファイルパスとサイズに関する制約

モジュールのzipファイルの内容には、いくつかの制限があります。これらの制約により、zipファイルは幅広いプラットフォームで安全かつ一貫して展開できます。

プライベートモジュール

Go モジュールは、パブリックインターネットでは利用できないバージョン管理サーバーやモジュールプロキシで頻繁に開発および配布されます。go コマンドはプライベートソースからモジュールをダウンロードしてビルドできますが、通常はいくつかの設定が必要です。

プライベートモジュールへのアクセスを設定するには、以下の環境変数を使用できます。「環境変数」セクションを参照して詳細を確認してください。「プライバシー」セクションも参照して、パブリックサーバーに送信される情報を制御する方法を確認してください。

これらの変数は、開発環境(たとえば、.profileファイル)で設定するか、go env -wを使用して永続的に設定できます。

このセクションの残りの部分では、プライベートモジュールプロキシとバージョン管理リポジトリへのアクセスを提供するための一般的なパターンについて説明します。

すべてのモジュールを提供するプライベートプロキシ

すべてのモジュール(パブリックとプライベートの両方)を提供する中央のプライベートプロキシサーバーは、管理者にとって最も多くの制御を提供し、個々の開発者にとって最小限の設定しか必要としません。

このようなサーバーを使用するようにgoコマンドを設定するには、以下の環境変数を設定します。https://proxy.corp.example.comをプロキシURLに、corp.example.comをモジュールプレフィックスに置き換えます。

GOPROXY=https://proxy.corp.example.com
GONOSUMDB=corp.example.com

GOPROXY設定は、goコマンドがhttps://proxy.corp.example.comからのみモジュールをダウンロードするように指示します。goコマンドは他のプロキシまたはバージョン管理リポジトリに接続しません。

GONOSUMDB設定は、goコマンドがパブリックチェックサムデータベースを使用して、corp.example.comで始まるパスのモジュールを認証しないように指示します。

この構成で実行されているプロキシは、プライベートバージョン管理サーバーへの読み取りアクセスが必要になる可能性があります。また、パブリックモジュールの新しいバージョンをダウンロードするために、パブリックインターネットへのアクセスも必要になります。

このような方法で使用できるGOPROXYサーバーの既存の実装はいくつかあります。最小限の実装は、モジュールキャッシュディレクトリからファイルを提供し、不足しているモジュールを取得するためにgo mod download(適切な設定で)を使用します。

プライベートモジュールを提供するプライベートプロキシ

プライベートプロキシサーバーは、公開されているモジュールを提供することなく、プライベートモジュールを提供できます。goコマンドは、プライベートサーバーで利用できないモジュールについては、パブリックソースにフォールバックするように設定できます。

この方法で動作するようにgoコマンドを設定するには、以下の環境変数を設定します。https://proxy.corp.example.comをプロキシURLに、corp.example.comをモジュールプレフィックスに置き換えます。

GOPROXY=https://proxy.corp.example.com,https://proxy.golang.org,direct
GONOSUMDB=corp.example.com

GOPROXY設定は、goコマンドが最初にhttps://proxy.corp.example.comからモジュールをダウンロードしようとすると指示します。そのサーバーが404(見つかりません)または410(削除されました)で応答した場合、goコマンドはhttps://proxy.golang.orgにフォールバックし、次にリポジトリへの直接接続にフォールバックします。

GONOSUMDB設定は、goコマンドがパブリックチェックサムデータベースを使用して、パスがcorp.example.comで始まるモジュールを認証しないように指示します。

この構成で使用されるプロキシは、それ自体が提供していなくても、パブリックモジュールへのアクセスを制御できることに注意してください。プロキシが404または410以外のエラーステータスでリクエストに応答した場合、goコマンドはGOPROXYリストの後続のエントリにフォールバックしません。たとえば、プロキシは、不適切なライセンスを持つモジュールまたは既知のセキュリティ上の脆弱性のあるモジュールに対して403(禁止)で応答できます。

プライベートモジュールへの直接アクセス

goコマンドは、パブリックプロキシをバイパスして、バージョン管理サーバーからプライベートモジュールを直接ダウンロードするように設定できます。これは、プライベートプロキシサーバーの実行が不可能な場合に便利です。

この方法で動作するようにgoコマンドを設定するには、GOPRIVATEを設定し、corp.example.comをプライベートモジュールプレフィックスに置き換えます。

GOPRIVATE=corp.example.com

この状況では、GOPROXY変数を変更する必要はありません。デフォルト値はhttps://proxy.golang.org,directで、これはgoコマンドに、最初にhttps://proxy.golang.orgからモジュールをダウンロードしようとさせ、そのプロキシが404(見つかりません)または410(削除されました)で応答した場合に直接接続にフォールバックするように指示します。

GOPRIVATE設定は、goコマンドがcorp.example.comで始まるモジュールについて、プロキシまたはチェックサムデータベースに接続しないように指示します。

内部HTTPサーバーは、モジュールパスをリポジトリURLに解決するために必要となる場合があります。たとえば、goコマンドがモジュールcorp.example.com/modをダウンロードする場合、https://corp.example.com/mod?go-get=1へのGETリクエストを送信し、レスポンスからリポジトリURLを検索します。この要件を回避するには、各プライベートモジュールパスに、リポジトリルートプレフィックスを示すVCSサフィックス(.gitなど)を含めるようにします。たとえば、goコマンドがモジュールcorp.example.com/repo.git/modをダウンロードする場合、追加のリクエストを行うことなく、https://corp.example.com/repo.gitまたはssh://corp.example.com/repo.gitにあるGitリポジトリをクローンします。

開発者は、プライベートモジュールを含むリポジトリへの読み取りアクセス権が必要です。これは、.gitconfigなどのグローバルVCS設定ファイルで設定できます。VCSツールは、インタラクティブな認証プロンプトを必要としないように設定するのが最適です。デフォルトでは、Gitを呼び出す場合、goコマンドはGIT_TERMINAL_PROMPT=0を設定することでインタラクティブなプロンプトを無効にしますが、明示的な設定は尊重します。

プライベートプロキシへの資格情報の渡す

goコマンドは、プロキシサーバーと通信する場合、HTTP 基本認証をサポートしています。

資格情報は、.netrcファイルで指定できます。たとえば、以下の行を含む.netrcファイルは、指定されたユーザー名とパスワードを使用して、マシンproxy.corp.example.comに接続するようにgoコマンドを設定します。

machine proxy.corp.example.com
login jrgopher
password hunter2

ファイルの場所は、NETRC環境変数で設定できます。NETRCが設定されていない場合、goコマンドはUNIXライクなプラットフォームでは$HOME/.netrcを、Windowsでは%USERPROFILE%\_netrcを読み取ります。

.netrcのフィールドは、スペース、タブ、改行で区切られています。残念ながら、これらの文字はユーザー名やパスワードでは使用できません。また、マシン名は完全なURLにすることができないため、同じマシン上の異なるパスに対して異なるユーザー名とパスワードを指定することはできません。

あるいは、資格情報をGOPROXYURLに直接指定することもできます。例えば、

GOPROXY=https://jrgopher:hunter2@proxy.corp.example.com

この方法を使用する際には注意してください。環境変数はシェル履歴やログに表示される可能性があります。

プライベートリポジトリへの資格情報の渡す

goコマンドは、モジュールをバージョン管理リポジトリから直接ダウンロードできます。これは、プライベートプロキシを使用しない場合、プライベートモジュールに必要なことです。「プライベートモジュールへの直接アクセス」セクションを参照して設定を確認してください。

goコマンドは、モジュールを直接ダウンロードする際に、gitなどのバージョン管理ツールを実行します。これらのツールは独自の認証を実行するため、.gitconfigなどのツール固有の設定ファイルで資格情報を設定する必要がある場合があります。

これがスムーズに機能することを確認するために、goコマンドが正しいリポジトリURLを使用し、バージョン管理ツールがパスワードのインタラクティブな入力を求めないことを確認してください。goコマンドは、リポジトリURLを検索する際にスキームが指定されていない限り、他のスキーム(ssh://など)よりもhttps:// URLを優先します。特にGitHubリポジトリの場合、goコマンドはhttps://を想定しています。

ほとんどのサーバーでは、クライアントをHTTP経由で認証するように設定できます。たとえば、GitHubはOAuthパーソナルアクセストークンをHTTPパスワードとして使用することをサポートしています。「プライベートプロキシへの資格情報の渡す」セクションと同様に、HTTPパスワードを.netrcファイルに保存できます。

あるいは、https:// URLを別のスキームに書き換えることもできます。たとえば、.gitconfigでは

[url "git@github.com:"]
    insteadOf = https://github.com/

詳細については、「なぜ「go get」はリポジトリのクローン作成時にHTTPSを使用するのですか?」を参照してください。

プライバシー

goコマンドは、モジュールプロキシサーバーとバージョン管理システムからモジュールとメタデータをダウンロードする場合があります。環境変数GOPROXYは、どのサーバーが使用されるかを制御します。環境変数GOPRIVATEGONOPROXYは、プロキシからどのモジュールがフェッチされるかを制御します。

GOPROXYのデフォルト値は

https://proxy.golang.org,direct

この設定では、goコマンドがモジュールまたはモジュールメタデータをダウンロードする場合、最初にGoogleが運営する公開モジュールプロキシであるproxy.golang.orgにリクエストを送信します(プライバシーポリシー)。各リクエストで送信される情報については、GOPROXYプロトコルを参照してください。goコマンドは個人を特定できる情報を送信しませんが、リクエストされている完全なモジュールパスは送信します。プロキシが404(見つかりません)または410(削除済み)のステータスで応答した場合、goコマンドはモジュールを提供するバージョン管理システムに直接接続しようとします。詳細については、バージョン管理システムを参照してください。

GOPRIVATEまたはGONOPROXY環境変数は、プライベートであり、プロキシからリクエストされるべきではないモジュールプレフィックスに一致するglobパターンの一覧に設定できます。例:

GOPRIVATE=*.corp.example.com,*.research.example.com

GOPRIVATEは単にGONOPROXYGONOSUMDBのデフォルトとして機能するため、GONOSUMDBに異なる値を設定する必要がない限り、GONOPROXYを設定する必要はありません。モジュールパスがGONOPROXYに一致する場合、goコマンドはそのモジュールに対してGOPROXYを無視し、そのバージョン管理リポジトリから直接フェッチします。これは、プライベートモジュールを提供するプロキシがない場合に便利です。プライベートモジュールへの直接アクセスを参照してください。

すべてのモジュールを提供する信頼できるプロキシがある場合、GONOPROXYを設定しないでください。たとえば、GOPROXYが1つのソースに設定されている場合、goコマンドは他のソースからモジュールをダウンロードしません。この状況では、GONOSUMDBを設定する必要があります。

GOPROXY=https://proxy.corp.example.com
GONOSUMDB=*.corp.example.com,*.research.example.com

プライベートモジュールのみを提供する信頼できるプロキシがある場合、GONOPROXYを設定する必要はありませんが、プロキシが正しいステータスコードで応答するように注意する必要があります。たとえば、次の構成を考えてみましょう。

GOPROXY=https://proxy.corp.example.com,https://proxy.golang.org
GONOSUMDB=*.corp.example.com,*.research.example.com

タイプミスにより、開発者が存在しないモジュールをダウンロードしようとしたとします。

go mod download corp.example.com/secret-product/typo@latest

goコマンドは最初に、proxy.corp.example.comからこのモジュールをリクエストします。そのプロキシが404(見つかりません)または410(削除済み)で応答した場合、goコマンドはproxy.golang.orgにフォールバックし、リクエストURLにsecret-productパスを送信します。プライベートプロキシが他のエラーコードで応答した場合、goコマンドはエラーを出力し、他のソースにフォールバックしません。

プロキシに加えて、goコマンドはチェックサムデータベースに接続して、go.sumにリストされていないモジュールの暗号化ハッシュを検証できます。GOSUMDB環境変数は、チェックサムデータベースの名前、URL、公開鍵を設定します。GOSUMDBのデフォルト値はsum.golang.orgであり、これはGoogleが運営する公開チェックサムデータベースです(プライバシーポリシー)。各リクエストで送信される情報については、チェックサムデータベースを参照してください。プロキシと同様に、goコマンドは個人を特定できる情報を送信しませんが、リクエストされている完全なモジュールパスは送信し、チェックサムデータベースは非公開モジュールのチェックサムを計算できません。

GONOSUMDB環境変数は、プライベートであり、チェックサムデータベースからリクエストされるべきではないモジュールを示すパターンに設定できます。GOPRIVATEGONOSUMDBGONOPROXYのデフォルトとして機能するため、GONOPROXYに異なる値を設定する必要がない限り、GONOSUMDBを設定する必要はありません。

プロキシはチェックサムデータベースをミラーリングすることができます。GOPROXYのプロキシがこの機能を持っている場合、goコマンドはチェックサムデータベースに直接接続しません。

チェックサムデータベースの使用を完全に無効にするには、GOSUMDBoffに設定できます。この設定では、goコマンドは、ダウンロードされたモジュールが既にgo.sumにある場合を除き、ダウンロードされたモジュールを認証しません。モジュールの認証を参照してください。

モジュールキャッシュ

モジュールキャッシュとは、goコマンドがダウンロードしたモジュールファイルを保存するディレクトリです。モジュールキャッシュは、コンパイルされたパッケージやその他のビルド成果物を含むビルドキャッシュとは異なります。

モジュールキャッシュのデフォルトの場所は$GOPATH/pkg/modです。別の場所を使用するには、GOMODCACHE環境変数を設定します。

モジュールキャッシュには最大サイズがなく、goコマンドは自動的にその内容を削除しません。

キャッシュは、同じマシンで開発された複数のGoプロジェクトで共有できます。goコマンドは、メインモジュールの場所にかかわらず、同じキャッシュを使用します。複数のgoコマンドインスタンスが、同時に同じモジュールキャッシュに安全にアクセスできます。

goコマンドは、ダウンロード後にモジュールが誤って変更されるのを防ぐために、読み取り専用権限でキャッシュにモジュールソースファイルとディレクトリを作成します。これには、rm -rfなどのコマンドでキャッシュを削除しにくくなるという不都合な副作用があります。代わりに、go clean -modcacheを使用してキャッシュを削除できます。あるいは、-modcacherwフラグを使用すると、goコマンドは読み書き権限を持つ新しいディレクトリを作成します。これにより、エディター、テスト、その他のプログラムがモジュールキャッシュ内のファイルを修正するリスクが高まります。go mod verifyコマンドを使用して、メインモジュールの依存関係に対する変更を検出できます。これは、各モジュール依存関係の抽出されたコンテンツをスキャンし、go.sumの予想されるハッシュと一致することを確認します。

次の表は、モジュールキャッシュ内のほとんどのファイルの目的を説明しています。一部の一時ファイル(ロックファイル、一時ディレクトリ)は省略されています。各パスについて、$moduleはモジュールパス、$versionはバージョンです。スラッシュ(/)で終わるパスはディレクトリです。モジュールパスとバージョンの大文字は、大文字と小文字を区別しないファイルシステムでの競合を避けるため、感嘆符(!)を使用してエスケープされます(Azure!azureとしてエスケープされます)。

パス 説明
$module@$version/ モジュールの.zipファイルの抽出された内容を含むディレクトリ。これは、ダウンロードされたモジュールのモジュールルートディレクトリとして機能します。元のモジュールにgo.modファイルがない場合は、このファイルは含まれません。
cache/download/ モジュールプロキシからダウンロードされたファイルと、バージョン管理システムから取得されたファイルを含むディレクトリ。このディレクトリのレイアウトはGOPROXYプロトコルに従っているため、このディレクトリはHTTPファイルサーバーで提供される場合や、file:// URLで参照される場合にプロキシとして使用できます。
cache/download/$module/@v/list 既知のバージョンのリスト(GOPROXYプロトコルを参照)。これは時間の経過とともに変化する可能性があるため、goコマンドは通常、このファイルの再利用ではなく、新しいコピーを取得します。
cache/download/$module/@v/$version.info バージョンに関するJSONメタデータ(GOPROXYプロトコルを参照)。これは時間の経過とともに変化する可能性があるため、goコマンドは通常、このファイルの再利用ではなく、新しいコピーを取得します。
cache/download/$module/@v/$version.mod このバージョンのgo.modファイル(GOPROXYプロトコルを参照)。元のモジュールにgo.modファイルがない場合、これは要件のない合成ファイルです。
cache/download/$module/@v/$version.zip モジュールの圧縮内容(GOPROXYプロトコルおよびモジュールzipファイルを参照)。
cache/download/$module/@v/$version.ziphash .zipファイル内のファイルの暗号化ハッシュ。.zipファイル自体がハッシュ化されるわけではないため、ファイルの順序、圧縮、配置、メタデータはハッシュに影響しません。モジュールを使用する場合、goコマンドは、このハッシュがgo.sumの対応する行と一致することを確認します。go mod verifyコマンドは、モジュールの.zipファイルと抽出されたディレクトリのハッシュがこれらのファイルと一致することを確認します。
cache/download/sumdb/ チェックサムデータベース(通常はsum.golang.org)からダウンロードされたファイルを含むディレクトリ。
cache/vcs/ ソースから直接フェッチされたモジュールのクローンされたバージョン管理リポジトリが含まれています。ディレクトリ名は、リポジトリの種類とURLから派生した16進数エンコードされたハッシュです。リポジトリは、ディスク上のサイズが最適化されています。たとえば、クローンされたGitリポジトリは、可能な限りベアでシャローです。

モジュールの認証

goコマンドがzipファイルまたはgo.modファイルモジュールキャッシュにダウンロードすると、暗号化ハッシュを計算し、既知の値と比較して、ファイルが最初にダウンロードされてから変更されていないことを確認します。ダウンロードされたファイルに正しいハッシュがない場合、goコマンドはセキュリティエラーを報告します。

go.modファイルの場合、goコマンドはファイルの内容からハッシュを計算します。モジュールzipファイルの場合、goコマンドは、アーカイブ内のファイルの名前と内容を決定的な順序でハッシュを計算します。ファイルの順序、圧縮、配置、その他のメタデータはハッシュに影響しません。golang.org/x/mod/sumdb/dirhashでハッシュの実装の詳細を参照してください。

goコマンドは、各ハッシュをメインモジュールのgo.sumファイルの対応する行と比較します。ハッシュがgo.sumのハッシュと異なる場合、goコマンドはセキュリティエラーを報告し、ダウンロードされたファイルを削除してモジュールキャッシュに追加しません。

go.sumファイルが存在しない場合、またはダウンロードされたファイルのハッシュが含まれていない場合、goコマンドは、公開されているモジュールのハッシュのグローバルソースであるチェックサムデータベースを使用してハッシュを確認できます。ハッシュが検証されると、goコマンドはそれをgo.sumに追加し、ダウンロードされたファイルをモジュールキャッシュに追加します。モジュールがプライベートである場合(GOPRIVATEまたはGONOSUMDB環境変数によって一致する場合)、またはチェックサムデータベースが無効になっている場合(GOSUMDB=offを設定した場合)、goコマンドはハッシュを受け入れ、検証せずにファイルをモジュールキャッシュに追加します。

モジュールキャッシュは通常、システム上のすべてのGoプロジェクトで共有され、各モジュールには、異なるハッシュを持つ独自のgo.sumファイルがある場合があります。他のモジュールを信頼する必要を避けるために、goコマンドは、モジュールキャッシュ内のファイルにアクセスするたびに、メインモジュールのgo.sumを使用してハッシュを検証します。zipファイルのハッシュの計算にはコストがかかるため、goコマンドは、ファイルを再ハッシュする代わりに、zipファイルと共に保存されている事前に計算されたハッシュを確認します。go mod verifyコマンドを使用して、zipファイルと抽出されたディレクトリがモジュールキャッシュに追加されてから変更されていないことを確認できます。

go.sumファイル

モジュールには、ルートディレクトリにgo.modファイルと共にgo.sumという名前のテキストファイルが含まれている場合があります。go.sumファイルには、モジュールの直接および間接的な依存関係の暗号化ハッシュが含まれています。goコマンドがモジュールの.modまたは.zipファイルをモジュールキャッシュにダウンロードすると、ハッシュを計算し、そのハッシュがメインモジュールのgo.sumファイル内の対応するハッシュと一致することを確認します。モジュールに依存関係がない場合、またはreplaceディレクティブを使用してすべての依存関係がローカルディレクトリに置き換えられている場合、go.sumは空であるか、存在しない場合があります。

go.sumの各行には、スペースで区切られた3つのフィールドがあります。モジュールパス、バージョン(/go.modで終わる場合もあります)、およびハッシュです。

go.sumファイルには、モジュールの複数のバージョンのハッシュが含まれている場合があります。最小バージョン選択を実行するために、goコマンドは依存関係の複数のバージョンのgo.modファイルをロードする必要がある場合があります。go.sumには、不要になったモジュールバージョンのハッシュ(たとえば、アップグレード後)も含まれている場合があります。go mod tidyは、不足しているハッシュを追加し、go.sumから不要なハッシュを削除します。

チェックサムデータベース

チェックサムデータベースは、go.sum行のグローバルなソースです。goコマンドは、多くの状況でこれを使用して、プロキシまたはオリジンサーバーによる不正な動作を検出できます。

チェックサムデータベースは、公開されているすべてのモジュールバージョンのグローバルな整合性と信頼性を確保します。これにより、不正なコードが気付かれずに提供されることがないため、信頼できないプロキシが可能になります。また、モジュールの作成者が後でリポジトリのタグを変更した場合でも、特定のバージョンに関連付けられたビットが日々変化しないことを保証します。

チェックサムデータベースは、Googleによって運営されているsum.golang.orgによって提供されています。これは、Trillianによってバックアップされたgo.sum行ハッシュのトランスペアレントログ(または「Merkle Tree」)です。Merkleツリーの主な利点は、独立した監査者が改ざんされていないことを検証できるため、単純なデータベースよりも信頼性が高いことです。

goコマンドは、提案:パブリックGoモジュールエコシステムのセキュリティ保護で最初に概説されたプロトコルを使用して、チェックサムデータベースと対話します。

次の表は、チェックサムデータベースが応答する必要があるクエリを指定しています。各パスについて、$baseはチェックサムデータベースURLのパス部分、$moduleはモジュールパス、$versionはバージョンです。たとえば、チェックサムデータベースURLがhttps://sum.golang.orgで、クライアントがバージョンv0.3.2でモジュールgolang.org/x/textのレコードを要求している場合、クライアントはhttps://sum.golang.org/lookup/golang.org/x/text@v0.3.2に対するGETリクエストを送信します。

大文字と小文字を区別しないファイルシステムから提供する場合のあいまいさを回避するために、$moduleおよび$version要素は、大文字を感嘆符とそれに対応する小文字に置き換えることによってケースエンコードされます。これにより、モジュールexample.com/Mexample.com/mの両方をディスクに保存できます(前者はexample.com/!mとしてエンコードされるため)。

角括弧で囲まれたパスの部分は、[.p/$W]のように、オプションの値を表します。

パス 説明
$base/latest 最新のログの署名付きエンコードされたツリー記述を返します。この署名付き記述は、1つ以上のサーバーキーによって署名され、サーバーの公開キーを使用して検証できるテキストであるnoteの形式です。ツリー記述は、ツリーのサイズと、そのサイズのツリーヘッドのハッシュを提供します。このエンコーディングは、 golang.org/x/mod/sumdb/tlog#FormatTreeで説明されています。
$base/lookup/$module@$version $version$moduleに関するエントリのログレコード番号、レコードのデータ(つまり、$version$modulego.sum行)、およびレコードを含む署名付きエンコードされたツリー記述を返します。
$base/tile/$H/$L/$K[.p/$W] ログのセクションを構成するハッシュのセットである[ログタイル](https://research.swtch.com/tlog#serving_tiles)を返します。各タイルは、タイルレベル$L、左から$K番目の2次元座標で、タイルの高さは$Hで定義されます。オプションの.p/$Wサフィックスは、$Wハッシュのみを含む部分的なログタイルを示します。部分的なタイルが見つからない場合、クライアントは完全なタイルのフェッチにフォールバックする必要があります。
$base/tile/$H/data/$K[.p/$W] /tile/$H/0/$K[.p/$W](リテラルのdataパス要素付き)のリーフハッシュのレコードデータを返します。

goコマンドがチェックサムデータベースを参照する場合、最初のステップは/lookupエンドポイントを介してレコードデータを取得することです。モジュールバージョンがログにまだ記録されていない場合、チェックサムデータベースは応答する前にオリジンサーバーからそれをフェッチしようとします。この/lookupデータは、このモジュールバージョンの合計とそのログ内での位置を提供し、クライアントに、証明を実行するためにフェッチする必要があるタイルを知らせます。goコマンドは、「包含」証明(特定のレコードがログに存在すること)と「整合性」証明(ツリーが改ざんされていないこと)を実行してから、新しいgo.sum行をメインモジュールのgo.sumファイルに追加します。/lookupからのデータは、最初に署名されたツリーハッシュに対して認証し、署名されたツリーハッシュをクライアントの署名されたツリーハッシュのタイムラインに対して認証する前に使用しないことが重要です。

チェックサムデータベースによって提供される署名付きツリーハッシュと新しいタイルはモジュールキャッシュに保存されるため、goコマンドは不足しているタイルのみをフェッチする必要があります。

goコマンドは、チェックサムデータベースに直接接続する必要はありません。チェックサムデータベースをミラーリングし、上記のプロトコルをサポートするモジュールプロキシを介してモジュール合計を要求できます。これは、組織外の要求をブロックするプライベートな企業プロキシに特に役立ちます。

GOSUMDB環境変数は、使用するチェックサムデータベースの名前、およびオプションでその公開キーとURLを識別します。

GOSUMDB="sum.golang.org"
GOSUMDB="sum.golang.org+<publickey>"
GOSUMDB="sum.golang.org+<publickey> https://sum.golang.org"

goコマンドはsum.golang.orgの公開キーを知っており、また、(中国本土で使用可能な)sum.golang.google.cnという名前がsum.golang.orgチェックサムデータベースに接続していることも知っています。他のデータベースを使用するには、公開キーを明示的に指定する必要があります。URLは、データベース名の前にhttps://が付いたものになります。

GOSUMDBは、Googleが運営するGoチェックサムデータベースであるsum.golang.orgにデフォルト設定されています。サービスのプライバシーポリシーについては、https://sum.golang.org/privacyを参照してください。

GOSUMDBoffに設定されている場合、またはgo get-insecureフラグで呼び出された場合、チェックサムデータベースは参照されず、認識されないすべてのモジュールが受け入れられます。これは、すべてのモジュールについて検証可能な繰り返し可能なダウンロードのセキュリティ保証を放棄するという犠牲を伴います。特定のモジュールについてチェックサムデータベースをバイパスするより良い方法は、GOPRIVATEまたはGONOSUMDB環境変数を使用することです。詳細については、プライベートモジュールを参照してください。

go env -wコマンドを使用して、将来のgoコマンドの呼び出しのためにこれらの変数を設定できます。

環境変数

goコマンドでのモジュールの動作は、以下にリストされている環境変数を使用して構成できます。このリストには、モジュール関連の環境変数のみが含まれています。goコマンドで認識されるすべての環境変数のリストについては、go help environmentを参照してください。

変数 説明
GO111MODULE

goコマンドがモジュール認識モードで実行されるか、GOPATHモードで実行されるかを制御します。3つの値が認識されます。

  • offgoコマンドはgo.modファイルを無視し、GOPATHモードで実行されます。
  • on(または設定されていない):go.modファイルが存在しない場合でも、goコマンドはモジュール認識モードで実行されます。
  • auto:現在のディレクトリまたは親ディレクトリのいずれかにgo.modファイルが存在する場合、goコマンドはモジュール認識モードで実行されます。Go 1.15以前では、これがデフォルトでした。

詳細については、モジュール認識コマンドを参照してください。

GOMODCACHE

goコマンドがダウンロードしたモジュールと関連ファイルを保存するディレクトリ。このディレクトリの構造の詳細については、モジュールキャッシュを参照してください。

GOMODCACHEが設定されていない場合、デフォルトは$GOPATH/pkg/modになります。

GOINSECURE

常に安全ではない方法でフェッチできるモジュールパスのプレフィックスのglobパターン(Goのpath.Matchの構文)のカンマ区切りリスト。直接フェッチされている依存関係のみに適用されます。

go get-insecureフラグとは異なり、GOINSECUREはモジュールチェックサムデータベースの検証を無効にしません。それを実現するには、GOPRIVATEまたはGONOSUMDBを使用できます。

GONOPROXY

モジュールプロキシではなく、常にバージョン管理リポジトリから直接フェッチする必要があるモジュールパスのプレフィックスのglobパターン(Goのpath.Matchの構文)のカンマ区切りリスト。

GONOPROXYが設定されていない場合、デフォルトはGOPRIVATEになります。プライバシーを参照してください。

GONOSUMDB

goがチェックサムデータベースを使用してチェックサムを検証しないモジュールパスのプレフィックスのglobパターン(Goのpath.Matchの構文)のカンマ区切りリスト。

GONOSUMDBが設定されていない場合、デフォルトはGOPRIVATEになります。プライバシーを参照してください。

GOPATH

GOPATHモードでは、GOPATH変数はGoコードを含む可能性のあるディレクトリのリストです。

モジュール認識モードでは、モジュールキャッシュは最初のGOPATHディレクトリのpkg/modサブディレクトリに格納されます。キャッシュ外のモジュールソースコードは、任意のディレクトリに格納できます。

GOPATHが設定されていない場合、ユーザーのホームディレクトリのgoサブディレクトリがデフォルトになります。

GOPRIVATE プライベートと見なされるべきモジュールパス接頭辞のglobパターン(Goのpath.Matchの構文)のカンマ区切りリスト。GOPRIVATEGONOPROXYGONOSUMDBのデフォルト値です。プライバシーを参照してください。GOPRIVATEは、モジュールがGOVCSに対してプライベートと見なされるかどうかについても決定します。
GOPROXY

カンマ(,)またはパイプ(|)で区切られたモジュールプロキシURLのリスト。goコマンドがモジュールに関する情報を検索する場合、成功した応答またはターミナルエラーを受け取るまで、リスト内の各プロキシに順番に問い合わせます。プロキシは、モジュールがそのサーバーで使用できないことを示すために、404(見つかりません)または410(なくなりました)ステータスで応答する場合があります。

goコマンドのエラーフォールバック動作は、URL間のセパレータ文字によって決定されます。プロキシURLの後にカンマが続く場合、goコマンドは404または410エラー後に次のURLにフォールバックします。その他のすべてのエラーは、ターミナルエラーと見なされます。プロキシURLの後にパイプが続く場合、goコマンドはタイムアウトなどの非HTTPエラーを含むすべてのエラーの後、次のソースにフォールバックします。

GOPROXY URLには、httpshttp、またはfileスキームを使用できます。URLにスキームがない場合、httpsが想定されます。モジュールキャッシュは、ファイルプロキシとして直接使用できます。

GOPROXY=file://$(go env GOMODCACHE)/cache/download

プロキシURLの代わりに2つのキーワードを使用できます。

  • off:任意のソースからのモジュールのダウンロードを許可しません。
  • direct:モジュールプロキシを使用する代わりに、バージョン管理リポジトリから直接ダウンロードします。

GOPROXYのデフォルトはhttps://proxy.golang.org,directです。この設定では、goコマンドは最初にGoogleが運営するGoモジュールミラーに問い合わせ、ミラーにモジュールがない場合は直接接続にフォールバックします。ミラーのプライバシーポリシーについては、https://proxy.golang.org/privacyを参照してください。特定のモジュールがプロキシを使用してダウンロードされないようにするには、GOPRIVATEGONOPROXY環境変数を設定できます。プライベートプロキシ設定の詳細については、プライバシーを参照してください。

モジュールプロキシパッケージをモジュールに解決するで、プロキシの使用方法の詳細を参照してください。

GOSUMDB

使用するチェックサムデータベースの名前、およびオプションでその公開鍵とURLを識別します。例:

GOSUMDB="sum.golang.org"
GOSUMDB="sum.golang.org+<publickey>"
GOSUMDB="sum.golang.org+<publickey> https://sum.golang.org"

goコマンドはsum.golang.orgの公開鍵を知っており、sum.golang.google.cn(中国本土で使用可能)という名前がsum.golang.orgデータベースに接続していることも知っています。他のデータベースを使用するには、公開鍵を明示的に指定する必要があります。URLは、データベース名の後にhttps://が続くものとしてデフォルトになります。

GOSUMDBのデフォルトはsum.golang.org(Googleが運営するGoチェックサムデータベース)です。サービスのプライバシーポリシーについては、https://sum.golang.org/privacyを参照してください。

GOSUMDBoffに設定されている場合、またはgo get-insecureフラグを使用して呼び出された場合、チェックサムデータベースは参照されず、認識されないすべてのモジュールが受け入れられます。これは、すべてのモジュールに対して検証可能な繰り返し可能なダウンロードのセキュリティ保証を放棄するという代償を伴います。特定のモジュールに対してチェックサムデータベースをバイパスするより良い方法は、GOPRIVATEまたはGONOSUMDB環境変数を使用することです。

モジュールの認証プライバシーで詳細を参照してください。

GOVCS

goコマンドがパブリックモジュールとプライベートモジュール(パスがGOPRIVATEのパターンに一致するかどうかで定義)またはglobパターンに一致するその他のモジュールのダウンロードに使用できるバージョン管理ツールのセットを制御します。

GOVCSが設定されていない場合、またはモジュールがGOVCSのどのパターンにも一致しない場合、goコマンドはパブリックモジュールにはgithgを使用し、プライベートモジュールには既知のバージョン管理ツールを使用できます。具体的には、goコマンドは、GOVCSが以下のように設定されているかのように動作します。

public:git|hg,private:all

GOVCSによるバージョン管理ツールの制御で完全な説明を参照してください。

GOWORK

GOWORK環境変数は、提供された[`go.work`ファイル](#go-work-file)を使用してワークスペースを定義するワークスペースモードに入るようにgoコマンドに指示します。GOWORKoffに設定されている場合、ワークスペースモードは無効になります。これは、シングルモジュールモードでgoコマンドを実行するために使用できます。たとえば、GOWORK=off go build .はシングルモジュールモードで.パッケージをビルドします。GOWORKが空の場合、goコマンドは[ワークスペース](#workspaces)セクションで説明されているようにgo.workファイルを検索します。

用語集

ビルド制約:Goソースファイルがパッケージのコンパイル時に使用されるかどうかを決定する条件。ビルド制約は、ファイル名サフィックス(例:foo_linux_amd64.go)またはビルド制約コメント(例:// +build linux,amd64)で表現できます。ビルド制約を参照してください。

ビルドリスト:go buildgo list、またはgo testなどのビルドコマンドで使用されるモジュールバージョンのリスト。ビルドリストは、メインモジュールgo.modファイルと、推移的に必要なモジュールのgo.modファイルから、最小バージョン選択を使用して決定されます。ビルドリストには、モジュールグラフ内のすべてのモジュールのバージョンが含まれており、特定のコマンドに関連するモジュールだけではありません。

標準バージョン:+incompatible以外のビルドメタデータサフィックスのない、正しくフォーマットされたバージョン。たとえば、v1.2.3は標準バージョンですが、v1.2.3+metaはそうではありません。

現在のモジュール:メインモジュールの同義語。

非推奨モジュール:作成者によってもはやサポートされていないモジュール(ただし、メジャーバージョンは、この目的のために別個のモジュールと見なされます)。非推奨モジュールは、そのgo.modファイルの最新バージョンで非推奨コメントでマークされています。

直接依存関係:メインモジュールのパッケージまたはテストの.goソースファイルのimport宣言にパスが表示されるパッケージ、またはそのようなパッケージを含むモジュール。(間接依存関係と比較してください。)

ダイレクトモード:環境変数の設定により、goコマンドはモジュールプロキシではなく、バージョン管理システムからモジュールを直接ダウンロードします。GOPROXY=directは、すべてのモジュールに対してこれを行います。GOPRIVATEGONOPROXYは、パターンリストに一致するモジュールに対してこれを行います。

go.modファイル:モジュールのパス、要件、その他のメタデータを定義するファイル。モジュールのルートディレクトリに表示されます。go.modファイルに関するセクションを参照してください。

go.workファイル ワークスペースで使用されるモジュールのセットを定義するファイル。go.workファイルに関するセクションを参照してください。

インポートパス:Goソースファイルでパッケージをインポートするために使用される文字列。パッケージパスと同義です。

間接依存関係:メインモジュールのパッケージまたはテストによって推移的にインポートされるが、メインモジュール内のimport宣言にパスが表示されないパッケージ。または、モジュールグラフに表示されるが、メインモジュールによって直接インポートされるパッケージを提供しないモジュール。(直接依存関係と比較してください。)

遅延モジュール読み込み:Go 1.17での変更により、go 1.17以降を指定するモジュールで、必要としないコマンドのモジュールグラフの読み込みを回避します。遅延モジュール読み込みを参照してください。

メインモジュール:goコマンドが呼び出されるモジュール。メインモジュールは、現在のディレクトリまたは親ディレクトリのgo.modファイルによって定義されます。モジュール、パッケージ、バージョンを参照してください。

メジャーバージョン:セマンティックバージョン(v1.2.31)の最初の番号。互換性のない変更を含むリリースでは、メジャーバージョンを増分し、マイナーバージョンとパッチバージョンを0に設定する必要があります。メジャーバージョンが0のセマンティックバージョンは不安定と見なされます。

メジャーバージョンサブディレクトリ:モジュールのメジャーバージョンサフィックスに一致するバージョン管理リポジトリ内のサブディレクトリ。モジュールを定義できます。たとえば、ルートパスexample.com/modのリポジトリ内のモジュールexample.com/mod/v2は、リポジトリのルートディレクトリまたはメジャーバージョンサブディレクトリv2に定義できます。リポジトリ内のモジュールディレクトリを参照してください。

メジャーバージョンサフィックス:メジャーバージョン番号に一致するモジュールパスのサフィックス。たとえば、example.com/mod/v2/v2。メジャーバージョンサフィックスはv2.0.0以降で必要であり、それ以前のバージョンでは許可されていません。メジャーバージョンサフィックスに関するセクションを参照してください。

最小バージョン選択(MVS):ビルドで使用されるすべてのモジュールのバージョンを決定するために使用されるアルゴリズム。最小バージョン選択に関するセクションで詳細を参照してください。

マイナーバージョン:セマンティックバージョン(v1.2.32)の2番目の番号。新しい下位互換性のある機能を含むリリースでは、マイナーバージョンを増分し、パッチバージョンを0に設定する必要があります。

モジュール:リリース、バージョン管理、および配布がまとめて行われるパッケージのコレクション。

モジュールキャッシュ:ダウンロードされたモジュールを格納するローカルディレクトリ(GOPATH/pkg/modにあります)。モジュールキャッシュを参照してください。

モジュールグラフ:メインモジュールにルートを置く、モジュール要件の有向グラフ。グラフの各頂点はモジュールであり、各辺はgo.modファイルのrequireステートメントからのバージョンです(メインモジュールのgo.modファイルのreplaceステートメントとexcludeステートメントに従います)。

モジュールグラフのプルーニング: Go 1.17 で導入された変更で、go 1.17 以降を指定するモジュールの推移的な依存関係を省略することで、モジュールグラフのサイズを削減します。モジュールグラフのプルーニングを参照してください。

モジュールパス: モジュールを識別し、モジュール内のパッケージインポートパスのプレフィックスとして機能するパスです。例えば、"golang.org/x/net" など。

モジュールプロキシ: GOPROXY プロトコルを実装するウェブサーバーです。goコマンドは、モジュールプロキシからバージョン情報、go.modファイル、モジュールのzipファイルをダウンロードします。

モジュールルートディレクトリ: モジュールを定義するgo.modファイルを含むディレクトリです。

モジュールサブディレクトリ: モジュールパスのうち、リポジトリルートパス以降の部分で、モジュールが定義されているサブディレクトリを示します。空でない場合、モジュールサブディレクトリはセマンティックバージョンタグのプレフィックスにもなります。モジュールサブディレクトリには、メジャーバージョンサフィックスは含まれません(モジュールがメジャーバージョンサブディレクトリにあっても)。モジュールパスを参照してください。

パッケージ: 同じディレクトリにある、まとめてコンパイルされるソースファイルの集合です。Go言語仕様のパッケージセクションを参照してください。

パッケージパス: パッケージを一意に識別するパスです。パッケージパスは、モジュールパスとモジュール内のサブディレクトリを結合したものです。例えば、"golang.org/x/net/html"は、モジュール"golang.org/x/net""html"サブディレクトリにあるパッケージのパッケージパスです。インポートパスの同義語です。

パッチバージョン: セマンティックバージョンにおける3番目の数値(v1.2.3では3)。モジュールの公開インターフェースに変更がないリリースでは、パッチバージョンを増分する必要があります。

プレリリースバージョン: パッチバージョンの直後にハイフンとドットで区切られた一連の識別子が続くバージョンです。例えば、v1.2.3-beta4など。プレリリースバージョンは不安定とみなされ、他のバージョンとの互換性があると想定されません。プレリリースバージョンは対応するリリースバージョンよりも前にソートされます:v1.2.3-prev1.2.3の前に来ます。リリースバージョンも参照してください。

擬似バージョン: リビジョン識別子(Gitコミットハッシュなど)とバージョン管理システムからのタイムスタンプをエンコードしたバージョンです。例えば、v0.0.0-20191109021931-daa7c04131f5など。非モジュールリポジトリとの互換性や、タグ付きバージョンが利用できない状況で使用されます。

リリースバージョン: プレリリースサフィックスのないバージョンです。例えば、v1.2.3v1.2.3-preではない)。プレリリースバージョンも参照してください。

リポジトリルートパス: モジュールパスのうち、バージョン管理リポジトリのルートディレクトリに対応する部分です。モジュールパスを参照してください。

リトラクトされたバージョン: 時期尚早に公開されたか、公開後に重大な問題が見つかったため、依存すべきではないバージョンです。retractディレクティブを参照してください。

セマンティックバージョンタグ: バージョン管理リポジトリのタグで、バージョンを特定のリビジョンにマッピングします。バージョンとコミットのマッピングを参照してください。

選択されたバージョン: 最小バージョン選択によって選択された、特定のモジュールのバージョンです。選択されたバージョンは、モジュールグラフで見つかったモジュールパスのうち、最も高いバージョンです。

vendorディレクトリ: メインモジュールのパッケージをビルドするために必要な、他のモジュールからのパッケージを含むディレクトリです。go mod vendorで管理されます。ベンダー管理を参照してください。

バージョン: モジュールの変更不能なスナップショットの識別子で、文字vの後にセマンティックバージョンが続きます。バージョンに関するセクションを参照してください。

ワークスペース: 最小バージョン選択(MVS)を実行する際にメインモジュールとして使用される、ディスク上のモジュールの集合です。ワークスペースに関するセクションを参照してください。