複数モジュールを組み込んだワークスペースの作成

2022/11/20に公開

複数のモジュールを使った開発をするならworkspaceというのを使うらしい。
goコマンドもいろいろあるようだけど、追々調べていこう。

今回は、GoチュートリアルのTutorial: Getting started with multi-module workspacesをやっていく。

モジュールの作成

workspaceという名前でディレクトリを作成

$ mkdir workspace
$ cd workspace

モジュールの初期化。

$ 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モジュールの依存関係を追加する。

$ cat go.mod
module example.com/hello

go 1.19

$ go get golang.org/x/example
go: downloading golang.org/x/example v0.0.0-20220412213650-2e68773dfca0
go: added golang.org/x/example v0.0.0-20220412213650-2e68773dfca0

$ ls
go.mod  go.sum

$ cat go.mod
module example.com/hello

go 1.19

require golang.org/x/example v0.0.0-20220412213650-2e68773dfca0 // indirect

$ cat go.sum
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
# 長いため割愛

hello.goを作成する。

hello.go
package main

import (
	"fmt"
	"golang.org/x/example/stringutil"
)

func main() {
	fmt.Println(stringutil.Reverse("Hello"))
}

プログラムを実行する

$ go run example.com/hello
olleH

ワークスペースを作成する

モジュールでワークスペースを指定するためにgo.workファイルを作成する。

workspaceディレクトリで、次のコマンドを実行する。

$ go work init ./hello

go work initコマンドは、./helloディレクトリ内のモジュールを含むワークスペース用のgo.workファイルを作成する。
これによって、go.workファイルが生成される。

$ cat go.work
go 1.19

use ./hello

goディレクティブは、Goのバージョンを示す。ディレクティブはgo.modと同じ。
useディレクティブは、ビルド時にhelloディレクトリ内のモジュールがメインモジュールであることをGoに伝えている。

workspaceディレクトリでコマンドを実行する

$ go run example.com/hello
olleH

モジュールの外だが、helloプログラムが実行できていることが確認できた。
Goコマンドには、ワークスぺースないの全てのモジュールがメインモジュールとして含まれるので、モジュールの外であっても、モジュール内のパッケージを参照して実行することができる。
ワークスペースの外でコマンドを実行すると、コマンドが使用するモジュールを認識できなくなるため、エラーが発生する。

golang.org/x/exampleモジュールをダウンロードして変更する

モジュールのGitリポジトリのコピーをダウンロードし、golang.org/x/exampleをワークスペースに追加して、新しい関数を追加する。

まずはじめにリポジトリをクローンする

$ git clone https://go.googlesource.com/example
Cloning into 'example'...
remote: Total 204 (delta 93), reused 204 (delta 93)
Receiving objects: 100% (204/204), 103.24 KiB | 121.00 KiB/s, done.
Resolving deltas: 100% (93/93), done.

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

$ go work use ./example

このコマンドは、新しいモジュールをgo.workファイルに追加するもの。

$ cat go.work
go 1.19

use (
        ./example
        ./hello
)

次に新しい機能を追加する。
文字列を大文字にする新しい関数をgolang.org/x/example/stringutilパッケージに追加する。

stringutilパッケージがあるディレクトリまで移動して、toupper.gpという新しいファイルを作成する。

$ cd example/stringutil
$ touch toupper.go
toupper.go
package stringutil

import "unicode"

func ToUpper(s string) string {
	r := []rune(s)
	for i := range r {
		r[i] = unicode.ToUpper(r[i])
	}
	return string(r)
}

helloプログラム側でToUpper関数を使用するように変更する。

hello.go
-fmt.Println(stringutil.Reverse("Hello"))
+fmt.Println(stringutil.ToUpper("Hello"))

ワークスペースでコードを実行する

$ go run example.com/hello
HELLO

チュートリアルはこれで終了。
モジュールのリリースのワークフローが公開されているので、ちゃんとしたモジュールを開発したら、そちらを参照したほうがよい。

Discussion