依存関係の使用と管理のワークフロー
Goツールを使用して便利なパッケージを取得し、利用できます。pkg.go.devで、役立ちそうなパッケージを検索し、go
コマンドを使用してそれらのパッケージを自分のコードにインポートし、その関数を呼び出すことができます。
以下は、最も一般的な依存関係管理のステップを示しています。各ステップの詳細については、このトピックのセクションを参照してください。
- 1. pkg.go.devで役立つパッケージを見つける。
- 2. コードに必要なパッケージをインポートする。
- 3. 依存関係追跡のためにコードをモジュールに追加する(まだモジュールにない場合)。依存関係追跡の有効化を参照してください。
- 4. 外部パッケージを依存関係として追加することで、管理できるようにする。
- 5. 時間の経過に応じて、必要に応じて依存関係のバージョンをアップグレードまたはダウングレードする。
モジュールとしての依存関係の管理
Goでは、インポートするパッケージを含むモジュールとして依存関係を管理します。このプロセスは次のことによってサポートされています:
- モジュールを公開し、そのコードを取得するための分散システム。開発者は、自分のリポジトリから他の開発者が使用できるようにモジュールを提供し、バージョン番号で公開します。
- モジュールを見つけるためのパッケージ検索エンジンとドキュメントブラウザ(pkg.go.dev)。役立つパッケージの検索とインポートを参照してください。
- モジュールの安定性と後方互換性の保証を理解するためのモジュールバージョン番号付け規則。モジュールバージョン番号付けを参照してください。
- 依存関係を管理しやすくするためのGoツール。モジュールのソースを取得したり、アップグレードしたりすることが含まれます。このトピックのセクションを参照してください。
役立つパッケージの検索とインポート
役立ちそうな関数を持つパッケージを見つけるためにpkg.go.devを検索できます。
使用したいパッケージを見つけたら、ページの上部にあるパッケージパスを見つけ、コピーするボタンをクリックしてパスをクリップボードにコピーします。自分のコードに、次の例のようにインポート文にパスを貼り付けます:
import "rsc.io/quote"
コードがパッケージをインポートした後、依存関係追跡を有効にし、コンパイル用のパッケージコードを取得します。詳細については、コード内での依存関係追跡の有効化と依存関係の追加を参照してください。
コード内での依存関係追跡の有効化
追加した依存関係を追跡し管理するには、まずコードを独自のモジュールに配置します。これにより、ソースツリーのルートにgo.modファイルが作成されます。追加した依存関係はそのファイルにリストされます。
コードを独自のモジュールに追加するには、go mod init
コマンドを使用します。たとえば、コマンドラインからコードのルートディレクトリに移動し、次の例のようにコマンドを実行します:
$ go mod init example/mymodule
go mod init
コマンドの引数は、モジュールのモジュールパスです。可能であれば、モジュールパスはソースコードのリポジトリの場所であるべきです。
最初にモジュールの最終的なリポジトリの場所がわからない場合は、安全な代替を使用します。これは、所有しているドメインの名前や、他の制御可能な名前(会社名など)と、モジュールの名前やソースディレクトリに続くパスである可能性があります。詳細については、モジュールの命名を参照してください。
Goツールを使用して依存関係を管理すると、ツールはgo.modファイルを更新し、依存関係の最新リストを維持します。
依存関係を追加すると、Goツールは依存しているモジュールのチェックサムを含むgo.sumファイルも作成します。Goはこれを使用して、特にプロジェクトで作業している他の開発者のために、ダウンロードしたモジュールファイルの整合性を確認します。
go.modおよびgo.sumファイルをリポジトリにコードと共に含めてください。
詳細については、go.modリファレンスを参照してください。
モジュールの命名
依存関係を追跡するためのモジュールを作成するためにgo mod init
を実行すると、モジュールの名前として機能するモジュールパスを指定します。モジュールパスは、モジュール内のパッケージのインポートパスプレフィックスになります。他のモジュールのモジュールパスと衝突しないモジュールパスを指定してください。
最低限、モジュールパスはその起源に関する何かを示す必要があります。たとえば、会社名や著者名、所有者名などです。しかし、パスはモジュールが何であるか、または何をするかについてより説明的である可能性もあります。
モジュールパスは通常、次の形式です:
<prefix>/<descriptive-text>
- プレフィックスは通常、モジュールを部分的に説明する文字列であり、その起源を説明する文字列です。これは次のようなものです:
- Goツールがモジュールのソースコードを見つけることができるリポジトリの場所(モジュールを公開する場合は必須)。
たとえば、github.com/<project-name>/
である可能性があります。このベストプラクティスを使用するのは、他の人が使用できるようにモジュールを公開する可能性がある場合です。公開に関する詳細は、モジュールの開発と公開を参照してください。 - あなたが制御する名前。
リポジトリ名を使用していない場合は、他の人が使用しない自信のあるプレフィックスを選択してください。良い選択肢は、あなたの会社の名前です。widgets
、utilities
、またはapp
のような一般的な用語は避けてください。
- Goツールがモジュールのソースコードを見つけることができるリポジトリの場所(モジュールを公開する場合は必須)。
- 説明的なテキストには、プロジェクト名が良い選択肢です。パッケージ名は機能を説明する上で最も重要な役割を果たします。モジュールパスは、これらのパッケージ名の名前空間を作成します。
予約されたモジュールパスプレフィックス
Goは、次の文字列がパッケージ名で使用されないことを保証します。
test
– 他のモジュール内の関数をローカルでテストするために設計されたモジュールのモジュールパスプレフィックスとしてtest
を使用できます。
テストの一部として作成されたモジュールにはtest
パスプレフィックスを使用してください。たとえば、テスト自体がgo mod init test
を実行し、その後、Goソースコード分析ツールでテストするために特定の方法でそのモジュールを設定することがあります。example
– 依存関係を追跡するためにモジュールを作成しているチュートリアルなど、一部のGoドキュメントでモジュールパスプレフィックスとして使用されます。
Goドキュメントは、例が公開モジュールである可能性がある場合を示すためにexample.com
も使用します。
依存関係の追加
公開されたモジュールからパッケージをインポートしている場合、go get
コマンドを使用してそのモジュールを依存関係として管理するために追加できます。
このコマンドは次のことを行います:
- 必要に応じて、コマンドラインで指定されたパッケージをビルドするために必要なモジュールのgo.modファイルに
require
ディレクティブを追加します。require
ディレクティブは、モジュールが依存しているモジュールの最小バージョンを追跡します。詳細については、go.modリファレンスを参照してください。 - 必要に応じて、依存しているパッケージをコンパイルできるようにモジュールのソースコードをダウンロードします。モジュールは、module proxy.golang.orgのようなモジュールプロキシから、またはバージョン管理リポジトリから直接ダウンロードできます。ソースはローカルにキャッシュされます。
Goツールがモジュールをダウンロードする場所を設定できます。詳細については、モジュールプロキシサーバーの指定を参照してください。
以下は、いくつかの例を示します。
- モジュール内のパッケージのすべての依存関係を追加するには、次のようなコマンドを実行します(”.”は現在のディレクトリのパッケージを指します):
$ go get .
- 特定の依存関係を追加するには、そのモジュールパスをコマンドの引数として指定します。
$ go get example.com/theirmodule
このコマンドは、ダウンロードする各モジュールを認証します。これにより、モジュールが公開されたときから変更されていないことが保証されます。モジュールが公開されて以来変更された場合(たとえば、開発者がコミットの内容を変更した場合)、Goツールはセキュリティエラーを表示します。この認証チェックは、改ざんされた可能性のあるモジュールから保護します。
特定の依存関係バージョンの取得
特定の依存関係モジュールのバージョンをgo get
コマンドで指定することにより取得できます。このコマンドは、go.modファイル内のrequire
ディレクティブを更新します(手動で更新することもできます)。
これを行いたい場合があります:
- モジュールの特定のプレリリースバージョンを取得して試したい。
- 現在要求しているバージョンが機能していないことがわかったので、信頼できるバージョンを取得したい。
- すでに要求しているモジュールをアップグレードまたはダウングレードしたい。
go get
コマンドを使用する例をいくつか示します:
- 特定の番号付きバージョンを取得するには、モジュールパスに@記号を追加し、続けて取得したいバージョンを追加します:
$ go get example.com/theirmodule@v1.3.4
- 最新バージョンを取得するには、モジュールパスに
@latest
を追加します:$ go get example.com/theirmodule@latest
以下のgo.modファイルrequire
ディレクティブの例(詳細はgo.modリファレンスを参照)では、特定のバージョン番号を要求する方法を示しています:
require example.com/theirmodule v1.3.4
利用可能なアップデートの発見
現在のモジュールで既に使用している依存関係の新しいバージョンがあるかどうかを確認できます。go list
コマンドを使用して、モジュールの依存関係のリストと、そのモジュールの最新バージョンを表示します。利用可能なアップグレードを発見したら、それをコードで試して、新しいバージョンにアップグレードするかどうかを決定できます。
go list
コマンドの詳細については、go list -m
を参照してください。
以下は、いくつかの例です。
- 現在のモジュールの依存関係であるすべてのモジュールと、それぞれの最新バージョンをリストします:
$ go list -m -u all
特定のモジュールの最新バージョンを表示します:
$ go list -m -u example.com/theirmodule
依存関係のアップグレードまたはダウングレード
Goツールを使用して利用可能なバージョンを発見し、異なるバージョンを依存関係として追加することで、依存関係モジュールをアップグレードまたはダウングレードできます。
- 1. 新しいバージョンを発見するには、利用可能なアップデートの発見で説明されている
go list
コマンドを使用します。 - 2. 特定のバージョンを依存関係として追加するには、特定の依存関係バージョンの取得で説明されている
go get
コマンドを使用します。
コードの依存関係の同期
インポートされたすべてのパッケージの依存関係を管理し、もはやインポートしていないパッケージの依存関係を削除していることを確認できます。
これは、コードと依存関係に変更を加えたときに役立ちます。これにより、管理された依存関係とダウンロードされたモジュールのコレクションが、コードにインポートされたパッケージによって特に要求されるコレクションと一致しなくなる可能性があります。
管理された依存関係セットを整理するには、go mod tidy
コマンドを使用します。このコマンドは、コードにインポートされたパッケージのセットを使用して、必要だが欠落しているモジュールを追加するためにgo.modファイルを編集します。また、関連するパッケージを提供しない未使用のモジュールを削除します。
このコマンドには、削除されたモジュールに関する情報を印刷する-vフラグを除いて、引数はありません。
$ go mod tidy
公開されていないモジュールコードに対する開発とテスト
公開されていない依存関係モジュールを使用するようにコードを指定できます。これらのモジュールのコードは、それぞれのリポジトリ、リポジトリのフォーク、またはそれらを消費する現在のモジュールのドライブにある可能性があります。
これを行いたい場合があります:
- 外部モジュールのコードに自分の変更を加えたい場合、たとえばフォークまたはクローンした後です。たとえば、モジュールの修正を準備し、それをモジュールの開発者にプルリクエストとして送信したい場合があります。
- 新しいモジュールを構築していて、まだ公開していないため、
go get
コマンドがアクセスできるリポジトリには存在しません。
ローカルディレクトリのモジュールコードの要求
必要なモジュールのコードが、要求するコードと同じローカルドライブにあることを指定できます。これは、次のような場合に便利です:
- 自分の別のモジュールを開発していて、現在のモジュールからテストしたい。
- 外部モジュールの問題を修正したり、機能を追加したりしていて、現在のモジュールからテストしたい。(外部モジュールをそのリポジトリのフォークから要求することもできます。詳細は、自分のリポジトリフォークから外部モジュールコードを要求するを参照してください。)
モジュールのコードのローカルコピーを使用するようにGoコマンドに指示するには、go.modファイル内のreplace
ディレクティブを使用して、require
ディレクティブで指定されたモジュールパスを置き換えます。ディレクティブに関する詳細は、go.modリファレンスを参照してください。
以下のgo.modファイルの例では、現在のモジュールが外部モジュールexample.com/theirmodule
を要求し、存在しないバージョン番号(v0.0.0-unpublished
)を使用して置き換えが正しく機能するようにします。replace
ディレクティブは、元のモジュールパスを../theirmodule
に置き換えます。これは、現在のモジュールのディレクトリと同じレベルにあるディレクトリです。
module example.com/mymodule
go 1.16
require example.com/theirmodule v0.0.0-unpublished
replace example.com/theirmodule v0.0.0-unpublished => ../theirmodule
require
/replace
ペアを設定する際は、go mod edit
およびgo get
コマンドを使用して、ファイルで説明されている要件が一貫していることを確認してください:
$ go mod edit -replace=example.com/theirmodule@v0.0.0-unpublished=../theirmodule
$ go get example.com/theirmodule@v0.0.0-unpublished
注意: 置き換えディレクティブを使用する場合、Goツールは依存関係の追加で説明されているように外部モジュールを認証しません。
バージョン番号に関する詳細は、モジュールバージョン番号付けを参照してください。
自分のリポジトリフォークから外部モジュールコードを要求する
外部モジュールのリポジトリをフォークした場合(たとえば、モジュールのコードの問題を修正するためや機能を追加するため)、Goツールにモジュールのソースとしてフォークを使用させることができます。これは、自分のコードからの変更をテストするのに便利です。(モジュールを要求するモジュールと同じローカルドライブにあるディレクトリでモジュールコードを要求することもできます。詳細は、ローカルディレクトリのモジュールコードの要求を参照してください。)
これを行うには、go.modファイル内のreplace
ディレクティブを使用して、外部モジュールの元のモジュールパスをリポジトリ内のフォークへのパスに置き換えます。これにより、Goツールはコンパイル時に置き換えパス(フォークの場所)を使用し、import
ステートメントを元のモジュールパスから変更せずに残すことができます。
以下のgo.modファイルの例では、現在のモジュールが外部モジュール`````example.com/theirmodule`````を要求します。`````replace`````ディレクティブは、元のモジュールパスを`````example.com/myfork/theirmodule`````に置き換えます。これは、モジュールのリポジトリのフォークです。
``````bash
module example.com/mymodule
go 1.16
require example.com/theirmodule v1.2.3
replace example.com/theirmodule v1.2.3 => example.com/myfork/theirmodule v1.2.3-fixed
`
require
/replace
ペアを設定する際は、Goツールコマンドを使用して、ファイルで説明されている要件が一貫していることを確認してください。現在のモジュールで使用されているバージョンを取得するには、go list
コマンドを使用します。その後、go mod edit
コマンドを使用して、必要なモジュールをフォークに置き換えます:
$ go list -m example.com/theirmodule
example.com/theirmodule v1.2.3
$ go mod edit -replace=example.com/theirmodule@v1.2.3=example.com/myfork/theirmodule@v1.2.3-fixed
注意: replace
ディレクティブを使用する場合、Goツールは依存関係の追加で説明されているように外部モジュールを認証しません。
バージョン番号に関する詳細は、モジュールバージョン番号付けを参照してください。
リポジトリ識別子を使用して特定のコミットを取得する
特定のコミットからモジュールの未公開コードを追加するには、go get
コマンドを使用できます。
これを行うには、go get
コマンドを使用し、@
記号で指定したコードを指定します。go get
を使用すると、コマンドはgo.modファイルにrequire
ディレクティブを追加し、外部モジュールを要求し、コミットに関する詳細に基づいて擬似バージョン番号を使用します。
以下の例は、gitリポジトリにソースがあるモジュールに基づいています。
- 特定のコミットでモジュールを取得するには、@commithash形式を追加します:
$ go get example.com/theirmodule@4cf76c2
特定のブランチでモジュールを取得するには、@branchname形式を追加します:
$ go get example.com/theirmodule@bugfixes
依存関係の削除
コードがモジュール内のパッケージをもはや使用しない場合、そのモジュールを依存関係として追跡するのをやめることができます。
未使用のすべてのモジュールの追跡を停止するには、go mod tidy
コマンドを実行します。このコマンドは、モジュール内のパッケージをビルドするために必要な欠落している依存関係を追加することもあります。
$ go mod tidy
特定の依存関係を削除するには、go get
コマンドを使用し、モジュールのモジュールパスを指定し、@none
を追加します。次の例のように:
$ go get example.com/theirmodule@none
go get
コマンドは、削除されたモジュールに依存する他の依存関係もダウングレードまたは削除します。
モジュールプロキシサーバーの指定
Goツールを使用してモジュールを操作する際、ツールはデフォルトでproxy.golang.org(Googleが運営する公開モジュールミラー)からモジュールをダウンロードするか、モジュールのリポジトリから直接ダウンロードします。Goツールがモジュールをダウンロードおよび認証するために別のプロキシサーバーを使用するように指定できます。
これは、(またはチームが)使用したい別のモジュールプロキシサーバーを設定または選択した場合に行いたい場合があります。たとえば、依存関係の使用方法をより厳密に制御するためにモジュールプロキシサーバーを設定することがあります。
Goツールが使用する別のモジュールプロキシサーバーを指定するには、GOPROXY
環境変数を1つ以上のサーバーのURLに設定します。Goツールは、指定した順序で各URLを試みます。デフォルトでは、GOPROXY
は最初に公開のGoogle運営モジュールプロキシを指定し、その後、モジュールのリポジトリから直接ダウンロードします(モジュールパスで指定された通り):
GOPROXY="https://proxy.golang.org,direct"
他のモジュールプロキシサーバーのURLに設定することができ、URLはカンマまたはパイプで区切ります。
- カンマを使用すると、Goツールは現在のURLがHTTP 404または410を返した場合にのみ、リスト内の次のURLを試みます。
``````bash
GOPROXY="https://proxy.example.com,https://proxy2.example.com"
`
- パイプを使用すると、GoツールはHTTPエラーコードに関係なく、リスト内の次のURLを試みます。
GOPROXY="https://proxy.example.com|https://proxy2.example.com"
Goモジュールは、公共のインターネットで利用できないバージョン管理サーバーやモジュールプロキシで頻繁に開発および配布されます。GOPRIVATE
環境変数を設定して、go
コマンドを構成し、プライベートソースからモジュールをダウンロードおよびビルドできます。次に、goコマンドはプライベートソースからモジュールをダウンロードおよびビルドできます。
``````bash
GOPRIVATE=*.corp.example.com,*.research.example.com
`