Go の workspace を使って go. mod を汚さずに replace を書く
はじめに
依存するモジュールがあって、これに手元の開発環境で変更を入れるんだけれども、そのモジュールをリリースする前に変更したモジュールを参照して開発したい。そういうことがまれによくあります。
いままで 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