我试图将go mod tidy的行为(以及go.sum的结果内容)与go list -m all的输出进行比较。阅读文档后,我了解到go.sum包含在go.mod和依赖项的go.mod文件中声明的所有依赖模块列表,go list -m all显示了在执行过程中真正加载的模块。例如,包括logrus和prometheus这样的应用程序:
go.mod
module mytest
go 1.14
require (
github.com/prometheus/common v0.4.0
github.com/sirupsen/logrus v1.8.1
)main.go
package main
import "github.com/sirupsen/logrus"
import "github.com/prometheus/common/version"
func main() {
logrus.Info("Hello World")
logrus.Infof("Prometheus info: %v", version.Info())
}在go mod tidy之后,go.sum显示go.mod请求的logrusv1.8.1和1.2.0对Prometheusv0.4.0的依赖;go list -m all只显示v1.8.1。
go.sum
[...]
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
[...]go表的输出
[...]
github.com/sirupsen/logrus v1.8.1
[...]如果说应用程序真正使用的模块是由go list -m all**?**列出的,正确吗?
潜在的问题是静态代码分析会检测到go.sum中列出的不安全模块版本,但实际上这些版本不会出现在go list -m all中,因此应用程序不应该真正使用这些版本,而应该只在构建阶段下载以选择合适的最小版本。
一些参考资料:
https://go.dev/ref/mod#go-mod-tidy
go mod整洁的行为就好像所有的构建标记都启用了一样,所以它将考虑特定于平台的源文件和需要自定义构建标记的文件,即使这些源文件通常不会被构建。
https://go.dev/ref/mod#go-sum-files
go.sum文件可能包含一个模块的多个版本的散列。go命令可能需要从依赖项的多个版本加载go.mod文件,以便执行最小版本选择。go.sum还可能包含不再需要的模块版本的散列(例如,升级后)。
除了
...In之外,您的模块的go.sum记录了构建中使用的所有直接和间接依赖项的校验和(因此,go.sum通常会列出比go.mod更多的模块)。
https://github.com/golang/go/wiki/Modules#version-selection
最小版本选择算法用于选择构建中使用的所有模块的版本。对于构建中的每个模块,通过最小版本选择所选择的版本始终是主模块中的require指令或其依赖项中显式列出的版本中语义最高的版本。
例如,如果您的模块依赖具有A的模块require D v1.0.0,而您的模块也依赖于具有require D v1.1.1的模块B,那么最小的版本选择将选择D的v1.1.1在构建中包含(考虑到它是列出的最高需求版本)。..。若要查看所选模块版本的列表(包括间接依赖项),请使用go list -m all.
发布于 2022-01-12 17:09:57
是的,正确的说法是,应用程序真正“使用”的模块是由go list -m all列出的(根据您提供的链接)。所谓“使用”,是指在构建时为编译应用程序的go代码而选择的包。
静态分析工具也有类似的问题,我们不得不更改配置,以使用go list -m all (转储到文件中)的输出,而不是go.sum。
https://stackoverflow.com/questions/70128040
复制相似问题