チュートリアル: マルチモジュールワークスペース入門
このチュートリアルでは、Go のマルチモジュールワークスペースの基本を紹介します。マルチモジュールワークスペースを使用すると、Go コマンドに複数のモジュールで同時にコードを記述していることを伝え、それらのモジュールでコードを簡単にビルドして実行できます。
このチュートリアルでは、共有マルチモジュールワークスペースに 2 つのモジュールを作成し、それらのモジュール全体に変更を加え、ビルドでそれらの変更の結果を確認します。
注: 他のチュートリアルについては、チュートリアルを参照してください。
前提条件
- Go 1.18 以降のインストール。
- コードを編集するためのツール。 任意のテキストエディタで問題ありません。
- コマンドターミナル。 Go は、Linux と Mac の任意のターミナル、および Windows の PowerShell または cmd でうまく動作します。
このチュートリアルには go1.18 以降が必要です。go.dev/dl のリンクを使用して、Go 1.18 以降をインストールしていることを確認してください。
コードのモジュールを作成する
まず、記述するコードのモジュールを作成します。
-
コマンドプロンプトを開き、ホームディレクトリに移動します。
Linux または Mac の場合
$ cd
Windows の場合
C:\> cd %HOMEPATH%
チュートリアルの残りの部分では、プロンプトとして $ を表示します。使用するコマンドは Windows でも動作します。
-
コマンドプロンプトから、workspace という名前のコード用のディレクトリを作成します。
$ mkdir workspace $ cd workspace
-
モジュールを初期化する
この例では、golang.org/x/example モジュールに依存する新しいモジュール `hello` を作成します。
hello モジュールを作成する
$ mkdir hello $ cd hello $ go mod init example.com/hello go: creating new go.mod: module example.com/hello
`go get` を使用して、golang.org/x/example/hello/reverse パッケージへの依存関係を追加します。
$ go get golang.org/x/example/hello/reverse
hello ディレクトリに、以下の内容で hello.go を作成します
package main import ( "fmt" "golang.org/x/example/hello/reverse" ) func main() { fmt.Println(reverse.String("Hello")) }
次に、hello プログラムを実行します
$ go run . olleH
ワークスペースを作成する
この手順では、モジュールを含むワークスペースを指定するために、`go.work` ファイルを作成します。
ワークスペースを初期化する
`workspace` ディレクトリで、以下を実行します
$ go work init ./hello
`go work init` コマンドは、`./hello` ディレクトリにあるモジュールを含むワークスペースの `go.work` ファイルを作成するように `go` に指示します。
`go` コマンドは、次のような `go.work` ファイルを生成します
go 1.18
use ./hello
`go.work` ファイルは `go.mod` と同様の構文を持っています。
`go` ディレクティブは、ファイルがどのバージョンの Go で解釈されるべきかを Go に指示します。これは `go.mod` ファイルの `go` ディレクティブに似ています。
`use` ディレクティブは、ビルドを行う際に `hello` ディレクトリにあるモジュールをメインモジュールにするように Go に指示します。
そのため、`workspace` の任意のサブディレクトリでモジュールがアクティブになります。
ワークスペースディレクトリでプログラムを実行する
`workspace` ディレクトリで、以下を実行します
$ go run ./hello
olleH
Go コマンドは、ワークスペース内のすべてのモジュールをメインモジュールとして含めます。これにより、モジュールの外部であっても、モジュール内のパッケージを参照できます。モジュールまたはワークスペースの外部で `go run` コマンドを実行すると、`go` コマンドがどのモジュールを使用するかを認識しないため、エラーが発生します。
次に、`golang.org/x/example/hello` モジュールのローカルコピーをワークスペースに追加します。そのモジュールは、`go.googlesource.com/example` Git リポジトリのサブディレクトリに保存されています。次に、`String` の代わりに使用できる新しい関数を `reverse` パッケージに追加します。
`golang.org/x/example/hello` モジュールをダウンロードして変更する
この手順では、`golang.org/x/example/hello` モジュールを含む Git リポジトリのコピーをダウンロードし、ワークスペースに追加してから、hello プログラムから使用する新しい関数を追加します。
-
リポジトリをクローンする
workspace ディレクトリから、`git` コマンドを実行してリポジトリをクローンします
$ git clone https://go.googlesource.com/example Cloning into 'example'... remote: Total 165 (delta 27), reused 165 (delta 27) Receiving objects: 100% (165/165), 434.18 KiB | 1022.00 KiB/s, done. Resolving deltas: 100% (27/27), done.
-
モジュールをワークスペースに追加する
Git リポジトリは `./example` にチェックアウトされたばかりです。`golang.org/x/example/hello` モジュールのソースコードは `./example/hello` にあります。それをワークスペースに追加します
$ go work use ./example/hello
`go work use` コマンドは、go.work ファイルに新しいモジュールを追加します。 अब यह इस तरह दिखेगा
go 1.18 use ( ./hello ./example/hello )
ワークスペースには、`example.com/hello` モジュールと `golang.org/x/example/hello/reverse` パッケージを提供する `golang.org/x/example/hello` モジュールの両方が含まれるようになりました.
これにより、`go get` コマンドでダウンロードしたモジュールキャッシュ内のパッケージのバージョンではなく、`reverse` パッケージのコピーに書き込む新しいコードを使用できます。
-
新しい関数を追加します。
`golang.org/x/example/hello/reverse` パッケージに、数値を反転させる新しい関数を追加します。
`workspace/example/hello/reverse` ディレクトリに、以下の内容を含む `int.go` という名前の新しいファイルを作成します
package reverse import "strconv" // Int returns the decimal reversal of the integer i. func Int(i int) int { i, _ = strconv.Atoi(String(strconv.Itoa(i))) return i }
-
関数を 使用するように hello プログラムを変更します。
`workspace/hello/hello.go` の内容を、以下の内容に変更します
package main import ( "fmt" "golang.org/x/example/hello/reverse" ) func main() { fmt.Println(reverse.String("Hello"), reverse.Int(24601)) }
ワークスペースでコードを実行する
workspace ディレクトリから、以下を実行します
$ go run ./hello
olleH 10642
Go コマンドは、コマンドラインで指定された `example.com/hello` モジュールを `go.work` ファイルで指定された `hello` ディレクトリで見つけ、同様に `go.work` ファイルを使用して `golang.org/x/example/hello/reverse` インポートを解決します.
`go.work` は、複数のモジュールで作業するために `replace` ディレクティブを追加する代わりに使用できます。
2 つのモジュールが同じワークスペースにあるため、一方のモジュールに変更を加えて、もう一方のモジュールで簡単に使用できます。
今後のステップ
次に、これらのモジュールを適切にリリースするには、たとえば `v0.1.0` で `golang.org/x/example/hello` モジュールのリリースを作成する必要があります。これは通常、モジュールのバージョン管理リポジトリでコミットにタグを付けることによって行われます。詳細については、モジュールリリースワークフローのドキュメント を参照してください。リリースが完了したら、`hello/go.mod` の `golang.org/x/example/hello` モジュールの要件を上げることができます
cd hello
go get golang.org/x/example/hello@v0.1.0
そうすれば、`go` コマンドはワークスペースの外部でモジュールを適切に解決できます.
ワークスペースの詳細
`go` コマンドには、チュートリアルの前半で説明した `go work init` に加えて、ワークスペースを操作するためのサブコマンドがいくつかあります
- `go work use [-r] [dir]` は、`dir` が存在する場合、`go.work` ファイルに `use` ディレクティブを追加し、引数ディレクトリが存在しない場合は `use` ディレクトリを削除します。 `-r` フラグは、`dir` のサブディレクトリを再帰的に調べます。
- `go work edit` は、`go mod edit` と同様に `go.work` ファイルを編集します
- `go work sync` は、ワークスペースのビルドリストからの依存関係を各ワークスペースモジュールに同期します。
ワークスペースと `go.work` ファイルの詳細については、Go モジュールリファレンスの ワークスペース を参照してください。