假设我有一个 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/foo
和 example2.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
答案 0 :(得分:3)
Go 的依赖项只有特定的最小版本——它们没有固定确切或最大版本,并且确实假设依赖项通常随着它们的发展而保持兼容。所以go get example3.com/bar@v0.4
会升级 example3.com/bar
到v0.4
,并且会降级任何依赖高于的版本em> v0.4
,但它会假设针对 v0.1
或 v0.2
编写的任何内容或多或少是兼容的——您或许可以使用 go test all
来验证这一点。>
因此没有一个内置命令可以直接执行您要执行的操作。
也就是说,您可以使用 go mod graph 和 grep
来确定哪些外部模块依赖于 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
更精确地做到这一点,它会为您提供有关主模块导入的包的结构化信息。 Deps
、ImportPath
和 Module
字段可能足以确定哪些包需要更新。 (可能有一种优雅的方法可以使用 jq
对其进行过滤和转换,但我今天没有足够的带宽来解决这个问题。)