Go Modules Reference
はじめに
モジュールは、Go が依存関係を管理する方法です。
このドキュメントは、Go のモジュールシステムに関する詳細なリファレンスマニュアルです。Go プロジェクトの作成については、「Go コードの書き方」を参照してください。モジュールの使用、プロジェクトのモジュールへの移行、およびその他のトピックについては、「Go モジュールの使用」から始まるブログシリーズを参照してください。
モジュール、パッケージ、およびバージョン
モジュールは、まとめてリリース、バージョン管理、配布されるパッケージの集まりです。モジュールは、バージョン管理リポジトリから直接、またはモジュールプロキシサーバーからダウンロードできます。
モジュールは、モジュールパスによって識別され、そのモジュールパスは、モジュールの依存関係に関する情報とともに、go.mod ファイルで宣言されます。モジュールルートディレクトリは、go.mod ファイルを含むディレクトリです。メインモジュールは、go コマンドが呼び出されるディレクトリを含むモジュールです。
モジュール内の各パッケージは、同じディレクトリにあるソースファイルの集まりであり、まとめてコンパイルされます。パッケージパスは、モジュールパスとパッケージを含むサブディレクトリ(モジュールルートに対する相対パス)を結合したものです。たとえば、モジュール"golang.org/x/net"には、ディレクトリ"html"にパッケージが含まれています。そのパッケージのパスは"golang.org/x/net/html"です。
モジュールパス
モジュールパスは、モジュールのgo.mod ファイル内のmodule ディレクティブで宣言される、モジュールの正規名です。モジュールのパスは、モジュール内のパッケージパスのプレフィックスです。
モジュールパスは、モジュールが何をするか、どこにあるかを両方とも記述する必要があります。通常、モジュールパスは、リポジトリのルートパス、リポジトリ内のディレクトリ(通常は空)、およびメジャーバージョンサフィックス(メジャーバージョン2以上の場合のみ)で構成されます。
- リポジトリルートパスは、モジュールが開発されているバージョン管理リポジトリのルートディレクトリに対応するモジュールパスの一部です。ほとんどのモジュールはリポジトリのルートディレクトリで定義されているため、これは通常、パス全体です。たとえば、
golang.org/x/netは、同じ名前のモジュールのリポジトリルートパスです。goコマンドがモジュールパスから派生したHTTPリクエストを使用してリポジトリを特定する方法については、「モジュールパスのリポジトリを検索する」を参照してください。 - モジュールがリポジトリのルートディレクトリで定義されていない場合、モジュールサブディレクトリは、メジャーバージョンサフィックスを含まない、ディレクトリの名前を示すモジュールパスの一部です。これは、セマンティックバージョンタグのプレフィックスとしても機能します。たとえば、モジュール
golang.org/x/tools/goplsは、ルートパスgolang.org/x/toolsを持つリポジトリのgoplsサブディレクトリにあるため、モジュールサブディレクトリgoplsを持ちます。詳細は「バージョンとコミットのマッピング」および「リポジトリ内のモジュールディレクトリ」を参照してください。 - モジュールがメジャーバージョン2以上でリリースされる場合、モジュールパスは
/v2のようなメジャーバージョンサフィックスで終わる必要があります。これは、サブディレクトリ名の一部である場合とそうでない場合があります。たとえば、パスgolang.org/x/repo/sub/v2を持つモジュールは、リポジトリgolang.org/x/repoの/subまたは/sub/v2サブディレクトリにある可能性があります。
モジュールが他のモジュールの依存関係になる可能性がある場合、goコマンドがモジュールを見つけてダウンロードできるように、これらのルールに従う必要があります。モジュールパスで使用できる文字には、いくつかの字句制限もあります。
他のモジュールの依存関係としてフェッチされることがないモジュールは、任意の有効なパッケージパスをそのモジュールパスとして使用できますが、モジュールの依存関係やGo標準ライブラリで使用される可能性のあるパスと衝突しないように注意する必要があります。Go標準ライブラリは、最初のパス要素にドットを含まないパッケージパスを使用し、goコマンドはネットワークサーバーからそのようなパスを解決しようとはしません。exampleとtestのパスはユーザーのために予約されています。これらは標準ライブラリでは使用されず、チュートリアルやサンプルコードで定義された、またはテストの一部として作成および操作されるような自己完結型モジュールでの使用に適しています。
バージョン
バージョンは、モジュールの不変のスナップショットを識別し、リリースまたはプレリリースのいずれかです。各バージョンは文字vで始まり、その後にセマンティックバージョンが続きます。バージョンの書式設定、解釈、比較方法の詳細については、「Semantic Versioning 2.0.0」を参照してください。
まとめると、セマンティックバージョンは、ドットで区切られた3つの非負整数(左から順にメジャー、マイナー、パッチバージョン)で構成されます。パッチバージョンの後に、ハイフンで始まるオプションのプレリリース文字列が続く場合があります。プレリリース文字列またはパッチバージョンの後に、プラス記号で始まるビルドメタデータ文字列が続く場合があります。たとえば、v0.0.0、v1.12.134、v8.0.5-pre、およびv2.0.9+metaは有効なバージョンです。
バージョンの各部分は、そのバージョンが安定しているかどうか、および以前のバージョンと互換性があるかどうかを示します。
- メジャーバージョンは、モジュールの公開インターフェースまたは文書化された機能に後方互換性のない変更(たとえば、パッケージが削除された後など)が行われた後、インクリメントされ、マイナーバージョンとパッチバージョンはゼロに設定されなければなりません。
- マイナーバージョンは、後方互換性のある変更(たとえば、新しい関数が追加された後など)が行われた後、インクリメントされ、パッチバージョンはゼロに設定されなければなりません。
- パッチバージョンは、バグ修正や最適化など、モジュールの公開インターフェースに影響を与えない変更の後、インクリメントされなければなりません。
- プレリリースサフィックスは、バージョンがプレリリースであることを示します。プレリリースバージョンは、対応するリリースバージョンよりも前にソートされます。たとえば、
v1.2.3-preはv1.2.3よりも前に来ます。 - ビルドメタデータサフィックスは、バージョンの比較目的では無視されます。goコマンドはビルドメタデータ付きのバージョンを受け入れ、バージョン間の全順序を維持するためにそれらを疑似バージョンに変換します。
- 特別なサフィックス
+incompatibleは、モジュールバージョン2以降への移行前にリリースされたバージョンを示します(「非モジュールリポジトリとの互換性」を参照)。 - 特別なサフィックス
+dirtyは、Goツールチェーン1.24以降で、作業ディレクトリにコミットされていない変更を含む有効なローカルバージョン管理システム (VCS) リポジトリ内でバイナリがビルドされた場合に、そのバイナリのバージョン情報に追加されます。
- 特別なサフィックス
メジャーバージョンが0であるか、プレリリースサフィックスがある場合、バージョンは不安定と見なされます。不安定なバージョンは、互換性要件の対象ではありません。たとえば、v0.2.0はv0.1.0と互換性がない場合があり、v1.5.0-betaはv1.5.0と互換性がない場合があります。
Goは、これらの規則に従わないタグ、ブランチ、またはリビジョンを使用して、バージョン管理システム内のモジュールにアクセスする場合があります。ただし、メインモジュール内では、goコマンドは、この標準に従わないリビジョン名を自動的に正規バージョンに変換します。goコマンドは、このプロセスの一部としてビルドメタデータサフィックス(+incompatibleを除く)も削除します。これにより、リビジョン識別子(Gitコミットハッシュなど)とバージョン管理システムからのタイムスタンプをエンコードするプレリリースバージョンである疑似バージョンが生じる場合があります。たとえば、コマンドgo get golang.org/x/net@daa7c041は、コミットハッシュdaa7c041を疑似バージョンv0.0.0-20191109021931-daa7c04131f5に変換します。メインモジュールの外部では正規バージョンが必要であり、go.modファイルにmasterのような非正規バージョンが出現すると、goコマンドはエラーを報告します。
疑似バージョン
疑似バージョンは、バージョン管理リポジトリ内の特定の改訂に関する情報をエンコードする、特別にフォーマットされたプレリリースバージョンです。たとえば、v0.0.0-20191109021931-daa7c04131f5は疑似バージョンです。
疑似バージョンは、セマンティックバージョンタグが利用できないリビジョンを参照する場合があります。たとえば、開発ブランチでバージョンタグを作成する前にコミットをテストするために使用できます。
各疑似バージョンは3つの部分で構成されます。
- ベースバージョンプレフィックス(
vX.0.0またはvX.Y.Z-0)。これは、改訂の前にセマンティックバージョンタグから派生したものか、そのようなタグがない場合はvX.0.0です。 - タイムスタンプ(
yyyymmddhhmmss)。これは、改訂が作成されたUTC時刻です。Gitでは、これはコミット時刻であり、作者時刻ではありません。 - リビジョン識別子(
abcdefabcdef)。これは、コミットハッシュの12文字のプレフィックス、またはSubversionではゼロ埋めされたリビジョン番号です。
各疑似バージョンは、ベースバージョンに応じて3つの形式のいずれかになります。これらの形式により、疑似バージョンはベースバージョンよりも高く、次のタグ付きバージョンよりも低く比較されることが保証されます。
vX.0.0-yyyymmddhhmmss-abcdefabcdefは、既知のベースバージョンがない場合に使用されます。すべてのバージョンと同様に、メジャーバージョンXはモジュールのメジャーバージョンサフィックスと一致する必要があります。vX.Y.Z-pre.0.yyyymmddhhmmss-abcdefabcdefは、ベースバージョンがvX.Y.Z-preのようなプレリリースバージョンである場合に使用されます。vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdefabcdefは、ベースバージョンがvX.Y.Zのようなリリースバージョンである場合に使用されます。たとえば、ベースバージョンがv1.2.3の場合、疑似バージョンはv1.2.4-0.20191109021931-daa7c04131f5になる場合があります。
異なるベースバージョンを使用することで、複数の疑似バージョンが同じコミットを参照する場合があります。これは、疑似バージョンが書き込まれた後に低いバージョンがタグ付けされた場合に自然に発生します。
これらの形式は、疑似バージョンに2つの有用なプロパティを与えます。
- 既知のベースバージョンを持つ疑似バージョンは、それらのバージョンよりも高い順序になりますが、それ以降のバージョンの他のプレリリースよりも低い順序になります。
- 同じベースバージョンプレフィックスを持つ疑似バージョンは、時系列順にソートされます。
goコマンドは、モジュールの作成者が疑似バージョンが他のバージョンと比較される方法を制御し、疑似バージョンがモジュールのコミット履歴の実際の一部であるリビジョンを参照することを保証するために、いくつかのチェックを実行します。
- ベースバージョンが指定されている場合、疑似バージョンによって記述されたリビジョンの祖先である対応するセマンティックバージョンタグが存在する必要があります。これにより、開発者が
v1.999.999-99999999999999-daa7c04131f5のようにすべてのタグ付きバージョンよりも高く比較される疑似バージョンを使用して最小バージョン選択を回避することを防ぎます。 - タイムスタンプはリビジョンのタイムスタンプと一致する必要があります。これにより、攻撃者がそれ以外は同じ疑似バージョンの無制限の数でモジュールプロキシを氾濫させるのを防ぎます。これにより、モジュールコンシューマーがバージョンの相対的な順序を変更することも防ぎます。
- リビジョンは、モジュールリポジトリのブランチまたはタグのいずれかの祖先である必要があります。これにより、攻撃者が未承認の変更やプルリクエストを参照することを防ぎます。
疑似バージョンを手動で入力する必要はありません。多くのコマンドはコミットハッシュまたはブランチ名を受け入れ、それを自動的に疑似バージョン(または利用可能な場合はタグ付きバージョン)に変換します。例えば
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バージョンは不安定であり、互換性の保証がないため、v0とv1の間でモジュールパスを変更する必要はありません。さらに、ほとんどのモジュールにとって、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にパッケージを含んでいるかどうかをチェックします。ディレクトリがパッケージと見なされるためには、少なくとも1つの.go拡張子のファイルが存在する必要があります。この目的のためにビルド制約は適用されません。ビルドリスト内のちょうど1つのモジュールがパッケージを提供する場合、そのモジュールが使用されます。どのモジュールもパッケージを提供しない場合、または2つ以上のモジュールがパッケージを提供する場合、goコマンドはエラーを報告します。-mod=modフラグは、goコマンドに、不足しているパッケージを提供する新しいモジュールを見つけ、go.modとgo.sumを更新するように指示します。go getおよびgo mod tidyコマンドはこれを自動的に行います。
goコマンドがパッケージパスの新しいモジュールを検索する際、GOPROXY環境変数をチェックします。これは、プロキシURLのカンマ区切りリスト、またはキーワードdirectまたはoffです。プロキシURLは、goコマンドがGOPROXYプロトコルを使用してモジュールプロキシに接続する必要があることを示します。directは、goコマンドがバージョン管理システムと通信する必要があることを示します。offは、通信を試行すべきではないことを示します。GOPRIVATEおよびGONOPROXY環境変数も、この動作を制御するために使用できます。
GOPROXYリストの各エントリについて、goコマンドは、パッケージを提供する可能性のある各モジュールパス(つまり、パッケージパスの各プレフィックス)の最新バージョンを要求します。正常に要求された各モジュールパスについて、goコマンドは最新バージョンのモジュールをダウンロードし、モジュールが要求されたパッケージを含んでいるかどうかをチェックします。1つ以上のモジュールが要求されたパッケージを含んでいる場合、最も長いパスを持つモジュールが使用されます。1つ以上のモジュールが見つかったが、どれも要求されたパッケージを含んでいない場合、エラーが報告されます。モジュールが見つからない場合、goコマンドはGOPROXYリストの次のエントリを試行します。エントリが残っていない場合、エラーが報告されます。
たとえば、goコマンドがパッケージgolang.org/x/net/htmlを提供するモジュールを探しており、GOPROXYがhttps://corp.example.com,https://proxy.golang.orgに設定されているとします。goコマンドは次のリクエストを行う可能性があります。
https://corp.example.com/へ(並行して)golang.org/x/net/htmlの最新バージョンのリクエストgolang.org/x/netの最新バージョンのリクエストgolang.org/xの最新バージョンのリクエストgolang.orgの最新バージョンのリクエスト
https://corp.example.com/へのすべてのリクエストが404または410で失敗した場合、https://proxy.golang.org/へgolang.org/x/net/htmlの最新バージョンのリクエストgolang.org/x/netの最新バージョンのリクエストgolang.org/xの最新バージョンのリクエストgolang.orgの最新バージョンのリクエスト
適切なモジュールが見つかると、goコマンドは、新しいモジュールのパスとバージョンを含む新しい要件をメインモジュールのgo.modファイルに追加します。これにより、将来同じパッケージがロードされたときに、同じバージョンで同じモジュールが使用されることが保証されます。解決されたパッケージがメインモジュールのパッケージによってインポートされていない場合、新しい要件には// indirectコメントが付きます。
go.mod ファイル
モジュールは、そのルートディレクトリにあるgo.modという名前のUTF-8エンコードされたテキストファイルによって定義されます。go.modファイルは行指向です。各行は、キーワードとそれに続く引数で構成される単一のディレクティブを保持します。例えば
module example.com/my/thing
go 1.23.0
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 の import のようにブロックを作成できます。
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 ファイル内の異なる種類のディレクティブを区別します。許可されるキーワードは、module、go、require、replace、exclude、およびretractです。
識別子は、モジュールパスやセマンティックバージョンなど、空白文字以外の文字のシーケンスです。
文字列は、引用符で囲まれた文字のシーケンスです。文字列には2種類あります: 引用符(", U+0022)で始まり、引用符で終わる解釈済み文字列と、グレイブアクセント(`, U+0060)で始まり、グレイブアクセントで終わる生文字列です。解釈済み文字列には、バックスラッシュ(\, U+005C)とそれに続く別の文字で構成されるエスケープシーケンスを含めることができます。エスケープされた引用符(\")は、解釈済み文字列を終了させません。解釈済み文字列の引用符なしの値は、引用符間の文字のシーケンスであり、各エスケープシーケンスはバックスラッシュに続く文字(例: \"は"に、\nはnに置き換えられます)に置き換えられます。対照的に、生文字列の引用符なしの値は、グレイブアクセント間の文字のシーケンスにすぎません。バックスラッシュは生文字列内で特別な意味を持ちません。
識別子と文字列は、go.mod文法では互換性があります。
モジュールパスとバージョン
go.modファイル内のほとんどの識別子と文字列は、モジュールパスまたはバージョンのいずれかです。
モジュールパスは、次の要件を満たす必要があります。
- パスは、スラッシュ(
/, U+002F)で区切られた1つ以上のパス要素で構成される必要があります。スラッシュで始まったり終わったりしてはなりません。 - 各パス要素は、ASCII文字、ASCII数字、および限られたASCII句読点(
-、.、_、および~)で構成される空でない文字列です。 - パス要素はドット(
.、U+002E)で始まったり終わったりしてはなりません。 - 最初のドットまでの要素プレフィックスは、大文字小文字に関わらず、Windowsで予約されているファイル名(
CON、com1、NuLなど)であってはなりません。 - 最初のドットまでの要素プレフィックスは、チルダとそれに続く1桁以上の数字で終わってはなりません(
EXAMPL~1.COMなど)。
モジュールパスがrequireディレクティブに表示され、置き換えられていない場合、またはモジュールパスがreplaceディレクティブの右側に表示される場合、goコマンドは、そのパスを持つモジュールをダウンロードする必要がある場合があります。その場合、いくつかの追加要件を満たす必要があります。
- 先頭のパス要素(最初のスラッシュまで、もしあれば)、慣例としてドメイン名ですが、小文字のASCII文字、ASCII数字、ドット(
.、U+002E)、およびハイフン(-、U+002D)のみを含まなければなりません。少なくとも1つのドットを含み、ハイフンで始めることはできません。 - 形式が
/vNの最終パス要素で、Nが数字に見える場合(ASCII数字とドット)、Nは先頭にゼロがあってはならず、/v1であってはならず、ドットを含んではなりません。gopkg.in/で始まるパスの場合、この要件は、パスがgopkg.inサービスの慣習に従うという要件に置き換えられます。
go.modファイル内のバージョンは、正規バージョンまたは非正規バージョンのいずれかです。
正規バージョンは文字vで始まり、その後Semantic Versioning 2.0.0仕様に従ったセマンティックバージョンが続きます。詳細については「バージョン」を参照してください。
他のほとんどの識別子と文字列は、非正規バージョンとして使用できますが、ファイルシステム、リポジトリ、およびモジュールプロキシとの問題を避けるために、いくつかの制限があります。非正規バージョンは、メインモジュールのgo.modファイルでのみ許可されます。goコマンドは、go.modファイルを自動的に更新する際に、各非正規バージョンを同等の正規バージョンに置き換えようとします。
モジュールパスがバージョンと関連付けられている場所(require、replace、excludeディレクティブなど)では、最終パス要素がバージョンと一致する必要があります。「メジャーバージョンサフィックス」を参照してください。
文法
go.mod構文は、以下に拡張バッカス・ナウア記法 (EBNF) を使用して指定されています。EBNF構文の詳細については、Go言語仕様のNotationセクションを参照してください。
GoMod = { Directive } .
Directive = ModuleDirective |
GoDirective |
ToolDirective |
IgnoreDirective |
RequireDirective |
ExcludeDirective |
ReplaceDirective |
RetractDirective .
改行、識別子、文字列はそれぞれnewline、ident、stringで示されます。
モジュールパスとバージョンは、ModulePathとVersionで示されます。
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.14、1.21rc1、または1.23.0のような有効なGoバージョンでなければなりません。
goディレクティブは、このモジュールを使用するために必要なGoの最小バージョンを設定します。Go 1.21より前は、このディレクティブは助言的なものにすぎませんでしたが、現在は必須の要件となっています。Goツールチェーンは、新しいGoバージョンを宣言するモジュールの使用を拒否します。
goディレクティブは、実行するGoツールチェーンを選択するための入力となります。詳細は「Goツールチェーン」を参照してください。
goディレクティブは、新しい言語機能の使用に影響を与えます。
- モジュール内のパッケージの場合、コンパイラは
goディレクティブで指定されたバージョンより後に導入された言語機能の使用を拒否します。たとえば、モジュールがgo 1.12ディレクティブを持つ場合、そのパッケージはGo 1.13で導入された1_000_000のような数値リテラルを使用できません。 - 古いGoバージョンがモジュールのパッケージの1つをビルドし、コンパイルエラーが発生した場合、エラーはモジュールが新しいGoバージョン用に書かれていることを示します。たとえば、モジュールが
go 1.13を持ち、パッケージが数値リテラル1_000_000を使用しているとします。そのパッケージがGo 1.12でビルドされる場合、コンパイラはコードがGo 1.13用に書かれていることを示します。
goディレクティブは、goコマンドの動作にも影響を与えます。
go 1.14以上では、自動ベンダー化が有効になる場合があります。vendor/modules.txtファイルが存在し、go.modと整合している場合、明示的に-mod=vendorフラグを使用する必要はありません。go 1.16以上では、allパッケージパターンは、メインモジュール内のパッケージおよびテストによって推移的にインポートされたパッケージのみに一致します。これは、モジュールが導入されて以来、go mod vendorによって保持されているパッケージセットと同じです。それより低いバージョンでは、allには、メインモジュール内のパッケージによってインポートされたパッケージのテスト、それらのパッケージのテストなども含まれます。go 1.17以上の場合go.modファイルには、メインモジュール内のパッケージまたはテストによって推移的にインポートされたパッケージを提供する各モジュールに対して明示的なrequireディレクティブが含まれています。(go 1.16以下では、間接依存関係は、最小バージョン選択が別のバージョンを選択する場合にのみ含まれます。)この追加情報により、モジュールグラフの剪定と遅延モジュール読み込みが可能になります。- 以前の
goバージョンよりも// indirect依存関係がはるかに多くなる可能性があるため、間接依存関係はgo.modファイルの別のブロックに記録されます。 go mod vendorは、ベンダー依存関係のgo.modおよびgo.sumファイルを省略します。(これにより、vendorのサブディレクトリ内でgoコマンドを呼び出す際に、正しいメインモジュールを識別できます)。go mod vendorは、各依存関係のgo.modファイルからのgoバージョンをvendor/modules.txtに記録します。
go 1.21以降の場合go行は、このモジュールで使用するために必要なGoの最小バージョンを宣言します。go行は、すべての依存関係のgo行以上である必要があります。goコマンドは、以前の古いGoバージョンとの互換性を維持しようとしなくなりました。goコマンドは、go.modファイルのチェックサムをgo.sumファイルに保持することに、より注意を払うようになりました。
go.modファイルには、最大1つのgoディレクティブを含めることができます。ほとんどのコマンドは、goディレクティブが存在しない場合、現在のGoバージョンでgoディレクティブを追加します。
goディレクティブが見つからない場合、go 1.16が仮定されます。
GoDirective = "go" GoVersion newline .
GoVersion = string | ident . /* valid release version; see above */
例
go 1.23.0
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
)
toolディレクティブ
toolディレクティブは、パッケージを現在のモジュールの依存関係として追加します。また、現在の作業ディレクトリがこのモジュール内、またはこのモジュールを含むワークスペース内にある場合に、go toolで実行できるようにします。
ツールパッケージが現在のモジュールにない場合、使用するツールのバージョンを指定するrequireディレクティブが存在する必要があります。
toolメタパターンは、現在のモジュールのgo.modで定義されているツールのリスト、またはワークスペースモードでは、ワークスペース内のすべてのモジュールで定義されているすべてのツールの結合に解決されます。
ToolDirective = "tool" ( ToolSpec | "(" newline { ToolSpec } ")" newline ) .
ToolSpec = ModulePath newline .
例
tool golang.org/x/tools/cmd/stringer
tool (
example.com/module/cmd/a
example.com/module/cmd/b
)
ignoreディレクティブ
ignoreディレクティブは、パッケージパターンに一致させる際、goコマンドがスラッシュで区切られたディレクトリパス、およびそれらに再帰的に含まれるすべてのファイルまたはディレクトリを無視するようにします。
パスが./で始まる場合、パスはモジュールルートディレクトリに対する相対パスとして解釈され、そのディレクトリおよびそれに再帰的に含まれるすべてのディレクトリまたはファイルは、パッケージパターンに一致させる際に無視されます。
それ以外の場合、モジュール内の任意の深さでそのパスを持つすべてのディレクトリ、およびそれらに再帰的に含まれるすべてのディレクトリまたはファイルは無視されます。
IgnoreDirective = "ignore" ( IgnoreSpec | "(" newline { IgnoreSpec } ")" newline ) .
IgnoreSpec = RelativeFilePath newline .
RelativeFilePath = /* slash-separated relative file path */ .
例
ignore ./node_modules
ignore (
static
content/html
./third_party/javascript
)
excludeディレクティブ
excludeディレクティブは、モジュールバージョンがgoコマンドによってロードされるのを防ぎます。
Go 1.16 以降では、いずれかのgo.modファイルのrequireディレクティブによって参照されるバージョンが、メインモジュールのgo.modファイルのexcludeディレクティブによって除外されると、その要件は無視されます。これにより、go getやgo mod tidyのようなコマンドが、より高いバージョンへの新しい要件をgo.modに追加し、必要に応じて// indirectコメントを付ける可能性があります。
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 get、go mod tidy、またはその他のコマンドを使用して自動的にそのバージョンにアップグレードしません。取り下げられたバージョンに依存するビルドは引き続き機能しますが、ユーザーがgo list -m -uで更新をチェックしたり、go getで関連モジュールを更新したりすると、取り下げについて通知されます。
バージョンを取り下げるには、モジュール作成者はretractディレクティブをgo.modに追加し、そのディレクティブを含む新しいバージョンを公開する必要があります。新しいバージョンは、他のリリースバージョンまたはプレリリースバージョンよりも高い必要があります。つまり、@latestバージョンクエリは、取り下げが考慮される前に新しいバージョンに解決される必要があります。goコマンドは、go list -m -retracted $modpath@latest(ここで$modpathはモジュールパス)によって示されるバージョンから取り下げをロードして適用します。
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.0とv1.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 .
例
v1.0.0からv1.9.9までのすべてのバージョンを取り下げる
retract v1.0.0
retract [v1.0.0, v1.9.9]
retract (
v1.0.0
[v1.0.0, v1.9.9]
)
- 時期尚早にバージョン
v1.0.0をリリースした後、バージョン管理なしに戻す
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 getおよびgo mod tidyコマンドを使用して、これらの問題のほとんどを修正できます。さらに、ほとんどのモジュール対応コマンド(go build、go testなど)で-mod=modフラグを使用して、goコマンドにgo.modとgo.sumの問題を自動的に修正するよう指示できます。
たとえば、次のgo.modファイルを考えてみましょう。
module example.com/M
go 1.23.0
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でトリガーされる更新は、非正規のバージョン識別子を正規のセマンティックバージョン形式に書き換えます。したがって、example.com/Aのv1はv1.0.0になり、example.com/Eのdevは、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.0とexample.com/C v1.0.0を必要とする場合、go.modのexample.com/B v1.0.0に対する要件は誤解を招く(example.com/Aがv1.2.0を必要とすることによって上書きされる)ため、削除されます。また、example.com/C v1.0.0に対する要件は冗長(example.com/Aが同じバージョンを必要とすることによって暗示される)ため、これも削除されます。メインモジュールにexample.com/Bまたはexample.com/Cのパッケージを直接インポートするパッケージが含まれている場合、要件は維持されますが、実際に使用されているバージョンに更新されます。
最後に、この更新はgo.modを正規の書式設定で再フォーマットし、将来の機械的な変更が最小限の差分になるようにします。goコマンドは、書式設定の変更のみが必要な場合はgo.modを更新しません。
モジュールグラフが import ステートメントの意味を定義するため、パッケージをロードするコマンドはすべてgo.modを使用し、したがってgo build、go get、go install、go list、go test、go mod tidyなどのコマンドもgo.modを更新できます。
Go 1.15以下では、-mod=modフラグがデフォルトで有効になっていたため、更新は自動的に実行されていました。Go 1.16以降、goコマンドは-mod=readonlyが設定されているかのように動作します。go.modに変更が必要な場合、goコマンドはエラーを報告し、修正を提案します。
最小バージョン選択 (MVS)
Goは、パッケージをビルドする際に使用するモジュールバージョンのセットを選択するために、最小バージョン選択 (MVS)と呼ばれるアルゴリズムを使用します。MVSについては、Russ Coxによる「Minimal Version Selection」で詳細に説明されています。
概念的には、MVS はgo.mod ファイルで指定された、モジュールの有向グラフ上で動作します。グラフ内の各頂点はモジュールバージョンを表します。各エッジは、require ディレクティブを使用して指定された、依存関係の最小必須バージョンを表します。グラフは、メインモジュールのgo.modファイル内のexclude および replace ディレクティブ、および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を必要とします。
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を含むビルドリストを返します。
除外
モジュールは、メインモジュールのgo.modファイル内のexcludeディレクティブを使用して、特定のバージョンで除外することもできます。
除外もモジュールグラフを変更します。バージョンが除外されると、モジュールグラフから削除され、そのバージョンに対する要件は次の上位バージョンにリダイレクトされます。
以下の例を考えてみましょう。C 1.3 が除外されました。MVS は、A 1.2 が C 1.3 の代わりに C 1.4 (次に高いバージョン) を要求したかのように動作します。
アップグレード
go getコマンドは、一連のモジュールをアップグレードするために使用できます。アップグレードを実行するために、goコマンドは、MVSを実行する前に、訪問したバージョンからアップグレードされたバージョンへのエッジを追加することで、モジュールグラフを変更します。
以下の例を考えてみましょう。モジュールBは1.2から1.3に、Cは1.3から1.4に、Dは1.2から1.3にアップグレードされる可能性があります。
アップグレード(およびダウングレード)は、間接依存関係を追加または削除する可能性があります。この場合、E 1.1はB 1.3によって必要とされるため、アップグレード後にE 1.1とF 1.1がビルドリストに表示されます。
アップグレードを保持するために、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に変更されます。
go getは、引数の後に@noneサフィックスを使用することで、依存関係を完全に削除することもできます。これはダウングレードと同様に機能します。指定されたモジュールのすべてのバージョンがモジュールグラフから削除されます。
モジュールグラフの剪定
メインモジュールがgo 1.17以上の場合、最小バージョン選択に使用されるモジュールグラフには、自身のgo.modファイルでgo 1.17以上を指定している各モジュール依存関係の直接の要件のみが含まれます。ただし、そのモジュールのバージョンが、go 1.16以下の他の依存関係によっても(推移的に)必要とされている場合は除きます。(go 1.17依存関係の推移的な依存関係は、モジュールグラフから剪定されます)。
go 1.17のgo.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.16以下を指定する各モジュールについては、推移的なgo 1.17依存関係を含む完全な推移的閉包が引き続き含まれます。(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ファイルのみを読み込み、その後、それらの要件のみを使用してビルドするパッケージを読み込もうとします。インポートされるパッケージ(たとえば、メインモジュール以外のパッケージのテストの依存関係)がそれらの要件の中に見つからない場合、モジュールグラフの残りの部分はオンデマンドで読み込まれます。
モジュールグラフをロードせずにすべてのインポートパッケージが見つかる場合、goコマンドは、それらのパッケージを含むモジュールのgo.modファイルのみをロードし、それらの要件がメインモジュールの要件とローカルで一貫していることを確認します。(不整合は、バージョン管理のマージ、手動編集、およびローカルファイルシステムパスを使用して置き換えられたモジュールの変更によって発生する可能性があります。)
ワークスペース
ワークスペースは、最小バージョン選択 (MVS) の実行時にメインモジュールとして使用される、ディスク上のモジュールの集合です。
ワークスペースは、ワークスペース内の各モジュールのモジュールディレクトリへの相対パスを指定するgo.workファイルで宣言できます。go.workファイルが存在しない場合、ワークスペースは現在のディレクトリを含む単一のモジュールで構成されます。
モジュールを操作するほとんどのgoサブコマンドは、現在のワークスペースによって決定されるモジュールセットに対して動作します。go mod init、go mod why、go mod edit、go mod tidy、go mod vendor、およびgo getは常に単一のメインモジュールに対して動作します。
コマンドは、GOWORK環境変数を最初に調べて、ワークスペースコンテキストにあるかどうかを判断します。GOWORKがoffに設定されている場合、コマンドはシングルモジュールコンテキストになります。空であるか、提供されていない場合、コマンドは現在の作業ディレクトリ、次に親ディレクトリを順に検索してgo.workファイルを探します。ファイルが見つかった場合、コマンドはそのファイルで定義されたワークスペースで動作します。それ以外の場合、ワークスペースには作業ディレクトリを含むモジュールのみが含まれます。GOWORKが.workで終わる既存のファイルへのパスを指す場合、ワークスペースモードが有効になります。その他の値はエラーです。go env GOWORKコマンドを使用して、goコマンドがどのgo.workファイルを使用しているかを判断できます。goコマンドがワークスペースモードでない場合、go env GOWORKは空になります。
go.workファイル
ワークスペースは、go.workという名前のUTF-8エンコードされたテキストファイルによって定義されます。go.workファイルは行指向です。各行は、キーワードとそれに続く引数で構成される単一のディレクティブを保持します。例えば
go 1.23.0
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ファイルを維持します。
go.workファイルをバージョン管理システムにコミットすることは、一般的に推奨されません。理由は2つあります。
- チェックインされた
go.workファイルは、開発者自身の親ディレクトリからのgo.workファイルを上書きし、useディレクティブが適用されない場合に混乱を引き起こす可能性があります。 - チェックインされた
go.workファイルは、継続的インテグレーション (CI) システムに誤ったバージョンのモジュール依存関係を選択させ、したがってテストさせる可能性があります。CIシステムは通常、go.workファイルを使用することを許可すべきではありません。そうすることで、モジュールが他のモジュールによって必要とされた場合(モジュール内のgo.workファイルは効果がない)のモジュールの動作をテストできます。
とはいえ、go.workファイルをコミットすることが理にかなっているケースもあります。たとえば、リポジトリ内のモジュールが排他的に相互に開発され、外部モジュールと同時に開発されない場合、開発者がワークスペースで異なるモジュールの組み合わせを使用したい理由はないかもしれません。その場合、モジュール作者は個々のモジュールが適切にテストされ、リリースされることを確認する必要があります。
字句要素
go.workファイル内の字句要素は、go.modファイルと同じ方法で定義されます。
文法
go.work構文は、以下に拡張バッカス・ナウア記法 (EBNF) を使用して指定されています。EBNF構文の詳細については、Go言語仕様のNotationセクションを参照してください。
GoWork = { Directive } .
Directive = GoDirective |
ToolchainDirective |
UseDirective |
ReplaceDirective .
改行、識別子、文字列はそれぞれnewline、ident、stringで示されます。
モジュールパスとバージョンは、ModulePathとVersionで示されます。モジュールパスとバージョンは、go.modファイルとまったく同じ方法で指定されます。
ModulePath = ident | string . /* see restrictions above */
Version = ident | string . /* see restrictions above */
goディレクティブ
有効なgo.workファイルにはgoディレクティブが必須です。バージョンは有効なGoリリースバージョンである必要があります。つまり、正の整数にドットと非負の整数が続く形式です(例: 1.18、1.19)。
goディレクティブは、go.workファイルが動作することを意図しているgoツールチェーンのバージョンを示します。go.workファイル形式が変更された場合、将来のツールチェーンバージョンは、示されたバージョンに従ってファイルを解釈します。
go.workファイルには、最大1つのgoディレクティブを含めることができます。
GoDirective = "go" GoVersion newline .
GoVersion = string | ident . /* valid release version; see above */
例
go 1.23.0
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ディレクティブは、引数ディレクトリのサブディレクトリに含まれるモジュールを追加しません。それらのモジュールは、go.modファイルを含むディレクトリによって別のuseディレクティブで追加される場合があります。
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 モードでインポートパスがディレクトリに解決されると、以下のようになります。
$modpath/$vn/$dirの形式のインポートを解決する場合$modpathは有効なモジュールパスです。$vnはメジャーバージョンサフィックスです。$dirは空である可能性のあるサブディレクトリです。
- 以下のすべてが真である場合
- パッケージ
$modpath/$vn/$dirは、関連するいずれのvendorディレクトリ にも存在しない。 go.modファイルがインポートするファイルと同じディレクトリ、または$GOPATH/srcのルートまでの親ディレクトリに存在する。$GOPATH[i]/src/$modpath/$vn/$suffixディレクトリは存在しない(いずれのルート$GOPATH[i]についても)。- ファイル
$GOPATH[d]/src/$modpath/go.modが存在し(あるルート$GOPATH[d]について)、モジュールパスを$modpath/$vnとして宣言している場合、
- パッケージ
- その場合、
$modpath/$vn/$dirのインポートはディレクトリ$GOPATH[d]/src/$modpath/$dirに解決されます。
このルールにより、メジャーバージョンのサブディレクトリを使用していない場合でも、モジュールに移行されたパッケージが GOPATH モードでビルドされたときに、モジュールに移行された他のパッケージをインポートできるようになります。
モジュール対応コマンド
ほとんどの go コマンドは、モジュール対応モードまたはGOPATH モードで実行できます。モジュール対応モードでは、go コマンドは go.mod ファイルを使用してバージョン管理された依存関係を見つけ、通常は モジュールキャッシュ からパッケージをロードし、不足している場合はモジュールをダウンロードします。GOPATH モードでは、go コマンドはモジュールを無視します。依存関係を見つけるために vendor ディレクトリ と GOPATH を参照します。
Go 1.16 以降、go.mod ファイルの有無にかかわらず、モジュール対応モードがデフォルトで有効になっています。それ以前のバージョンでは、現在のディレクトリまたは親ディレクトリに go.mod ファイルが存在する場合にモジュール対応モードが有効になっていました。
モジュール対応モードは、on、off、または auto に設定できる GO111MODULE 環境変数で制御できます。
GO111MODULE=offの場合、goコマンドはgo.modファイルを無視し、GOPATHモードで実行されます。GO111MODULE=onまたは未設定の場合、goコマンドはgo.modファイルが存在しない場合でもモジュール対応モードで実行されます。ただし、すべてのコマンドがgo.modファイルなしで機能するわけではありません。モジュール外のモジュールコマンド を参照してください。GO111MODULE=autoの場合、現在のディレクトリまたは任意の親ディレクトリにgo.modファイルが存在する場合、goコマンドはモジュール対応モードで実行されます。Go 1.15 以前では、これがデフォルトの動作でした。go modサブコマンドおよび バージョンクエリ を含むgo installは、go.modファイルが存在しない場合でもモジュール対応モードで実行されます。
モジュール対応モードでは、GOPATH はビルド時のインポートの意味を定義しなくなりましたが、ダウンロードされた依存関係 (GOPATH/pkg/mod; モジュールキャッシュ を参照) およびインストールされたコマンド (GOBIN が設定されていない場合は GOPATH/bin) は引き続き保存します。
ビルドコマンド
パッケージに関する情報をロードするすべてのコマンドはモジュール対応です。これには以下が含まれます。
go buildgo fixgo generatego installgo listgo rungo testgo vet
モジュール対応モードで実行されると、これらのコマンドは go.mod ファイルを使用して、コマンドラインにリストされている、または Go ソースファイルに記述されているインポートパスを解釈します。これらのコマンドは、すべてのモジュールコマンドに共通する以下のフラグを受け入れます。
-modフラグは、go.modが自動的に更新されるかどうか、およびvendorディレクトリが使用されるかどうかを制御します。-mod=modは、ベンダーディレクトリを無視し、インポートされたパッケージが既知のモジュールによって提供されない場合など、go.modを自動的に更新するようにgoコマンドに指示します。-mod=readonlyは、goコマンドにvendorディレクトリを無視し、go.modの更新が必要な場合にエラーを報告するよう指示します。-mod=vendorはgoコマンドにvendorディレクトリを使用するよう指示します。このモードでは、goコマンドはネットワークやモジュールキャッシュを使用しません。- デフォルトでは、
go.modのgoバージョン が1.14以上でvendorディレクトリが存在する場合、goコマンドは-mod=vendorが使用されたかのように動作します。それ以外の場合、goコマンドは-mod=readonlyが使用されたかのように動作します。 go getはこのフラグを拒否します。コマンドの目的が依存関係を変更することであり、それは-mod=modによってのみ許可されるためです。
-modcacherwフラグは、goコマンドに対し、モジュールキャッシュ内に新しいディレクトリを作成する際に、読み取り専用ではなく読み書き可能なパーミッションを設定するよう指示します。このフラグが一貫して使用される場合(通常、環境変数にGOFLAGS=-modcacherwを設定するか、go env -w GOFLAGS=-modcacherwを実行することによって)、モジュールキャッシュは、最初にパーミッションを変更することなくrm -rのようなコマンドで削除することができます。go clean -modcacheコマンドは、-modcacherwが使用されたかどうかにかかわらず、モジュールキャッシュを削除するために使用できます。-modfile=file.modフラグは、モジュールルートディレクトリ内のgo.modの代わりに、代替ファイルから読み込み(そして場合によっては書き込み)を行うようにgoコマンドに指示します。ファイル名は.modで終わる必要があります。モジュールルートディレクトリを決定するために、go.modというファイルは依然として存在している必要がありますが、アクセスされることはありません。-modfileが指定された場合、代替のgo.sumファイルも使用されます。そのパスは、-modfileフラグから.mod拡張子を削除して.sumを付加することで導出されます。
ベンダー
モジュールを使用する場合、go コマンドは通常、モジュールをそのソースからモジュールキャッシュにダウンロードし、ダウンロードされたコピーからパッケージをロードすることによって依存関係を満たします。ベンダー化は、以前のバージョンの Go との相互運用を可能にするため、またはビルドに使用されるすべてのファイルが単一のファイルツリーに格納されていることを保証するために使用できます。
go mod vendor コマンドは、メインモジュールのルートディレクトリに vendor という名前のディレクトリを作成し、メインモジュール内のパッケージをビルドおよびテストするために必要なすべてのパッケージのコピーを格納します。メインモジュール外のパッケージのテストによってのみインポートされるパッケージは含まれません。go mod tidy や他のモジュールコマンドと同様に、vendor ディレクトリを構築する際には ignore 以外のビルド制約は考慮されません。
go mod vendor は、ベンダー化されたパッケージとそのコピー元のモジュールバージョンをリストしたファイル vendor/modules.txt も作成します。ベンダー化が有効な場合、このマニフェストは、go list -m および go 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 build や go test などのビルドコマンドは、ネットワークやローカルのモジュールキャッシュにアクセスする代わりに、vendor ディレクトリからパッケージをロードします。go list -m コマンドは、go.mod にリストされているモジュールに関する情報のみを出力します。go mod download や go 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)、または特別なクエリ latest、upgrade、patch、none のいずれかを示すことができます。バージョンが指定されない場合、go get は @upgrade クエリを使用します。
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.0 は example.com/b も v1.2.0 にアップグレードします。
コマンドラインで指定されたモジュールがダウングレードまたは削除された場合、他のモジュールもダウングレードされることがあります。上記の例を続けると、モジュール example.com/b が v1.1.0 にダウングレードされたとします。モジュール example.com/a も、example.com/b をバージョン v1.1.0 以下で要求するバージョンにダウングレードされます。
モジュールの要件は、バージョンサフィックス @none を使用して削除できます。これは特別な種類のダウングレードです。削除されたモジュールに依存するモジュールは、必要に応じてダウングレードまたは削除されます。モジュールの要件は、メインモジュール内のパッケージによってそのパッケージの1つ以上がインポートされている場合でも削除できます。この場合、次のビルドコマンドで新しいモジュールの要件が追加される可能性があります。
あるモジュールが2つの異なるバージョンで必要とされる場合(コマンドライン引数で明示的に指定された場合、またはアップグレードとダウングレードを満たすために)、go get はエラーを報告します。
go get が新しいバージョンのセットを選択した後、新しく選択されたモジュールバージョン、またはコマンドラインで指定されたパッケージを提供するモジュールが 取り下げられている か 非推奨である かどうかをチェックします。go get は、見つかった取り下げられたバージョンまたは非推奨のモジュールごとに警告を出力します。すべての依存関係における取り下げと非推奨をチェックするには、go list -m -u all を使用できます。
go get が go.mod ファイルを更新した後、コマンドラインで指定されたパッケージをビルドします。実行可能ファイルは、GOBIN 環境変数で指定されたディレクトリにインストールされます。GOBIN が設定されていない場合、デフォルトは $GOPATH/bin または $HOME/go/bin です。
go get は以下のフラグをサポートしています
-dフラグは、パッケージをビルドまたはインストールしないようgo getに指示します。-dを使用すると、go getはgo.mod内の依存関係のみを管理します。パッケージをビルドおよびインストールするために-dなしでgo getを使用することは非推奨です(Go 1.17 以降)。Go 1.18 では、-dは常に有効になります。-uフラグは、コマンドラインで指定されたパッケージによって直接的または間接的にインポートされたパッケージを提供するモジュールをアップグレードするようにgo getに指示します。-uによって選択された各モジュールは、より高いバージョン(プレリリース)で既に要求されていない限り、最新バージョンにアップグレードされます。-u=patchフラグ(-u patchではない)もgo getに依存関係をアップグレードするよう指示しますが、go getは各依存関係を最新のパッチバージョンにアップグレードします(@patchバージョンクエリに似ています)。-tフラグは、コマンドラインで指定されたパッケージのテストをビルドするために必要なモジュールを考慮するようgo getに指示します。-tと-uが一緒に使用された場合、go getはテスト依存関係も更新します。-insecureフラグはもはや使用すべきではありません。これは、go getがカスタムインポートパスを解決し、HTTP のような安全でないスキームを使用してリポジトリやモジュールプロキシからフェッチすることを許可します。GOINSECURE環境変数 はよりきめ細かい制御を提供し、代わりにこれを使用すべきです。
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 環境変数で指定されたディレクトリにインストールされます。GOBIN が設定されていない場合、デフォルトは $GOPATH/bin または $HOME/go/bin です。$GOROOT 内の実行可能ファイルは、$GOBIN の代わりに $GOROOT/bin または $GOTOOLDIR にインストールされます。実行可能ではないパッケージはビルドおよびキャッシュされますが、インストールはされません。
Go 1.16 以降、引数にバージョンサフィックス(例: @latest または @v1.0.0)がある場合、go install はモジュール対応モードでパッケージをビルドし、現在のディレクトリまたは親ディレクトリに go.mod ファイルが存在してもそれを無視します。これは、メインモジュールの依存関係に影響を与えることなく実行可能ファイルをインストールする場合に便利です。
ビルドで使用されるモジュールのバージョンに関する曖昧さを排除するために、引数は以下の制約を満たす必要があります。
- 引数はパッケージパスまたはパッケージパターン(「
...」ワイルドカードを含む)である必要があります。標準パッケージ(fmtなど)、メタパターン(std、cmd、all、work、tool)、または相対/絶対ファイルパスであってはなりません。 - すべての引数は同じバージョンサフィックスを持っている必要があります。異なるクエリは、同じバージョンを参照している場合でも許可されません。
- すべての引数は、同じモジュール内の同じバージョンのパッケージを参照する必要があります。
- パッケージパス引数は
mainパッケージを参照する必要があります。パターン引数はmainパッケージのみを照合します。 - メインモジュールとみなされるモジュールはありません。
- コマンドラインで指定されたパッケージを含むモジュールが
go.modファイルを持っている場合、それがメインモジュールであった場合に異なる解釈を引き起こすようなディレクティブ(replaceおよびexclude)を含んではなりません。 - モジュールは自分自身のより高いバージョンを必要としてはいけません。
- どのモジュールでもベンダーディレクトリは使用されません。(ベンダーディレクトリは モジュール zip ファイル に含まれないため、
go installはそれらをダウンロードしません。)
- コマンドラインで指定されたパッケージを含むモジュールが
サポートされているバージョンクエリ構文については、バージョンクエリ を参照してください。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 が nil でない場合、Dir は Replace.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 フラグは、list に対して、-versions フラグで出力されるリストに撤回されたバージョンを表示し、バージョンクエリ を解決する際に撤回されたバージョンを考慮するよう指示します。例えば、go list -m -retracted example.com/m@latest は、モジュール example.com/m の最も高いリリースバージョンまたはプレリリースバージョンを表示します。そのバージョンが撤回されていても同様です。retract ディレクティブ と 非推奨 は、このバージョンの go.mod ファイルからロードされます。-retracted フラグは Go 1.16 で追加されました。
テンプレート関数 module は、モジュールパスまたはクエリでなければならない単一の文字列引数を受け取り、指定されたモジュールを Module 構造体として返します。エラーが発生した場合、結果は非 nil の Error フィールドを持つ 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 フラグは、ダウンロードされた各モジュール(または失敗)を記述する 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 フラグを指定すると、download は実行されるコマンドを標準エラーに出力します。
-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 ファイルを読み書きしますが、編集フラグの後に別のターゲットファイルを指定できます。
編集フラグは、一連の編集操作を指定します。
-moduleフラグは、モジュールのパス(go.modファイルのモジュール行)を変更します。-go=versionフラグは、想定される Go 言語バージョンを設定します。-require=path@versionおよび-droprequire=pathフラグは、指定されたモジュールパスとバージョンの要件を追加または削除します。-requireはpathの既存の要件を上書きすることに注意してください。これらのフラグは主にモジュールグラフを理解するツール向けです。ユーザーは、他のモジュールによって課される制約を満たすために必要に応じて他のgo.mod調整を行うgo get path@versionまたはgo get path@noneを優先すべきです。go getを参照してください。-exclude=path@versionと-dropexclude=path@versionフラグは、指定されたモジュールパスとバージョンの除外を追加および削除します。-exclude=path@versionは、その除外が既に存在する場合は何もしないことに注意してください。-replace=old[@v]=new[@v]フラグは、指定されたモジュールパスとバージョンのペアの置換を追加します。old@vの@vを省略すると、左側にバージョンがない置換が追加され、これは古いモジュールパスのすべてのバージョンに適用されます。new@vの@vを省略すると、新しいパスはモジュールパスではなくローカルのモジュールルートディレクトリでなければなりません。-replaceはold[@v]の冗長な置換を上書きするため、@vを省略すると特定のバージョンの置換が削除されることに注意してください。-dropreplace=old[@v]フラグは、指定されたモジュールパスとバージョンのペアの置換を削除します。@vが提供されている場合、指定されたバージョンの置換が削除されます。左側にバージョンがない既存の置換は、引き続きモジュールを置換する可能性があります。@vが省略されている場合、バージョンがない置換が削除されます。-retract=versionと-dropretract=versionフラグは、指定されたバージョンの取り消しを追加および削除します。バージョンは単一のバージョン(例:v1.2.3)または区間(例:[v1.1.0,v1.2.0])のいずれかです。-retractフラグではretractディレクティブの理由コメントを追加できないことに注意してください。理由コメントは推奨されており、go list -m -uおよびその他のコマンドで表示される場合があります。-tool=pathと-droptool=pathフラグは、指定されたパスにtoolディレクティブを追加および削除します。これにより、ビルドグラフに必要な依存関係が追加されることはありません。ツールを追加するにはgo get -tool pathを、削除するにはgo get -tool path@noneを使用することを推奨します。
編集フラグは繰り返すことができます。変更は指定された順序で適用されます。
go mod edit には、その出力を制御する追加のフラグがあります。
-fmtフラグは、他の変更を行わずにgo.modファイルを再フォーマットします。この再フォーマットは、go.modファイルを使用または書き換える他の変更によっても暗黙的に行われます。このフラグが必要になるのは、go mod edit -fmtのように他のフラグが指定されていない場合のみです。-printフラグは、最終的なgo.modをテキスト形式でディスクに書き戻すのではなく、そのテキスト形式で出力します。-jsonフラグは、最終的なgo.modをテキスト形式でディスクに書き戻すのではなく、JSON 形式で出力します。JSON 出力は以下の Go 型に対応します。
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
}
type Tool struct {
Path string
}
これは go.mod ファイル自体を記述するだけであり、間接的に参照される他のモジュールは記述しないことに注意してください。ビルドに利用可能なモジュールの完全なセットについては、go list -m -json all を使用してください。go list -m を参照してください。
例えば、ツールは go mod edit -json の出力を解析して go.mod ファイルをデータ構造として取得し、その後 go mod edit を -require、-exclude などと共に呼び出すことで変更を加えることができます。
ツールは、パッケージ 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行に1つずつ出力します。各行は2つのスペース区切りフィールドを持ちます。モジュールバージョンとその依存関係の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 内の場合)を使用してモジュールパスを推測しようとします。
go mod tidy
使い方
go mod tidy [-e] [-v] [-x] [-diff] [-go=version] [-compat=version]
go mod tidy は、go.mod ファイルがモジュール内のソースコードと一致していることを保証します。現在のモジュールのパッケージと依存関係をビルドするために必要な不足しているモジュール要件を追加し、関連するパッケージを提供しないモジュールの要件を削除します。また、不足しているエントリを go.sum に追加し、不要なエントリを削除します。
-e フラグ(Go 1.16 で追加)は、パッケージのロード中に発生したエラーにもかかわらず、go mod tidy が処理を続行しようとさせます。
-v フラグを指定すると、go mod tidy は削除されたモジュールに関する情報を標準エラーに出力します。
-x フラグを指定すると、go mod tidy は tidy が実行するコマンドを出力します。
-diff フラグを指定すると、go mod tidy は go.mod または go.sum を変更せず、代わりに必要な変更を統合された差分として出力します。差分が空でない場合、非ゼロのコードで終了します。
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 コメントは、メインモジュール内のパッケージによってインポートされるパッケージを提供しないモジュールを示します(// indirect 依存関係とコメントが追加される時期の詳細については、require ディレクティブ を参照してください)。
-go フラグが設定されている場合、go mod tidy は go ディレクティブ を指定されたバージョンに更新し、そのバージョンに応じて モジュールグラフの剪定 および 遅延モジュールロード を有効または無効にします(必要に応じて間接要件を追加または削除します)。
デフォルトでは、go mod tidy は、go ディレクティブで示されたバージョンの直前の Go バージョンでモジュールグラフがロードされたときに、モジュールの選択されたバージョンが変更されないことをチェックします。互換性のためにチェックされるバージョンは、-compat フラグによって明示的に指定することもできます。
go mod vendor
使い方
go mod vendor [-e] [-v] [-o]
go mod vendor コマンドは、メインモジュールのルートディレクトリに vendor という名前のディレクトリを構築し、メインモジュール内のパッケージのビルドとテストをサポートするために必要なすべてのパッケージのコピーを格納します。メインモジュール外のパッケージのテストによってのみインポートされるパッケージは含まれません。go mod tidy や他のモジュールコマンドと同様に、vendor ディレクトリを構築する際には ignore 以外のビルド制約は考慮されません。
ベンダー化が有効な場合、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 ディレクトリを再構築する前に削除することに注意してください。ベンダー化されたパッケージにローカルな変更を加えるべきではありません。go コマンドは vendor ディレクトリ内のパッケージが変更されていないことをチェックしませんが、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 は「all modules verified」と出力します。それ以外の場合、変更されたモジュールを報告し、非ゼロのステータスで終了します。
すべてのモジュール対応コマンドは、メインモジュールの 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つのスタンザからなるシーケンスで、空行で区切られます。各スタンザは、ターゲットパッケージまたはモジュールを示す # で始まるコメント行で始まります。後続の行は、インポートグラフを通るパスを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 why は go mod graph によって出力されるモジュールグラフではなく、パッケージグラフをクエリすることに注意してください。
-vendor フラグは、go mod why に、メインモジュール外のパッケージのテストにおけるインポートを無視するように指示します(go mod vendor と同様)。デフォルトでは、go mod why は all パターンに一致するパッケージのグラフを考慮します。このフラグは、go.mod の go ディレクティブ を使用して go 1.16 以降を宣言するモジュールでは、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 から取得できます。
テーブル内の各行の意味は、最初の列の単語によって決定されます。
path: 実行可能ファイルのビルドに使用されたmainパッケージのパス。mod:mainパッケージを含むモジュール。列はそれぞれモジュールパス、バージョン、合計です。メインモジュール はバージョン(devel)を持ち、合計はありません。dep: 実行可能ファイルにリンクされた1つ以上のパッケージを提供したモジュール。modと同じ形式です。=>: 前の行のモジュールの 置換。置換がローカルディレクトリの場合、ディレクトリパスのみがリストされます(バージョンや合計はありません)。置換がモジュールバージョンの場合、パス、バージョン、合計がmodおよびdepと同様にリストされます。置換されたモジュールには合計はありません。
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
バージョンクエリは以下のいずれかです。
v1.2.3のような完全指定のセマンティックバージョン。特定のバージョンを選択します。構文については バージョン を参照してください。v1やv1.2のようなセマンティックバージョンのプレフィックス。そのプレフィックスを持つ最も新しい利用可能なバージョンを選択します。や >=v1.5.6のようなセマンティックバージョンの比較。比較ターゲットに最も近い利用可能なバージョンを選択します(>と>=の場合は最も低いバージョン、<と<=の場合は最も高いバージョン)。- 基になるソースリポジトリのリビジョン識別子。コミットハッシュプレフィックス、リビジョンタグ、またはブランチ名など。リビジョンがセマンティックバージョンでタグ付けされている場合、このクエリはそのバージョンを選択します。それ以外の場合、このクエリは基になるコミットの 疑似バージョン を選択します。他のバージョンクエリと一致する名前のブランチとタグは、この方法では選択できないことに注意してください。例えば、クエリ
v2は、v2という名前のブランチではなく、v2で始まる最新バージョンを選択します。 - 文字列
latest。利用可能な最新のリリースバージョンを選択します。リリースバージョンがない場合、latestは最新のプレリリースバージョンを選択します。タグ付けされたバージョンがない場合、latestはリポジトリのデフォルトブランチの先端にあるコミットの疑似バージョンを選択します。 - 文字列
upgrade。latestと似ていますが、モジュールが現在latestが選択するバージョンよりも高いバージョン(例えば、プレリリース)で要求されている場合、upgradeは現在のバージョンを選択します。 - 文字列
patch。現在要求されているバージョンと同じメジャーおよびマイナーバージョン番号を持つ、利用可能な最新バージョンを選択します。現在バージョンが要求されていない場合、patchはlatestと同等です。Go 1.16 以降、go getはpatchを使用する際に現在のバージョンを要求します(ただし、-u=patchフラグはこの要件を持ちません)。
特定の名前付きバージョンまたはリビジョンに対するクエリを除き、すべてのクエリは go list -m -versions によって報告される利用可能なバージョンを考慮します(go list -m を参照)。このリストには、疑似バージョンではなく、タグ付けされたバージョンのみが含まれます。メインモジュールの go.mod ファイル の exclude ディレクティブ によって許可されないモジュールバージョンは考慮されません。同じモジュールの latest バージョンの go.mod ファイルの retract ディレクティブ でカバーされているバージョンも、go list -m で -retracted フラグが使用されている場合と、retract ディレクティブをロードする場合を除き、無視されます。
リリースバージョン はプレリリースバージョンよりも優先されます。例えば、バージョン v1.2.2 と v1.2.3-pre が利用可能な場合、latest クエリは v1.2.2 を選択します。v1.2.3-pre の方が高いにもかかわらずです。v1.2.2 を選択します。v1.2.3-pre が v1.2.4 に近いにもかかわらずです。リリースバージョンまたはプレリリースバージョンが利用できない場合、latest、upgrade、および patch クエリは、リポジトリのデフォルトブランチの先端にあるコミットの疑似バージョンを選択します。他のクエリはエラーを報告します。
モジュール外のモジュールコマンド
モジュール対応の Go コマンドは通常、作業ディレクトリまたは親ディレクトリの go.mod ファイルによって定義された メインモジュール のコンテキストで実行されます。一部のコマンドは go.mod ファイルなしでモジュール対応モードで実行できますが、ほとんどのコマンドは go.mod ファイルが存在しない場合、動作が異なったり、エラーを報告したりします。
モジュール対応モードの有効化と無効化については、モジュール対応コマンド を参照してください。
| コマンド | 動作 |
|---|---|
go buildgo docgo fixgo fmtgo generatego installgo listgo rungo testgo vet
|
標準ライブラリ内のパッケージと、コマンドラインで .go ファイルとして指定されたパッケージのみをロード、インポート、ビルドできます。他のモジュールからのパッケージは、モジュール要件を記録し、決定論的なビルドを保証する場所がないため、ビルドできません。 |
go get |
パッケージと実行可能ファイルは通常どおりビルドおよびインストールできます。go get が go.mod ファイルなしで実行される場合、メインモジュールは存在しないため、replace および exclude ディレクティブは適用されないことに注意してください。 |
go list -m |
ほとんどの引数では明示的な バージョンクエリ が必要ですが、-versions フラグが使用される場合は除きます。 |
go mod download |
ほとんどの引数では明示的な バージョンクエリ が必要です。 |
go mod edit |
明示的なファイル引数が必要です。 |
go mod graphgo mod tidygo mod vendorgo mod verifygo 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 ファイルを探します。
編集フラグは、一連の編集操作を指定します。
-fmtフラグは、他の変更を行わずに go.work ファイルを再フォーマットします。この再フォーマットは、go.work ファイルを使用または書き換える他の変更によっても暗黙的に行われます。このフラグが必要になるのは、go work edit -fmtのように他のフラグが指定されていない場合のみです。-use=pathと-dropuse=pathフラグは、go.workファイルのモジュールディレクトリのセットから use ディレクティブを追加および削除します。-replace=old[@v]=new[@v]フラグは、指定されたモジュールパスとバージョンのペアの置換を追加します。old@vの@vが省略された場合、左側にバージョンがない置換が追加され、これは古いモジュールパスのすべてのバージョンに適用されます。new@vの@vが省略された場合、新しいパスはモジュールパスではなくローカルのモジュールルートディレクトリでなければなりません。-replaceはold[@v]の冗長な置換を上書きするため、@vを省略すると特定のバージョンの既存の置換が削除されることに注意してください。-dropreplace=old[@v]フラグは、指定されたモジュールパスとバージョンのペアの置換を削除します。@vが省略された場合、左側にバージョンがない置換が削除されます。-go=versionフラグは、想定される Go 言語バージョンを設定します。
編集フラグは繰り返すことができます。変更は指定された順序で適用されます。
go work edit には、その出力を制御する追加のフラグがあります。
-printフラグは、最終的な go.work を go.mod に書き戻すのではなく、テキスト形式で出力します。-jsonフラグは、最終的な go.work ファイルを go.mod に書き戻すのではなく、JSON 形式で出力します。JSON 出力はこれらの Go 型に対応します。
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 ファイルから削除されます。
-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 のコンテンツタイプを持ち、charset は utf-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/text の go.mod ファイルを要求している場合、クライアントは https://example.com/mod/golang.org/x/text/@v/v0.3.2.mod に対して GET リクエストを送信します。
大文字と小文字を区別しないファイルシステムから提供する際の曖昧さを避けるため、$module および $version 要素は、すべての大文字を感嘆符とその後の対応する小文字に置き換えることで大文字と小文字がエンコードされます。これにより、example.com/M は example.com/!m としてエンコードされるため、モジュール example.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
}
今後、さらにフィールドが追加される可能性があるため、他の名前は予約されています。 |
$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 コマンドは明示的な info、mod、および zip ファイルを合成し、それらをこのディレクトリに保存します。これは、プロキシから直接ダウンロードした場合と同じです。キャッシュのレイアウトはプロキシの URL スペースと同じであるため、$GOPATH/pkg/mod/cache/download を https://example.com/proxy で提供する (またはコピーする) と、ユーザーは GOPROXY を https://example.com/proxy に設定することで、キャッシュされたモジュールバージョンにアクセスできます。
プロキシとの通信
go コマンドは、モジュールソースコードとメタデータをモジュールプロキシからダウンロードすることがあります。GOPROXY 環境変数は、go コマンドがどのプロキシに接続できるか、およびバージョン管理システムと直接通信できるかどうかを設定するために使用できます。ダウンロードされたモジュールデータはモジュールキャッシュに保存されます。go コマンドは、キャッシュにまだない情報が必要な場合にのみプロキシに接続します。
GOPROXY プロトコルのセクションでは、GOPROXY サーバーに送信される可能性のあるリクエストについて説明しています。ただし、go コマンドがこれらのリクエストをいつ行うかを理解することも役立ちます。たとえば、go build は以下の手順に従います。
go.modファイルを読み込み、最小バージョン選択 (MVS) を実行して、ビルドリストを計算します。- コマンドラインで指定されたパッケージと、それらがインポートするパッケージを読み込みます。
- ビルドリスト内のどのモジュールにもパッケージが提供されていない場合、それを提供するモジュールを見つけます。その最新バージョンに対するモジュール要件を
go.modに追加し、最初からやり直します。 - すべてが読み込まれた後にパッケージをビルドします。
go コマンドがビルドリストを計算するとき、モジュールグラフ内の各モジュールの go.mod ファイルを読み込みます。go.mod ファイルがキャッシュにない場合、go コマンドは $module/@v/$version.mod リクエスト ($module はモジュールパス、$version はバージョン) を使用してプロキシからダウンロードします。これらのリクエストは、curl のようなツールでテストできます。たとえば、以下のコマンドは、バージョン v0.2.0 の golang.org/x/mod の go.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/html、golang.org/x/net、golang.org/x/、および golang.org の最新バージョンを見つけようとします。実際に存在し、そのパッケージを提供するモジュールは golang.org/x/net のみなので、go コマンドはそのモジュールの最新バージョンを使用します。複数のモジュールがパッケージを提供する場合、go コマンドは最も長いパスを持つモジュールを使用します。
go コマンドがモジュールの最新バージョンを要求するとき、最初に $module/@v/list のリクエストを送信します。リストが空であるか、返されたバージョンのどれも使用できない場合、$module/@latest のリクエストを送信します。バージョンが選択されると、go コマンドはメタデータのために $module/@v/$version.info リクエストを送信します。その後、go.mod ファイルとソースコードをロードするために $module/@v/$version.mod と $module/@v/$version.zip リクエストを送信する場合があります。
$ 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 コマンドはチェックサムデータベースからそれ retrieves します。計算されたハッシュが一致しない場合、go コマンドはセキュリティエラーを報告し、モジュールキャッシュにファイルをインストールしません。GOPRIVATE および GONOSUMDB 環境変数を使用して、特定のモジュールのチェックサムデータベースへのリクエストを無効にすることができます。GOSUMDB 環境変数を off に設定して、チェックサムデータベースへのリクエストを完全に無効にすることもできます。詳細については、「モジュールの認証」を参照してください。.info リクエストに対して返されるバージョンリストとバージョンメタデータは認証されず、時間とともに変更される可能性があることに注意してください。
プロキシからモジュールを直接提供する
ほとんどのモジュールはバージョン管理リポジトリで開発および提供されます。ダイレクトモードでは、go コマンドはバージョン管理ツールを使用してそのようなモジュールをダウンロードします (バージョン管理システムを参照)。モジュールプロキシからモジュールを直接提供することも可能です。これは、バージョン管理サーバーを公開せずにモジュールを提供したい組織や、go コマンドがサポートしないバージョン管理ツールを使用している組織にとって便利です。
go コマンドがダイレクトモードでモジュールをダウンロードする場合、まずモジュールパスに基づいて HTTP GET リクエストでモジュールサーバーの URL を検索します。HTML 応答で go-import という名前の <meta> タグを探します。タグのコンテンツには、リポジトリのルートパス、バージョン管理システム、および 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.info、v1.0.0.mod、および v1.0.0.zip のリクエストを送信してモジュールをダウンロードします。
プロキシから直接提供されるモジュールは、GOPATH モードの go get ではダウンロードできないことに注意してください。
バージョン管理システム
go コマンドは、モジュールのソースコードとメタデータをバージョン管理リポジトリから直接ダウンロードすることがあります。プロキシからのモジュールのダウンロードは通常高速ですが、プロキシが利用できない場合や、モジュールのリポジトリがプロキシからアクセスできない場合 (プライベートリポジトリではよくあることです) には、リポジトリに直接接続する必要があります。Git、Subversion、Mercurial、Bazaar、および Fossil がサポートされています。go コマンドがバージョン管理ツールを使用するには、そのツールが PATH 内のディレクトリにインストールされている必要があります。
プロキシではなくソースリポジトリから特定のモジュールをダウンロードするには、GOPRIVATE または GONOPROXY 環境変数を設定します。すべてのモジュールをソースリポジトリから直接ダウンロードするように go コマンドを設定するには、GOPROXY を direct に設定します。詳細については、「環境変数」を参照してください。
モジュールパスのリポジトリの検索
go コマンドが direct モードでモジュールをダウンロードする場合、最初にモジュールを含むリポジトリを特定します。
モジュールパスがパスコンポーネントの末尾に VCS 修飾子 (.bzr、.fossil、.git、.hg、.svn のいずれか) を持つ場合、go コマンドはそのパス修飾子までのすべてをリポジトリ URL として使用します。たとえば、モジュール example.com/foo.git/bar の場合、go コマンドは Git を使用して example.com/foo のリポジトリをダウンロードし、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 ドキュメントを返す必要があります。<meta> タグは、go コマンドの制限されたパーサーを混乱させないように、ドキュメントの早い段階で表示される必要があります。特に、生の JavaScript や CSS の前に表示される必要があります。<meta> タグは次の形式である必要があります。
<meta name="go-import" content="root-path vcs repo-url [subdirectory]">
root-path はリポジトリのルートパスであり、リポジトリのルートディレクトリに対応するモジュールパスの部分、または、存在し Go 1.25 以降を使用している場合は subdirectory に対応します (以下の subdirectory セクションを参照)。これは、要求されたモジュールパスのプレフィックスであるか、正確に一致する必要があります。正確に一致しない場合、<meta> タグが一致することを確認するために、プレフィックスに対して別のリクエストが行われます。
vcs はバージョン管理システムです。これは以下の表にリストされているツールのいずれか、またはキーワード mod である必要があります。mod は、GOPROXY プロトコルを使用して指定された URL からモジュールをダウンロードするように go コマンドに指示します。詳細については、「プロキシからモジュールを直接提供する」を参照してください。
repo-url はリポジトリの URL です。URL にスキームが含まれていない場合 (モジュールパスに VCS 修飾子があるか、<meta> タグにスキームがないため)、go コマンドはバージョン管理システムがサポートする各プロトコルを試行します。たとえば、Git の場合、go コマンドは https:// を試行し、次に git+ssh:// を試行します。安全でないプロトコル (http:// や git:// など) は、モジュールパスが GOINSECURE 環境変数と一致する場合にのみ使用できます。
subdirectory は、存在する場合、リポジトリのルートディレクトリのデフォルトを上書きして、root-path に対応するリポジトリの、スラッシュで区切られたサブディレクトリです。subdirectory を提供する go-import メタタグは、Go 1.25 以降でのみ認識されます。Go の以前のバージョンでモジュールの解決を試みると、メタタグは無視され、他の場所でモジュールを解決できない場合は解決エラーが発生します。
| 名前 | コマンド | GOVCS のデフォルト | セキュアなスキーム |
|---|---|---|---|
| バザール | bzr |
プライベートのみ | https, bzr+ssh |
| フォッシル | 化石 |
プライベートのみ | https |
| Git | git |
公開と非公開 | https, git+ssh, ssh |
| マーキュリアル | hg |
公開と非公開 | https, ssh |
| サブバージョン | svn |
プライベートのみ | https, svn+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 コマンドはリモート URL https://go.googlesource.com/mod の Git リポジトリを使用します。
GitHub やその他の人気のあるホスティングサービスは、すべてのリポジトリに対して ?go-get=1 クエリに応答するため、通常、これらのサイトでホストされているモジュールにはサーバー設定は不要です。
リポジトリの URL が見つかると、go コマンドはリポジトリをモジュールキャッシュにクローンします。一般に、go コマンドは不要なデータをリポジトリからフェッチすることを避けるようにします。ただし、実際に使用されるコマンドはバージョン管理システムによって異なり、時間とともに変更される場合があります。Git の場合、go コマンドはコミットをダウンロードせずに利用可能なほとんどのバージョンをリストできます。通常、祖先コミットをダウンロードせずにコミットをフェッチしますが、そうすることが必要な場合もあります。
バージョンをコミットにマッピングする
go コマンドは、v1.2.3、v2.4.0-beta、または v3.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 には属しません。
メジャーバージョンが v2 以上で、go.mod ファイルが存在せず、モジュールがリポジトリのルートディレクトリにある場合、メジャーバージョンサフィックスのないモジュールに属するタグがあります。この種のバージョンはサフィックス +incompatible で示されます。バージョンタグ自体にサフィックスがあってはいけません。非モジュールリポジトリとの互換性を参照してください。
一度タグが作成されると、削除したり、別のリビジョンに変更したりしてはいけません。バージョンは、安全で再現可能なビルドを保証するために認証されます。タグが変更された場合、クライアントはダウンロード時にセキュリティエラーを表示する可能性があります。タグが削除された後でも、そのコンテンツはモジュールプロキシで利用可能なままになる場合があります。
擬似バージョンをコミットにマッピングする
go コマンドは、v1.3.2-0.20191109021931-daa7c04131f5 のような擬似バージョンとしてエンコードされた特定の改訂版でリポジトリ内のモジュールをチェックアウトできます。
擬似バージョンの最後の 12 文字 (上記の例では daa7c04131f5) は、チェックアウトするリポジトリ内のリビジョンを示します。その意味はバージョン管理システムによって異なります。Git と Mercurial の場合、これはコミットハッシュのプレフィックスです。Subversion の場合、これはゼロパディングされたリビジョン番号です。
コミットをチェックアウトする前に、go コマンドはタイムスタンプ (上記の 20191109021931) がコミット日付と一致することを確認します。また、ベースバージョン (上記の例では v1.3.2 の前のバージョンである v1.3.1) がコミットの祖先であるセマンティックバージョンタグに対応していることを確認します。これらのチェックにより、モジュール作者は擬似バージョンが他のリリースバージョンと比較される方法を完全に制御できるようになります。
詳細については、「擬似バージョン」を参照してください。
ブランチとコミットをバージョンにマッピングする
バージョンクエリを使用して、モジュールを特定のブランチ、タグ、またはリビジョンでチェックアウトできます。
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 以降でリリースされた場合、そのパスにはメジャーバージョンサフィックスが必要です。メジャーバージョンサフィックスを持つモジュールは、サフィックスのあるサブディレクトリとサフィックスのないサブディレクトリの2つのサブディレクトリのいずれかで定義できます。たとえば、上記のモジュールの新しいバージョンがパス 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 という名前のファイルがない場合、同じリビジョンに存在すれば、リポジトリのルートディレクトリから LICENSE という名前のファイルをコピーします。
この特別ケースにより、同じ LICENSE ファイルをリポジトリ内のすべてのモジュールに適用できます。これは、.txt などの拡張子のない、 specifically LICENSE という名前のファイルにのみ適用されます。残念ながら、既存のモジュールの暗号化された合計を壊さずにこれを拡張することはできません。詳細については、「モジュールの認証」を参照してください。他のツールやウェブサイト (例: pkg.go.dev) は、他の名前のファイルを認識する場合があります。
また、go コマンドはモジュールの .zip ファイルを作成する際にシンボリックリンクを含まないことにも注意してください。詳細については、「ファイルパスとサイズ制約」を参照してください。結果として、リポジトリのルートディレクトリに LICENSE ファイルがない場合、作成者は代わりにライセンスファイルのコピーをサブディレクトリに定義されたモジュール内に作成することで、それらのファイルがモジュールの .zip ファイルに含まれるようにすることができます。
GOVCS によるバージョン管理ツールの制御
go コマンドが git のようなバージョン管理コマンドでモジュールをダウンロードできることは、コードを任意のサーバーからインポートできる分散型パッケージエコシステムにとって重要です。また、悪意のあるサーバーが、呼び出されたバージョン管理コマンドに意図しないコードを実行させる方法を見つけた場合、潜在的なセキュリティ問題にもなります。
機能とセキュリティの懸念のバランスを取るため、go コマンドはデフォルトで、公開サーバーからコードをダウンロードするために git と hg のみを使用します。プライベートサーバー (GOPRIVATE 環境変数と一致するパッケージをホストするものとして定義されます) からコードをダウンロードするために、既知のバージョン管理システムのいずれかを使用します。Git と Mercurial のみを許可する根拠は、これら2つのシステムが信頼できないサーバーのクライアントとして実行される問題に最も注意を払ってきたという点にあります。対照的に、Bazaar、Fossil、Subversion は主に信頼できる認証された環境で使用されており、攻撃対象領域として十分に精査されていません。
バージョン管理コマンドの制限は、コードをダウンロードするために直接バージョン管理アクセスを使用する場合にのみ適用されます。プロキシからモジュールをダウンロードする場合、go コマンドは代わりにGOPROXY プロトコルを使用します。これは常に許可されています。デフォルトでは、go コマンドは公開モジュールには Go モジュールミラー (proxy.golang.org) を使用し、プライベートモジュールの場合、またはミラーが公開パッケージの提供を拒否する場合 (通常は法的な理由による) にのみバージョン管理にフォールバックします。したがって、クライアントは Bazaar、Fossil、または Subversion リポジトリから提供される公開コードにデフォルトでアクセスできます。これらのダウンロードは Go モジュールミラーを使用するため、ミラーはカスタムサンドボックスを使用してバージョン管理コマンドを実行するセキュリティリスクを負います。
GOVCS 変数を使用して、特定のモジュールに許可されるバージョン管理システムを変更できます。GOVCS 変数は、モジュール対応モードと GOPATH モードの両方でパッケージをビルドする際に適用されます。モジュールを使用する場合、パターンはモジュールパスと一致します。GOPATH を使用する場合、パターンはバージョン管理リポジトリのルートに対応するインポートパスと一致します。
GOVCS 変数の一般的な形式は、pattern:vcslist ルールのコンマ区切りリストです。パターンは、モジュールまたはインポートパスの1つ以上の先行要素と一致する必要がある glob パターンです。vcslist は、許可されるバージョン管理コマンドのパイプ区切りリスト、または既知のコマンドすべてを許可する all、または何も許可しない off です。モジュールが vcslist off のパターンと一致しても、オリジンサーバーが mod スキームを使用している場合、ダウンロードされる可能性があることに注意してください。mod スキームは、go コマンドにGOPROXY プロトコルを使用してモジュールをダウンロードするように指示します。リスト内で最初に一致するパターンが適用されます。たとえ後続のパターンも一致する可能性があってもです。
例えば、次を考えてみましょう。
GOVCS=github.com:git,evil.com:off,*:git|hg
この設定では、github.com/ で始まるモジュールまたはインポートパスを持つコードは git のみを使用でき、evil.com 上のパスはバージョン管理コマンドを一切使用できず、その他のすべてのパス (* はすべてに一致します) は git または hg のみを使用できます。
特殊なパターン public と private は、公開モジュールパスとプライベートモジュールパスに一致します。パスが 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 ファイルが幅広いプラットフォームで安全かつ一貫して抽出できることを保証します。
- モジュールの zip ファイルの最大サイズは 500 MiB です。そのファイルの合計解凍サイズも 500 MiB に制限されています。
go.modファイルは 16 MiB に制限されています。LICENSEファイルも 16 MiB に制限されています。これらの制限は、ユーザー、プロキシ、およびモジュールエコシステムの他の部分に対するサービス拒否攻撃を軽減するために存在します。モジュールディレクトリツリーに 500 MiB を超えるファイルを含むリポジトリは、モジュールのパッケージをビルドするために必要なファイルのみを含むコミットでモジュールのバージョンにタグ付けする必要があります。ビデオ、モデル、その他の大きなアセットは通常ビルドには必要ありません。 - モジュールの zip ファイル内の各ファイルは、
$module@$version/というプレフィックスで始まる必要があります。ここで、$moduleはモジュールパス、$versionはバージョンです (例:golang.org/x/mod@v0.3.0/)。モジュールパスは有効である必要があり、バージョンは有効で正規である必要があり、バージョンはモジュールパスのメジャーバージョンサフィックスと一致する必要があります。具体的な定義と制限については、「モジュールパスとバージョン」を参照してください。 - ファイルモード、タイムスタンプ、その他のメタデータは無視されます。
- 空のディレクトリ (パスがスラッシュで終わるエントリ) はモジュール zip ファイルに含めることができますが、展開されません。
goコマンドは、作成する zip ファイルに空のディレクトリを含めません。 - シンボリックリンクやその他の不規則なファイルは、オペレーティングシステムやファイルシステム間で移植性がなく、zip ファイル形式でそれらを表す移植可能な方法がないため、zip ファイルを作成する際に無視されます。
- メインモジュール以外の
vendorディレクトリ内のファイルは、vendorディレクトリが使用されることがないため、zip ファイルを作成する際に無視されます。 - モジュールルートディレクトリ以外の
go.modファイルを含むディレクトリ内のファイルは、モジュールの一部ではないため、zip ファイルを作成する際に無視されます。goコマンドは、zip ファイルを解凍する際にgo.modファイルを含むサブディレクトリを無視します。 - zip ファイル内のどの 2 つのファイルも、Unicode の大文字小文字の区別を無視して (「
strings.EqualFold」を参照)、パスが同じであってはなりません。これにより、大文字小文字を区別しないファイルシステムで衝突なく zip ファイルを抽出できることが保証されます。 go.modファイルは、トップレベルディレクトリ ($module@$version/go.mod) に存在する場合があります。存在する場合は、go.mod(すべて小文字) という名前でなければなりません。go.modという名前のファイルは、他のディレクトリでは許可されません。- モジュール内のファイル名とディレクトリ名は、Unicode 文字、ASCII 数字、ASCII スペース文字 (U+0020)、および ASCII 句読点文字
!#$%&()+,-.=@[]^_{}~で構成できます。パッケージパスにはこれらのすべての文字を含めることはできないことに注意してください。違いについては、module.CheckFilePathとmodule.CheckImportPathを参照してください。 - ファイルまたはディレクトリの名前は、最初のドットまでの部分が、Windows で予約されているファイル名であってはなりません (大文字小文字に関係なく、
CON、com1、NuLなど)。
プライベートモジュール
Go モジュールは、多くの場合、公開インターネット上で利用できないバージョン管理サーバーやモジュールプロキシ上で開発および配布されます。go コマンドはプライベートソースからモジュールをダウンロードしてビルドできますが、通常はいくつかの構成が必要です。
以下の環境変数は、プライベートモジュールへのアクセスを設定するために使用できます。詳細については、「環境変数」を参照してください。また、公開サーバーに送信される情報の制御については、「プライバシー」を参照してください。
GOPROXY— モジュールプロキシ URL のリスト。goコマンドは、リスト内の各サーバーから順にモジュールをダウンロードしようとします。キーワードdirectは、goコマンドにプロキシを使用する代わりに、開発されているバージョン管理リポジトリからモジュールをダウンロードするように指示します。GOPRIVATE— プライベートとみなされるべきモジュールパスプレフィックスのグロブパターンのリスト。GONOPROXYとGONOSUMDBのデフォルト値として機能します。GONOPROXY— プロキシからダウンロードしてはいけないモジュールパスプレフィックスのグロブパターンのリスト。goコマンドは、GOPROXYにかかわらず、一致するモジュールを開発されているバージョン管理リポジトリからダウンロードします。GONOSUMDB— 公開チェックサムデータベース sum.golang.org を使用してチェックすべきではないモジュールパスプレフィックスのグロブパターンのリスト。GOINSECURE— HTTP やその他の安全でないプロトコルで取得できるモジュールパスプレフィックスのグロブパターンのリスト。
これらの変数は、開発環境 (たとえば、.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 (Not Found) または 410 (Gone) で応答した場合、go コマンドは https://proxy.golang.org にフォールバックし、その後リポジトリへの直接接続にフォールバックします。
GONOSUMDB の設定は、go コマンドに、corp.example.com で始まるパスを持つモジュールの認証に公開チェックサムデータベースを使用しないように指示します。
この構成で使用されるプロキシは、公開モジュールを提供しない場合でも、それらへのアクセスを制御できることに注意してください。プロキシがリクエストに対して 404 または 410 以外のエラー状態を返した場合、go コマンドは GOPROXY リストの後のエントリにフォールバックしません。たとえば、プロキシは、不適切なライセンスを持つモジュールや既知のセキュリティ脆弱性を持つモジュールに対して 403 (Forbidden) で応答する可能性があります。
プライベートモジュールへの直接アクセス
go コマンドは、公開プロキシを迂回して、プライベートモジュールをバージョン管理サーバーから直接ダウンロードするように設定できます。これは、プライベートプロキシサーバーの実行が現実的ではない場合に便利です。
このように go コマンドが動作するように設定するには、GOPRIVATE を設定し、corp.example.com をプライベートモジュールプレフィックスに置き換えます。
GOPRIVATE=corp.example.com
この状況では GOPROXY 変数を変更する必要はありません。デフォルトは https://proxy.golang.org,direct であり、go コマンドに最初に https://proxy.golang.org からモジュールをダウンロードしようと指示し、そのプロキシが 404 (Not Found) または 410 (Gone) で応答した場合に直接接続にフォールバックするように指示します。
GOPRIVATE の設定は、go コマンドに、corp.example.com で始まるモジュールに対してプロキシやチェックサムデータベースに接続しないように指示します。
モジュールパスをリポジトリ URL に解決するために、内部 HTTP サーバーが依然として必要になる場合があります。たとえば、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 ファイルは、go コマンドに指定されたユーザー名とパスワードでマシン proxy.corp.example.com に接続するように設定します。
machine proxy.corp.example.com
login jrgopher
password hunter2
ファイルの場所は、NETRC 環境変数で設定できます。NETRC が設定されていない場合、go コマンドは UNIX 系プラットフォームでは $HOME/.netrc を、Windows では %USERPROFILE%\_netrc を読み取ります。
.netrc のフィールドは、スペース、タブ、改行で区切られます。残念ながら、これらの文字はユーザー名やパスワードには使用できません。また、マシン名は完全な URL にすることはできないため、同じマシン上の異なるパスに対して異なるユーザー名とパスワードを指定することはできません。
あるいは、資格情報は GOPROXY URL で直接指定できます。たとえば、
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 環境変数は、どのサーバーを使用するかを制御します。GOPRIVATE と GONOPROXY 環境変数は、どのモジュールをプロキシからフェッチするかを制御します。
GOPROXY のデフォルト値は次のとおりです。
https://proxy.golang.org,direct
この設定では、go コマンドがモジュールまたはモジュールメタデータをダウンロードする際、まず Google が運営する公開モジュールプロキシ (プライバシーポリシー) である proxy.golang.org にリクエストを送信します。各リクエストで送信される情報の詳細については、「GOPROXY プロトコル」を参照してください。go コマンドは個人を特定できる情報を送信しませんが、要求されている完全なモジュールパスは送信します。プロキシが 404 (Not Found) または 410 (Gone) ステータスで応答した場合、go コマンドはモジュールを提供するバージョン管理システムに直接接続しようとします。詳細については、「バージョン管理システム」を参照してください。
GOPRIVATE または GONOPROXY 環境変数は、プライベートであり、どのプロキシからも要求すべきでないモジュールプレフィックスに一致するグロブパターンのリストに設定できます。たとえば、
GOPRIVATE=*.corp.example.com,*.research.example.com
GOPRIVATE は単に GONOPROXY と GONOSUMDB のデフォルトとして機能するため、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 (Not Found) または 410 (Gone) で応答した場合、go コマンドは proxy.golang.org にフォールバックし、リクエスト URL に secret-product パスを送信します。プライベートプロキシが他のエラーコードで応答した場合、go コマンドはエラーを出力し、他のソースにはフォールバックしません。
プロキシに加えて、go コマンドはチェックサムデータベースに接続して、go.sum にリストされていないモジュールの暗号ハッシュを検証することがあります。GOSUMDB 環境変数は、チェックサムデータベースの名前、URL、公開鍵を設定します。GOSUMDB のデフォルト値は、Google が運営する公開チェックサムデータベース sum.golang.org (プライバシーポリシー) です。各リクエストで送信される内容の詳細については、「チェックサムデータベース」を参照してください。プロキシと同様に、go コマンドは個人を特定できる情報を送信しませんが、要求されている完全なモジュールパスは送信します。また、チェックサムデータベースは非公開モジュールのチェックサムを計算できません。
GONOSUMDB 環境変数は、どのモジュールがプライベートであり、チェックサムデータベースから要求すべきでないかを示すパターンに設定できます。GOPRIVATE は GONOSUMDB と GONOPROXY のデフォルトとして機能するため、GONOPROXY が異なる値を持つべきでない限り、GONOSUMDB を設定する必要はありません。
プロキシはチェックサムデータベースをミラーリングすることがあります。GOPROXY 内のプロキシがこれを行う場合、go コマンドはチェックサムデータベースに直接接続しません。
GOSUMDB は off に設定すると、チェックサムデータベースの使用を完全に無効にできます。この設定では、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 ファイルがなかった場合、go.mod ファイルは含まれません。 |
キャッシュ/ダウンロード/ |
モジュールプロキシからダウンロードされたファイルおよびバージョン管理システムから派生したファイルを含むディレクトリ。このディレクトリのレイアウトは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 ファイルと抽出されたディレクトリのハッシュがこれらのファイルと一致することを確認します。 |
キャッシュ/ダウンロード/sumdb/ |
チェックサムデータベース (通常は sum.golang.org) からダウンロードされたファイルを含むディレクトリ。 |
キャッシュ/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 の各行は、モジュールパス、バージョン (/go.mod で終わる場合があります)、ハッシュの 3 つのフィールドをスペースで区切って記述されています。
- モジュールパスは、ハッシュが属するモジュールの名前です。
- バージョンは、ハッシュが属するモジュールのバージョンです。バージョンが
/go.modで終わる場合、ハッシュはモジュールのgo.modファイルのみのものであり、それ以外の場合は、ハッシュはモジュールの.zipファイル内のファイル用です。 - ハッシュ列は、アルゴリズム名 (
h1など) と base64 エンコードされた暗号ハッシュで構成され、コロン (:) で区切られます。現在、SHA-256 (h1) のみがサポートされているハッシュアルゴリズムです。将来、SHA-256 に脆弱性が発見された場合、別のアルゴリズム (h2など) が追加でサポートされます。
go.sum ファイルには、モジュールの複数のバージョンのハッシュが含まれる場合があります。go コマンドは、最小バージョン選択を実行するために、依存関係の複数のバージョンから go.mod ファイルをロードする必要がある場合があります。go.sum には、もはや必要ないモジュールバージョンのハッシュも含まれる場合があります (たとえば、アップグレード後)。go mod tidy は、不足しているハッシュを追加し、不要なハッシュを go.sum から削除します。
チェックサムデータベース
チェックサムデータベースは、go.sum 行のグローバルなソースです。go コマンドは、多くの状況でこれを使用して、プロキシまたはオリジンサーバーによる不正行為を検出できます。
チェックサムデータベースは、すべての公開モジュールバージョンに対してグローバルな一貫性と信頼性を可能にします。これにより、信頼できないプロキシは、気付かれずに誤ったコードを提供することができないため、可能になります。また、特定のバージョンに関連付けられたビットが、モジュールの作者がリポジトリ内のタグを後で変更した場合でも、日によって変更されないことを保証します。
チェックサムデータベースは、Google が運営する sum.golang.org によって提供されます。これは、Trillian によってサポートされている go.sum 行ハッシュの透過的なログ (または「マークルツリー」) です。マークルツリーの主な利点は、独立した監査人が改ざんされていないことを検証できるため、単純なデータベースよりも信頼性が高いことです。
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/M は example.com/!m としてエンコードされるため、モジュール example.com/M と example.com/m の両方をディスクに保存できます。
角括弧で囲まれたパスの部分 (例: [.p/$W]) は、オプションの値を表します。
| パス | 説明 |
|---|---|
$base/latest |
最新のログの署名付きエンコードされたツリー記述を返します。この署名付き記述は、1つ以上のサーバーキーによって署名され、サーバーの公開鍵を使用して検証できるテキストであるノートの形式です。ツリー記述は、そのサイズのツリーのサイズとツリーヘッドのハッシュを提供します。このエンコーディングは、 golang.org/x/mod/sumdb/tlog#FormatTreeで説明されています。 |
$base/lookup/$module@$version |
$version の $module に関するエントリのログレコード番号を返し、その後、レコードのデータ (つまり、$version の $module の go.sum 行) と、レコードを含む署名付きでエンコードされたツリー記述を返します。 |
$base/tile/$H/$L/$K[.p/$W] |
[ログタイル](https://research.swtch.com/tlog#serving_tiles)を返します。これはログのセクションを構成するハッシュのセットです。各タイルは、タイルレベル $L、左から $K 番目、タイル高さ $H の2次元座標で定義されます。オプションの .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 はデフォルトで sum.golang.org、Google が運営する Go チェックサムデータベースです。サービスプライバシーポリシーについては、https://sum.golang.org/privacy を参照してください。
GOSUMDB が off に設定されている場合、または go get が -insecure フラグで呼び出された場合、チェックサムデータベースは参照されず、すべての未認識モジュールが受け入れられます。これは、すべてのモジュールについて検証された再現可能なダウンロードのセキュリティ保証を放棄する代償を伴います。特定のモジュールのチェックサムデータベースをバイパスするより良い方法は、GOPRIVATE または GONOSUMDB 環境変数を使用することです。詳細については、「プライベートモジュール」を参照してください。
go env -w コマンドは、将来の go コマンド呼び出しのためにこれらの変数を設定するために使用できます。
環境変数
go コマンドのモジュール動作は、以下の環境変数を使用して構成できます。このリストにはモジュール関連の環境変数のみが含まれています。go コマンドが認識するすべての環境変数のリストについては、go help environment を参照してください。
| 変数 | 説明 |
|---|---|
GO111MODULE |
詳細については、モジュール対応コマンドを参照してください。 |
GOMODCACHE |
|
GOINSECURE |
常に安全でない方法でフェッチできるモジュールパスプレフィックスのグロブパターン(Go の
|
GONOPROXY |
モジュールプロキシからではなく、常にバージョン管理リポジトリから直接フェッチする必要があるモジュールパスプレフィックスのグロブパターン(Go の
|
GONOSUMDB |
チェックサムデータベースを使用して
|
GOPATH |
モジュール対応モードでは、モジュールキャッシュは最初の
|
GOPRIVATE |
プライベートと見なすべきモジュールパスプレフィックスのグロブパターン(Go の path.Match の構文)をカンマで区切ったリストです。GOPRIVATE は GONOPROXY および GONOSUMDB のデフォルト値です。プライバシーを参照してください。GOPRIVATE は、モジュールが GOVCS に対してプライベートと見なされるかどうかも決定します。 |
GOPROXY |
モジュールプロキシURLのリストで、カンマ (
GOPROXY=file://$(go env GOMODCACHE)/cache/download プロキシURLの代わりに次の2つのキーワードを使用できます。
プロキシがどのように使用されるかについての詳細は、モジュールプロキシとパッケージからモジュールへの解決を参照してください。 |
GOSUMDB |
使用するチェックサムデータベースの名前、オプションでその公開鍵とURLを識別します。例: GOSUMDB="sum.golang.org" GOSUMDB="sum.golang.org+<publickey>" GOSUMDB="sum.golang.org+<publickey> https://sum.golang.org"
|
GOVCS |
public:git|hg,private:all 完全な説明については、 |
GOWORK |
|
用語集
ビルド制約: Go ソースファイルがパッケージをコンパイルするときに使用されるかどうかを決定する条件です。ビルド制約は、ファイル名サフィックス (例: foo_linux_amd64.go) またはビルド制約コメント (例: // +build linux,amd64) で表現できます。ビルド制約を参照してください。
ビルドリスト: go build、go list、go test などのビルドコマンドに使用されるモジュールバージョンのリストです。ビルドリストは、メインモジュールのgo.mod ファイルと、最小バージョン選択を使用して推移的に必要なモジュールの go.mod ファイルから決定されます。ビルドリストには、特定のコマンドに関連するモジュールだけでなく、モジュールグラフ内のすべてのモジュールのバージョンが含まれています。
正規バージョン: +incompatible 以外のビルドメタデータサフィックスを持たない、正しくフォーマットされたバージョンです。例えば、v1.2.3 は正規バージョンですが、v1.2.3+meta は違います。
現在のモジュール: メインモジュールの同義語です。
非推奨モジュール: その作成者によってサポートされなくなったモジュール(ただし、この目的のためにメジャーバージョンは異なるモジュールと見なされます)。非推奨モジュールは、そのgo.mod ファイルの最新バージョンで非推奨コメントでマークされます。
直接依存関係: メインモジュール内のパッケージまたはテスト用の .go ソースファイル内のimport 宣言にパスが表示されるパッケージ、またはそのようなパッケージを含むモジュールです。(間接依存関係と比較してください。)
ダイレクトモード: モジュールプロキシとは対照的に、go コマンドがバージョン管理システムから直接モジュールをダウンロードするようにする環境変数の設定です。GOPROXY=direct はすべてのモジュールに対してこれを行います。GOPRIVATE および GONOPROXY は、パターンのリストに一致するモジュールに対してこれを行います。
go.mod ファイル: モジュールのパス、要件、その他のメタデータを定義するファイルです。モジュールのルートディレクトリに存在します。go.mod ファイルのセクションを参照してください。
go.work ファイル: ワークスペースで使用されるモジュールのセットを定義するファイルです。go.work ファイルのセクションを参照してください。
インポートパス: Go ソースファイルでパッケージをインポートするために使用される文字列です。パッケージパスと同義です。
間接依存関係: メインモジュール内のパッケージまたはテストによって推移的にインポートされるパッケージですが、そのパスがメインモジュール内のどのimport 宣言にも表示されないもの。または、モジュールグラフに表示されるが、メインモジュールによって直接インポートされるパッケージを提供しないモジュール。(直接依存関係と比較してください。)
遅延モジュール読み込み: Go 1.17での変更点。go 1.17 以降を指定するモジュールで、モジュールグラフを必要としないコマンドでは、その読み込みを避けるようにします。遅延モジュール読み込みを参照してください。
メインモジュール: go コマンドが呼び出されるモジュールです。メインモジュールは、現在のディレクトリまたは親ディレクトリにあるgo.mod ファイルによって定義されます。モジュール、パッケージ、およびバージョンを参照してください。
メジャーバージョン: セマンティックバージョンの最初の数字(v1.2.3 の 1)。互換性のない変更を含むリリースでは、メジャーバージョンをインクリメントし、マイナーバージョンとパッチバージョンを0に設定する必要があります。メジャーバージョンが0のセマンティックバージョンは不安定と見なされます。
メジャーバージョンサブディレクトリ: モジュールのメジャーバージョンサフィックスに一致するバージョン管理リポジトリ内のサブディレクトリで、モジュールが定義される可能性があります。例えば、ルートパス example.com/mod を持つリポジトリ内のモジュール example.com/mod/v2 は、リポジトリのルートディレクトリまたはメジャーバージョンサブディレクトリ v2 で定義される可能性があります。リポジトリ内のモジュールディレクトリを参照してください。
メジャーバージョンサフィックス: メジャーバージョン番号に一致するモジュールパスサフィックス。たとえば、example.com/mod/v2 の /v2 です。メジャーバージョンサフィックスは v2.0.0 以降で必須であり、それ以前のバージョンでは許可されません。メジャーバージョンサフィックスのセクションを参照してください。
最小バージョン選択 (MVS): ビルドで使用されるすべてのモジュールのバージョンを決定するために使用されるアルゴリズムです。詳細については、最小バージョン選択のセクションを参照してください。
マイナーバージョン: セマンティックバージョンの2番目の数字(v1.2.3 の 2)。新しい後方互換性のある機能を含むリリースでは、マイナーバージョンをインクリメントし、パッチバージョンを0に設定する必要があります。
モジュール: 一緒にリリース、バージョン管理、配布されるパッケージの集合です。
モジュールキャッシュ: ダウンロードされたモジュールを格納するローカルディレクトリで、GOPATH/pkg/mod にあります。モジュールキャッシュを参照してください。
モジュールグラフ: メインモジュールをルートとするモジュール要件の有向グラフです。グラフ内の各頂点はモジュールであり、各エッジは go.mod ファイル内の require ステートメントからのバージョンです(メインモジュールの go.mod ファイル内の replace および exclude ステートメントに従います)。
モジュールグラフ剪定: Go 1.17における変更で、go 1.17 以降を指定するモジュールの推移的な依存関係を省略することで、モジュールグラフのサイズを削減します。モジュールグラフ剪定を参照してください。
モジュールパス: モジュールを識別し、モジュール内のパッケージインポートパスのプレフィックスとして機能するパスです。例: "golang.org/x/net"。
モジュールプロキシ: GOPROXY プロトコルを実装するWebサーバーです。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-pre は v1.2.3 の前に来ます)。リリースバージョンも参照してください。
擬似バージョン: リビジョン識別子(Gitコミットハッシュなど)とバージョン管理システムのタイムスタンプをエンコードしたバージョンです。例: v0.0.0-20191109021931-daa7c04131f5。非モジュールリポジトリとの互換性や、タグ付きバージョンが利用できないその他の状況で使用されます。
リリースバージョン: プレリリースサフィックスのないバージョン。例えば、v1.2.3 であり、v1.2.3-pre ではありません。プレリリースバージョンも参照してください。
リポジトリルートパス: モジュールパスのうち、バージョン管理リポジトリのルートディレクトリに対応する部分です。モジュールパスを参照してください。
撤回されたバージョン: 早すぎる公開、または公開後に重大な問題が発見されたなどの理由で依存すべきではないバージョンです。retract ディレクティブを参照してください。
セマンティックバージョンタグ: バージョンを特定のリビジョンにマッピングする、バージョン管理リポジトリ内のタグです。バージョンをコミットにマッピングするを参照してください。
選択されたバージョン: 最小バージョン選択によって選択された、特定のモジュールのバージョンです。選択されたバージョンは、モジュールグラフ内で見つかったモジュールのパスに対する最高のバージョンです。
ベンダーディレクトリ: メインモジュール内のパッケージをビルドするために必要な、他のモジュールのパッケージを含む vendor という名前のディレクトリ。go mod vendor で管理されます。ベンダーリングを参照してください。
バージョン: モジュールの不変のスナップショットの識別子で、文字 v の後にセマンティックバージョンが続きます。バージョンのセクションを参照してください。
ワークスペース: 最小バージョン選択 (MVS)を実行する際にメインモジュールとして使用される、ディスク上のモジュールのコレクションです。ワークスペースのセクションを参照してください。