2023/12/02

最近の go get

"go get" の仕様が変わったという話は聞いていたし、実際に違いも感じるのだが、「なんとなく」で go get したり go mod tidy したりしている。
そのせいだと思うが、git clone してビルドするだけなのに go.mod が更新されていたり go.sum が更新されたりして落ち着かない。
それに過去の仕様を覚えているというわけでもない。

あきらめて、いまの go v1.21 くらいだとどう使うのが普通なのか調べておこう。


なるべく go.dev から参照していきたい。解説記事を読んだとしても、私が過去の仕様を知らないので「これは古い内容だ」という判断ができないのだ。

まず、go v1.17 から "go get" で実行ファイルのインストールが行われなくなった。
その代わりに "go install" を使いなさいということだ。

Deprecation of 'go get' for installing executables - The Go Programming Language
https://go.dev/doc/go-get-install-deprecation

その代わり "go get" がどうなったかというと、go v1.18 から go.mod への追加、更新、削除を行うようになったということだ。


今の "go get" の説明はここにあった。

go command - cmd/go - Go Packages
https://pkg.go.dev/cmd/go#hdr-Add_dependencies_to_current_module_and_install_them

"Add dependencies to current module and install them" というタイトルだったが、実際は更新や削除までやるようだ。
コマンド単体の説明があったので、こちらの方がよいか。

go get
https://go.dev/ref/mod#go-get

  • Upgrade a specific module.
  • Upgrade modules that provide packages imported by packages in the main module.
  • Upgrade or downgrade to a specific version of a module.
  • Update to the commit on the module's master branch.
  • Remove a dependency on a module and downgrade modules that require it to versions that don't require it.
  • Upgrade the minimum required Go version for the main module.
  • Upgrade the suggested Go toolchain, leaving the minimum Go version alone.
  • Upgrade to the latest patch release of the suggested Go toolchain.

多い、多いよ。。。

勝手に分類するなら、個別パッケージ向けかメインモジュール向けかというところか。

個別パッケージ向け

# Upgrade a specific module.
$ go get golang.org/x/net

# Upgrade or downgrade to a specific version of a module.
$ go get golang.org/x/text@v0.3.2

# Update to the commit on the module's master branch.
$ go get golang.org/x/text@master

# Remove a dependency on a module and downgrade modules that require it
# to versions that don't require it.
$ go get golang.org/x/text@none

# Upgrade to the latest patch release of the suggested Go toolchain.
$ go get toolchain@patch

メインモジュール向け

# Upgrade modules that provide packages imported by packages in the main module.
$ go get -u ./...

# Upgrade the minimum required Go version for the main module.
$ go get go

# Upgrade the suggested Go toolchain, leaving the minimum Go version alone.
$ go get toolchain


メインモジュールというのはカレントディレクトリか親ディレクトリの go.mod を指すそうだ。go.dev のドキュメントは "go get" や "go.mod" のフォントが若干他とは違っているようだけど、そのくらいだと見分けが付けづらいのよねぇ。

昔の "go get -d" が go v1.18 からはデフォルトの挙動になっている。"-d" がない場合はそのパッケージのビルドとインストールまでやっていた挙動がなくなったというのが仕様変更でよく言われている内容ということになる。

ここの用例ではオプションがあるけれども "go get" だけでも動作する。パッケージを指定していないのでメインモジュールに向けての操作になるはず。"-u" がないからアップグレードでもないし indirect な require だけ更新するのだろうか?


ここまで "go get" を見てきたが、パッケージの取得だけなら "go mod tidy" を使うイメージを持っている。が、 "go mod tidy" で go.sum が更新されたことがあるような気がするのだ。
なんとなく "go get" だけ実行したときと同じような感じがする。

go mod tidy
https://go.dev/ref/mod#go-mod-tidy

  • adds any missing module requirements necessary to build the current module’s packages and dependencies
  • removes requirements on modules that don’t provide any relevant packages.
  • It also adds any missing entries to go.sum and removes unnecessary entries.

こちらは go.modとソースコードの関係性を重視しているのか? "go get" は "-u" 指定しない限りは indirect くらいしか更新しないようだが "go mod tidy" は不要なパッケージがあれば indirect でなくても削除していた。ただ新しいバージョンがあっても更新はしないので、ビルドできるかどうかだけ判断しているのかな?

0 件のコメント:

コメントを投稿

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

注: コメントを投稿できるのは、このブログのメンバーだけです。