2021/11/21

[golang, github]go.modのmoduleを実物と違うのにしてよいのか

go.mod に慣れていないせいかもしれないが(golang自体にも慣れていないが)、非常に難しく感じる。

文句を言っても仕方ない(か、golangのプルリクを出すとか)ので、理解に努めよう。

$ go version
go version go1.17.3 linux/amd64


golang でオリジナルのものを作るときは気にならないかもしれないが、GitHub で fork したり mirror したりして一部を書き換えたいとなると思考が止まってしまう。

 

よくあるのが、git cloneする中でも改造して使いたいのはその一部だけ、というパターンだろう。
例として、fmt.Printf するだけのリポジトリを用意した。

https://github.com/hirokuma/gogo-test1/tree/v1

main.go と gogo/gogo1.go だけだ。

ここの gogoパッケージにある Gogo() だけ使うリポジトリがこちら。

https://github.com/hirokuma/gogo-test2/tree/v1

特に変な動作はしない。

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 とか書けばいけるのかな?

https://github.com/hirokuma/gogo-test2/blob/v2/go.mod#L1

いけた。

自分より前に 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 で置き換えてみよう。

https://github.com/hirokuma/gogo-test2/blob/v4/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を作った。

https://github.com/hirokuma/gogo-test2/compare/v4...v5

これを gogo-test1 の人が見て、あら私もこっちの gogo を使ってみたいわ、と思ったらこうなる。

https://github.com/hirokuma/gogo-test1/compare/v1...v2

うーん、これでよいような気もする。

 

 

では、gogo-test2 の module を yoshio に変更してみよう。

https://github.com/hirokuma/gogo-test2/compare/v5...v6

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 で対応するようだ。

https://github.com/hirokuma/gogo-test1/compare/v2...v3

なので、module と実物のパスが異なってもなんとかなりそうだ。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。