go modules 是否支持升级传递依赖?

Does go modules support upgrading transitive dependencies?

假设我有一个 go 模块,每个依赖项都指向相同传递依赖项的不同版本。

example.com/foo v1.1 --> example3.com/baz v0.1
example2.com/bar v2.1 --> example3.com/baz v0.2

说我在 v0.2 中发现了一个错误,这是由 go modules minimum version algorithm 解决的版本,并且想升级所有指向特定版本的依赖项传递依赖。我们称它为 example3.com/v0.4.

是否有我可以 运行 升级 example.com/fooexample2.com/bar 的命令,以便 example3.com/v0.4 满足传递依赖关系(如果存在)?

理想情况下,我会调用 go get <some flag> example3.com/bar v0.4,结果类似于:

example.com/foo v1.x --> example3.com/baz v0.4
example2.com/bar v2.x --> example3.com/baz v0.4

Go 的依赖项只有特定的最低版本——它们不固定确切或最高版本,并且假设依赖项在发展过程中通常保持兼容。所以 go get example3.com/bar@v0.4 升级 example3.com/barv0.4,并将 降级 任何依赖于版本 高于 v0.4,但它会假设针对 v0.1v0.2 编写的任何内容或多或少是兼容的——您也许可以验证使用 go test all.

所以没有内置命令可以直接执行您想要执行的操作。


也就是说,您可以使用 go mod graphgrep 来确定哪些外部模块依赖于 any example3.com/bar。然后你可以使用 sed 将这些行砍到模块路径,并使用 go get:

升级这些模块
MODS=$(go mod graph | grep '@.* example3.com/bar@.*' | sed 's/@.*//')
go get -d $MODS

可以 使用 go list -json all 更精确地做到这一点,这将为你提供有关 导入的结构化信息主模块。 DepsImportPathModule 字段可能足以确定哪些包需要更新。 (可能有一种优雅的方法可以使用 jq 来过滤和转换它,但我今天没有足够的带宽来解决这个问题。)