The Go Blog (Go ブログ)
ワークスペースに慣れる
Go 1.18 では、複数のモジュールを同時に操作できるワークスペースモードが Go に追加されました。
ダウンロードページにアクセスして Go 1.18 を入手できます。リリースノートには、すべての変更に関する詳細が記載されています。
ワークスペース
Go 1.18 のワークスペースでは、各モジュールの go.mod
ファイルを編集することなく、複数のモジュールを同時に操作できます。ワークスペース内の各モジュールは、依存関係の解決時にメインモジュールとして扱われます。
以前は、あるモジュールに機能を追加して別のモジュールで使用するには、最初のモジュールへの変更を公開するか、依存モジュールの go.mod を編集して、ローカルの未公開モジュール変更の replace
ディレクティブを追加する必要がありました。エラーなしで公開するには、最初のモジュールへのローカルの変更を公開した後、依存モジュールの go.mod
ファイルから replace
ディレクティブを削除する必要がありました。
Go ワークスペースを使用すると、ワークスペースディレクトリのルートにある go.work
ファイルを使用してすべての依存関係を制御できます。 go.work
ファイルには、個々の go.mod
ファイルをオーバーライドする use
ディレクティブと replace
ディレクティブがあるため、各 go.mod
ファイルを個別に編集する必要はありません。
スペース区切りの引数としてモジュールディレクトリのリストを指定して go work init
を実行することにより、ワークスペースを作成します。ワークスペースには、作業中のモジュールが含まれている必要はありません。init
コマンドは、ワークスペース内のモジュールをリストする go.work
ファイルを作成します。引数なしで go work init
を実行すると、コマンドは空のワークスペースを作成します。
ワークスペースにモジュールを追加するには、go work use [moddir]
を実行するか、go.work
ファイルを手動で編集します。 go work use -r .
を実行して、引数ディレクトリ内の go.mod
ファイルを持つディレクトリをワークスペースに再帰的に追加します。ディレクトリに go.mod
ファイルがない場合、またはディレクトリが存在しない場合、そのディレクトリの use
ディレクティブは go.work
ファイルから削除されます。
go.work
ファイルの構文は go.mod
ファイルに似ており、次のディレクティブが含まれています。
go
: Go ツールチェーンのバージョン。例:go 1.18
use
: ディスク上のモジュールをワークスペース内のメインモジュールのセットに追加します。その引数は、モジュールのgo.mod
ファイルを含むディレクトリへの相対パスです。use
ディレクティブは、指定されたディレクトリのサブディレクトリにあるモジュールを追加しません。replace
:go.mod
ファイルのreplace
ディレクティブと同様に、go.work
ファイルのreplace
ディレクティブは、モジュールの*特定のバージョン*またはモジュールの*すべてのバージョン*の内容を、他の場所で見つかった内容に置き換えます。
ワークフロー
ワークスペースは柔軟性があり、さまざまなワークフローをサポートします。以下のセクションでは、最も一般的と思われるワークフローの概要を簡単に説明します。
アップストリームモジュールに機能を追加し、独自のモジュールで使用します
-
ワークスペースのディレクトリを作成します。
-
編集するアップストリームモジュールをクローンします。
-
アップストリームモジュールのローカルバージョンに機能を追加します。
-
ワークスペースフォルダーで
go work init [アップストリームモジュールディレクトリへのパス]
を実行します。 -
アップストリームモジュールに追加された機能を実装するために、独自のモジュールを変更します。
-
ワークスペースフォルダーで
go work use [モジュールへのパス]
を実行します。go work use
コマンドは、モジュールへのパスをgo.work
ファイルに追加します。go 1.18 use ( ./path-to-upstream-mod-dir ./path-to-your-module )
-
アップストリームモジュールに追加された新機能を使用して、モジュールを実行およびテストします。
-
新機能を含むアップストリームモジュールを公開します。
-
新機能を使用してモジュールを公開します。
同じリポジトリ内の複数の相互依存モジュールを操作する
同じリポジトリ内の複数のモジュールを操作する場合、各モジュールの `go.mod` ファイルで `replace` ディレクティブを使用する代わりに、`go.work` ファイルでワークスペースを定義します。
-
ワークスペースのディレクトリを作成します。
-
編集するモジュールを含むリポジトリをクローンします。`use` ディレクティブでそれぞれへの相対パスを指定するため、モジュールはワークスペースフォルダーにある必要はありません。
-
ワークスペースディレクトリで `go work init [モジュール1へのパス] [モジュール2へのパス]` を実行します。
例: `example.com/x/tools` モジュール内の他のパッケージに依存する `example.com/x/tools/groundhog` を操作しているとします。
リポジトリをクローンし、ワークスペースフォルダーで `go work init tools tools/groundhog` を実行します。
`go.work` ファイルの内容は次のようになります。
go 1.18 use ( ./tools ./tools/groundhog )
`tools` モジュールで行われたローカルの変更は、ワークスペースの `tools/groundhog` で使用されます。
依存関係構成の切り替え
異なる依存関係構成でモジュールをテストするには、別々の `go.work` ファイルを持つ複数のワークスペースを作成するか、1つのワークスペースを維持し、単一の `go.work` ファイルで不要な `use` ディレクティブをコメントアウトします。
複数のワークスペースを作成するには
- 異なる依存関係ニーズに合わせて個別のディレクトリを作成します。
- 各ワークスペースディレクトリで `go work init` を実行します。
- `go work use [依存関係へのパス]` を使用して、各ディレクトリ内に必要な依存関係を追加します。
- 各ワークスペースディレクトリで `go run [モジュールへのパス]` を実行して、その `go.work` ファイルで指定された依存関係を使用します。
同じワークスペース内で異なる依存関係をテストするには、`go.work` ファイルを開き、目的の依存関係を追加またはコメントアウトします。
まだ GOPATH を使用していますか?
おそらくワークスペースを使用することで気が変わるでしょう。`GOPATH` ユーザーは、`GOPATH` ディレクトリのベースにある `go.work` ファイルを使用して依存関係を解決できます。ワークスペースはすべての `GOPATH` ワークフローを完全に再現することを目的としていませんが、モジュールの利点を提供しながら `GOPATH` の利便性の一部を共有するセットアップを作成できます。
GOPATH のワークスペースを作成するには
- `GOPATH` ディレクトリのルートで `go work init` を実行します.
- ローカルモジュールまたは特定のバージョンをワークスペースの依存関係として使用するには、`go work use [モジュールへのパス]` を実行します。
- モジュールの `go.mod` ファイルの既存の依存関係を置き換えるには、`go work replace [モジュールへのパス]` を使用します。
- GOPATH または任意のディレクトリにあるすべてのモジュールを追加するには、`go work use -r` を実行して、`go.mod` ファイルを持つディレクトリをワークスペースに再帰的に追加します。ディレクトリに `go.mod` ファイルがない場合、またはディレクトリが存在しない場合、そのディレクトリの `use` ディレクティブは `go.work` ファイルから削除されます。
注: ワークスペースに追加したい `go.mod` ファイルのないプロジェクトがある場合は、プロジェクトディレクトリに移動して `go mod init` を実行し、`go work use [モジュールへのパス]` を使用して新しいモジュールをワークスペースに追加します。
ワークスペースコマンド
`go work init` と `go work use` に加えて、Go 1.18 ではワークスペース用に次のコマンドが導入されています。
- `go work sync`: `go.work` ファイルの依存関係を各ワークスペースモジュールの `go.mod` ファイルにプッシュします。
- `go work edit`: 主にツールやスクリプトで使用するための、`go.work` を編集するためのコマンドラインインターフェイスを提供します。
モジュール対応のビルドコマンドといくつかの `go mod` サブコマンドは、`GOWORK` 環境変数を調べて、ワークスペースコンテキスト内にあるかどうかを判断します。
`GOWORK` 変数が `.work` で終わるファイルへのパスを指定している場合、ワークスペースモードが有効になります。使用されている `go.work` ファイルを確認するには、`go env GOWORK` を実行します。`go` コマンドがワークスペースモードではない場合、出力は空になります.
ワークスペースモードが有効になっている場合、`go.work` ファイルが解析され、ワークスペースモードの3つのパラメーター(Go バージョン、ディレクトリのリスト、置換のリスト)が決定されます.
ワークスペースモードで試してみるコマンド(すでに何をするか知っている場合)
go work init
go work sync
go work use
go list
go build
go test
go run
go vet
エディターエクスペリエンスの向上
私たちは、Go の言語サーバー gopls と VSCode Go 拡張機能 のアップグレードに特に興奮しています。これにより、LSP 互換エディターで複数のモジュールをスムーズかつ快適に操作できます。
ワークスペース内のモジュール全体で、参照の検索、コード補完、定義へのジャンプが機能します。gopls
のバージョン 0.8.1 では、go.work
ファイルの診断、補完、フォーマット、ホバーが導入されました。これらの gopls 機能は、LSP 互換の任意のエディタで利用できます。
エディタ固有の注意事項
- 最新の vscode-go リリース では、Go ステータスバーのクイックピックメニューからワークスペースの
go.work
ファイルにすばやくアクセスできます。
- GoLand はワークスペースをサポートしており、
go.work
ファイルの構文ハイライトとコード補完を追加する予定です。
さまざまなエディタで gopls
を使用する方法の詳細については、gopls
のドキュメントをご覧ください。
次のステップ
- Go 1.18 をダウンロードしてインストールします。
- ワークスペースをGo ワークスペースチュートリアルで使用してみてください。
- ワークスペースで問題が発生した場合、または提案がある場合は、issue を作成してください。
- ワークスペースのメンテナンスに関するドキュメントをお読みください。
go work init
、go work sync
など、単一のモジュールの外部で作業するためのモジュールコマンドをご覧ください。
次の記事:ジェネリクスを使用する場合
前の記事:Go がサプライチェーン攻撃を軽減する方法
ブログインデックス