假设我有一个go模块,每个依赖项都指向同一传递依赖项的不同版本。
example.com/foo v1.1 --> example3.com/baz v0.1
example2.com/bar v2.1 --> example3.com/baz v0.2
假设我在v0.2
中发现了一个bug,这是go modules
最小版本算法解决的版本,并且想要升级指向传递依赖的指定版本的所有依赖。设为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
Go的依赖项只有特定的最小版本——它们不确定确切的或最大的版本,并且假设依赖项在演变过程中通常保持兼容。因此,go get example3.com/bar@v0.4
将将example3.com/bar
升级到v0.4
,并将降级任何依赖于版本高于v0.4
的内容,但它将假设针对v0.1
或v0.2
编写的任何内容或多或少是兼容的-您可以使用go test all
进行验证。
所以没有一个内置的命令可以直接做你想做的事情。
也就是说,您可以使用go mod graph和grep
来确定哪些外部模块依赖于任何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
,但我今天没有带宽来弄清楚。)