Goの公式チュートリアルをやってみる【マルチモジュールワークスペース】

前回

Goの公式チュートリアルをやってみる【モジュールの作成】

初めに

前回は簡単な一つのモジュールを作成しました。ですが、実際にモジュールを開発する際は一つではなく、複数のモジュールを使用して開発を行います。

今回は複数のモジュールを開発する際に、一度にビルドして実行する方法を学んでいきます。

今回もhelloモジュールを作成しますが、前回のhelloモジュールとは違いますので退避することをお勧めいたします。

また、今回はGitを使用しますので、事前にダウンロードとインストールをお願いいたします。

helloモジュールの作成

まずは一つ目のモジュールとなる、helloモジュールを作成しましょう。

最初にworkspaceフォルダを作成します。そしてその中にhelloフォルダを作成し、コマンドプロンプトでhelloフォルダに移動します。その後go mod init example.com/helloコマンドを実行してモジュールを作成します。

go.modファイルが生成されたことを確認したら、go get golang.org/x/example/hello/reverseコマンドを実行し、golang.org/x/example/hello/reverseパッケージの依存関係を取得します。

そして、hello.goファイルを作成して以下のコードを追加します。

/workspace/hello/hello.go
package main

import (
    "fmt"

    "golang.org/x/example/hello/reverse"
)

func main() {
    fmt.Println(reverse.String("Hello"))
}

コードを追加したら実際に実行して出力を確認してみましょう。
以下の出力を得られたら、作成完了です。

$ go run .
olleH

ワークスペースの作成

ワークスペースの初期化

workspaceディレクトリに移動し、go work init ./helloコマンドを実行します。すると、以下のようなgo.workファイルが生成されます。

/workspace/go.work
go 1.22.5

use ./hello

go.workファイルはgo.modと似た構文を持っています。goディレクティブは、ファイルがどのバージョンのGoで解釈されるべきかを指示します。useディレクティブは、ビルドする際にhelloディレクトリのモジュールをメインモジュールにするようにGoへ指示しています。これで、workspace内のどのディレクトリでもこのモジュールがアクティブになるようになりました。

workspaceディレクトリでプログラムを実行

workspaceディレクトリで以下のコマンドを実行してみましょう。

$ go run ./hello
olleH

コマンドが実行できたら正常にワークスペースを初期化できています。

Goのコマンドはワークスペース内のすべてのモジュールをメインモジュールとして含むようになりました。これでモジュールの外でもモジュールの内のパッケージを参照できるようになります。

次にgolang.org/x/example/helloモジュールのローカルコピーをワークスペースに追加しましょう。そしてStringの代わりに使える関数をreverseパッケージに追加します。

golang.org/x/example/helloモジュールのダウンロードと修正

リポジトリのクローン

まずは対象のモジュールのリポジトリをGitを用いてクローンします。workspaceディレクトリで以下のコマンドを入力してください。

$ git clone https://go.googlesource.com/example
Cloning into 'example'...
Rremote: Total 389 (delta 133), reused 389 (delta 133)
Receiving objects: 100% (389/389), 349.16 KiB | 1.75 MiB/s, done.
Resolving deltas: 100% (133/133), done.

モジュールをワークスペースに追加

対象のリポジトリをクローンしたら、workspaceディレクトリにexampleフォルダがチェックアウトされました。workspace/example/hellogolang.org/x/example/helloモジュールがありますので、ワークスペースに追加していきましょう。workspaceディレクトリでgo work use ./example/helloコマンドを実行しましょう。

/workspace/go.work
go 1.18

use (
    ./hello
    ./example/hello
)

go.workファイルを確認すると上記の様にモジュールが追加されていることを確認できます。このワークスペースにはexample.com/helloモジュールとgolang.org/x/example/helloモジュールの両方が含まれるようになり、golang.org/x/example/hello/reverseが提供されるようになりました。これでgo getコマンドでダウンロードしたモジュールキャッシュのパッケージのバージョンではなく、reverseパッケージのコピーに書かれた新しいコードを使用することができます。

関数の追加

golang.org/x/example/hello/reverseパッケージに、数字を反転させる関数を追加しましょう。workspace/example/hello/reverseディレクトリに以下の内容のint.goというファイルを作成します。

workspace/example/hello/reverse/int.go
package reverse

import "strconv"

// 整数 i の 10 進数の逆数を返します。
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コマンドを実行しましょう。

$ go run ./hello
olleH 10642

goコマンドはコマンドラインで指定されたexample.com/helloモジュールをgo.workファイルで指定されたhelloディレクトリで見つけ、同様にgolang.org/x/example/hello/reverseのインポートをgo.workファイルを使用して解決します。go.workreplaceディレクティブを追加する代わりに使うことで、複数のモジュールにまたがって動作させることができます。2つのモジュールは同じワークスペースで管理されているので、片方のモジュールに変更が加わっても簡単にもう片方で使用することができます。

リリース

リリースする際はモジュールごとにバージョンを付与して管理します。通常はGitなどのバージョン管理システムのリポジトリにコミットタグを付与して管理します。モジュールをほかの人が使用できる形になったらv0を。安定板になったらv1を、破壊的なアップグレードになる場合はv2を検討しますが、最後の手段としましょう。詳細は公式の『モジュールのリリースとバージョニングのワークフロー』を参考にしてください。

まとめ

  • go work init xxx/yyyでワークスペースの初期化を行う
  • go work use aaa/bbbでワークスペースにモジュールを追加する
  • ワークスペースのトップにワークスペースの情報がまとまったgo.workファイルが生成される
  • ワークスペースを使用するとワークスペース内であればどこでもモジュールを実行できるようになる

次回

Goの公式チュートリアルをやってみる【ジェネリクス】

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です