🔁

Go の workspace を使って go. mod を汚さずに replace を書く

2022/07/01に公開

はじめに

依存するモジュールがあって、これに手元の開発環境で変更を入れるんだけれども、そのモジュールをリリースする前に変更したモジュールを参照して開発したい。そういうことがまれによくあります。

いままで go.mod に書かれていた replace を Go 1.18 の workspace を使って go.work に書き出すようにすると、go.mod を汚さずにすむので、うっかりコミットしたりしそうになることも避けやすくなります(たぶん)。

対象は Go 1.18 以降です。

Go における workspace

Go の workspace は 1.18 で導入された機能で、複数のモジュールを同時に開発するときに利用できる仕組みです。ここにチュートリアルがあります。Zenn にも記事が結構上がってると思うので、参照してみて下さい。

今回は、単に今まで replace でやってきたことを workspace でやりたいだけなので、飛ばします。

手元の開発環境で開発中のモジュールを参照する

依存するモジュールがあって、これに手元の開発環境で変更を入れるんだけれども、そのモジュールをリリースする前に変更したモジュールを参照して開発したい。そういうことがまれによくあります。

そういったときは、go.mod に依存するモジュールの replace に手元の開発環境のモジュールを指定していました。

go.mod

module github.com/ikawaha/kagome/v2

go 1.18

replace (
	github.com/ikawaha/kagome-dict/ipa => ../kagome-dict/ipa
)

require (
	github.com/ikawaha/kagome-dict v1.0.4
	github.com/ikawaha/kagome-dict/ipa v1.0.4
	github.com/ikawaha/kagome-dict/uni v1.1.3
)

こんな感じで書いておくと(ホントは直接書かずに go mod edit コマンド使うのがいいのかも)、必要なライブラリを手元のフォルダを参照して置換してくれます。こうしておくと、上の例だと ipa モジュールだけローカルフォルダのモジュールに置換してくれます。(push ずみ違うバージョンに置き換えるとかもできます。詳しくはリファレンスを参照下さい)

これすごく便利なんですけど、go.mod が変更されちゃうので、うっかりこのままコミットしちゃったりすると「ぐぬぬ」ってなります。

go.mod に replace を書かずに workspace を利用する

Go 1.18 からは workspace という機能が追加されて、これで replace が置き換えられます。
go.mod があるフォルダで、

go work init .

とすると、go.work というファイルが出来ます。

go 1.18

use .

中身はこうなっています。こいつを

go 1.18

use .

replace (
	github.com/ikawaha/kagome-dict/ipa => ../kagome-dict/ipa
)

って書き換えてやると、go.mod に replace 書いたのと同等の意味になります。

これまで go.mod に書いていた repalce が go.work に書かれるので、モジュールの置き換えが不要になったときはこれを消せばいいですし、間違って push しちゃうことも減ると思います(go.work を commit したり push しちゃったら結局アレなんですが・・・)

おわりに

これを発見して、自分では便利でよく使っているのですが、workplace は複数モジュールに対応するための仕組みっぽいので、こうやって使うのは違うのかも知れないのです。もっといいやり方あるよとか、そのやり方弊害あるんじゃない?とかあれば教えて欲しいです。

Happy hacking!

Discussion