go 模块是否支持升级可传递依赖项?

时间:2021-07-30 22:04:29

标签: go go-modules

假设我有一个 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

1 个答案:

答案 0 :(得分:3)

Go 的依赖项只有特定的最小版本——它们没有固定确切或最大版本,并且确实假设依赖项通常随着它们的发展而保持兼容。所以go get example3.com/bar@v0.4升级 example3.com/barv0.4,并且会降级任何依赖高于的版本em> 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 对其进行过滤和转换,但我今天没有足够的带宽来解决这个问题。)