go.mod に慣れていないせいかもしれないが(golang自体にも慣れていないが)、非常に難しく感じる。
文句を言っても仕方ない(か、golangのプルリクを出すとか)ので、理解に努めよう。
$ go version
go version go1.17.3 linux/amd64
golang でオリジナルのものを作るときは気にならないかもしれないが、GitHub で fork したり mirror したりして一部を書き換えたいとなると思考が止まってしまう。
よくあるのが、git cloneする中でも改造して使いたいのはその一部だけ、というパターンだろう。
例として、fmt.Printf するだけのリポジトリを用意した。
main.go と gogo/gogo1.go だけだ。
ここの gogoパッケージにある Gogo() だけ使うリポジトリがこちら。
特に変な動作はしない。
go.mod は自分で記述したわけではなく、 go tidy で勝手に追加されたように思う。
それはよいのだが、gogo-test2 の方を go build . でビルドすると gogo-test2 というバイナリファイルができあがる。
これはなぜかというと、go.mod の module がそういう名前になっているからだ。
もしここで、オリジナルと同じ gogo-test1 という名前にしたくて go.mod の module を github.com/hirokuma/gogo-test1 にすると go build . は失敗する。
$ go build .
main.go:6:2: no required module provides package github.com/hirokuma/gogo-test1/gogo; to add it:
go get github.com/hirokuma/gogo-test1/gogo
main.go:6 は import "github.com/hirokuma/gogo-test1/gogo" している箇所だ。
ではオリジナルと同じ名前のバイナリファイルを作るのには go build だけで無理なのかというとそうでもない。
あまり理解できていないのだが module path とか module directory という考え方があるようで、うーん、後ろに v2 とか書けばいけるのかな?
いけた。
自分より前に v2 を使っている人がいたら私が v3 にしないといけないかというと、たぶんそういうことではないはずだ。調べるのは無理だろうし。
もし v2 でダメになるのはオリジナルが v2 などにした場合だろう。
さて、 gogo-test2 から gogo-test1/gogo にある Gogo() を呼び出していたが、自分で gogo.Gogo() を定義し直したいとしよう。
https://github.com/hirokuma/gogo-test2/blob/v3/gogo/gogo1.go
これを実行すると、gogo-test1 の Gogo() が呼び出される。
$ go run .
gogo-test2!
gogo!
なぜかというと、gogo-test2/main.go で import しているのが gogo-test1/gogo だからだ。
では、go.mod で置き換えてみよう。
うまくいくかと思ったが、これではダメだった。
$ go run .
gogo-test2!
gogo!main.go の import を変更すればよいと思うのだが、本体の変更をせずに go.mod だけで管理できるようになっていると思うのだよ、私は。
難しいねぇ。続きは明日だ。
明日になった。続けよう。
ここまでを整理しておこう。
gogo-test2/v3 から追加した gogo/gogo1.go を main.go で参照させたいのだが、うまくいっていない。
gogo-test2/v4 で replace を追加したのだが、やっぱり参照してくれない。
もちろん、main.go の import を gogo-test2 に変更すれば参照する。
あれ、もしかしたらそれで問題ないのか?
そもそも gogo を自分で実装したものを使う時点で gogo-test1 とは何の関係もなくなっているのだ。
なので、関係をなくした v5を作った。
これを gogo-test1 の人が見て、あら私もこっちの gogo を使ってみたいわ、と思ったらこうなる。
うーん、これでよいような気もする。
では、gogo-test2 の module を yoshio に変更してみよう。
go.mod を変更すると main.go の import も変更しないといけなかった。
しかし、これだと git clone しないといけないのだったら gogo-test2.git だとわからないんじゃなかろうか?
gogo-test1/v2 の go.mod を gogo-test2/v6 に変更したらやはりエラーになった。
$ go get
go: github.com/hirokuma/gogo-test2@v0.0.0-20211121012830-b239fb1fd1ae: parsing go.mod:
module declares its path as: github.com/hirokuma/yoshio
but was required as: github.com/hirokuma/gogo-test2
こういう場合も replace で対応するようだ。
なので、module と実物のパスが異なってもなんとかなりそうだ。
0 件のコメント:
コメントを投稿
コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。
注: コメントを投稿できるのは、このブログのメンバーだけです。