go.sum的内容以及go应用真正使用的模块

new*_*bee 15 dependencies go dependency-management go-modules

我正在尝试将 go.sum 的行为go mod tidy(以及 go.sum 的结果内容)与 的输出进行比较go list -m all。\n阅读文档,我了解 go.sum 包含 go.mod 和依赖项中声明的依赖模块的完整列表\' go.mod 文件,go list -m all显示执行过程中真正加载的模块。\n例如,一个包含 logrus 和 prometheus 的应用程序如下所示:

\n

go.mod

\n
module mytest\n\ngo 1.14\n\nrequire (\n        github.com/prometheus/common v0.4.0\n        github.com/sirupsen/logrus v1.8.1\n)\n
Run Code Online (Sandbox Code Playgroud)\n

主程序

\n
package main\n\nimport "github.com/sirupsen/logrus"\nimport "github.com/prometheus/common/version"\n\nfunc main() {\n  logrus.Info("Hello World")\n  logrus.Infof("Prometheus info: %v", version.Info())\n}\n
Run Code Online (Sandbox Code Playgroud)\n

之后go mod tidy,go.sum 显示了 go.mod 请求的 logrus v1.8.1 和 prometheus v0.4.0 的依赖项 1.2.0;go list -m all仅显示 v1.8.1。

\n

总和

\n
[...]\ngithub.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=\ngithub.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=\ngithub.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=\n[...]\n
Run Code Online (Sandbox Code Playgroud)\n

执行列表的输出

\n
[...]\ngithub.com/sirupsen/logrus v1.8.1\n[...]\n
Run Code Online (Sandbox Code Playgroud)\n

说应用程序真正使用的模块由 列出是否正确go list -m all

\n

根本问题是静态代码分析检测到 go.sum 中列出的不安全模块版本,但实际上这些版本不会显示在 中go list -m all,因此应用程序不应该真正使用它们,而只能在构建阶段下载选择合适的最小版本。

\n

一些参考:

\n

https://go.dev/ref/mod#go-mod-tidy

\n
\n

go mod tidy 的行为就像启用了所有构建标签一样,因此它将考虑特定于平台的源文件和需要自定义构建标签的文件,即使这些源文件通常不会构建。

\n
\n

https://go.dev/ref/mod#go-sum-files

\n
\n

go.sum 文件可能包含模块的多个版本的哈希值。\ngo 命令可能需要从依赖项的多个版本\n 加载 go.mod 文件,以便执行最小版本选择。go.sum 还可能包含不再需要的模块版本的哈希值(例如,升级后)。

\n
\n

https://github.com/golang/go/wiki/Modules#is-gosum-a-lock-file-why-does-gosum-include-information-for-module-versions-i-am-no-longer-使用

\n
\n

[...]此外,您的模块的 go.sum 记录构建中使用的所有直接和间接依赖项的校验和(因此您的 ngo.sum 通常会比 go.mod 列出更多的模块)。

\n
\n

https://github.com/golang/go/wiki/Modules#version-selection

\n
\n

最小版本选择算法用于选择构建中使用的所有模块的版本。对于构建中的每个模块,由最小版本选择选择的版本始终是主模块或其依赖项之一中的 require 指令明确列出的语义上最高的版本。

\n

例如,如果您的模块依赖于A具有 a 的模块require D v1.0.0,并且您的模块还依赖于具有Ba 的模块require D v1.1.1,则最小版本选择将选择 D 的 v1.1.1 包含在构建中(假定它是列出的最高\n需要版本)。[...] 要查看所选模块版本的列表\n(包括间接依赖项),请使用go list -m all.

\n
\n

小智 9

go list -m all是的,正确地说应用程序真正“使用”的模块由(根据您提供的链接的文档)列出。“使用”表示在构建时选择用于编译应用程序的 go 代码的包。

我们在静态分析工具上遇到了类似的问题,我们必须更改配置以使用go list -m all(转储到文件中)的输出而不是go.sum.