go.sum 的内容和 go 应用程序真正使用的模块

Content of go.sum and modules really used by a go application

我正在尝试将 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 请求的 logrus v1.8.1 和 prometheus v0.4.0 的依赖项 1.2.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 中,因此不应真正使用它们由应用程序,但仅在构建阶段下载到 select 适当的最小版本。

一些参考:

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

go mod tidy acts as if all build tags are enabled, so it will consider platform-specific source files and files that require custom build tags, even if those source files wouldn’t normally be built.

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

The go.sum file may contain hashes for multiple versions of a module. The go command may need to load go.mod files from multiple versions of a dependency in order to perform minimal version selection. go.sum may also contain hashes for module versions that aren’t needed anymore (for example, after an upgrade).

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

[...]In addition, your module's go.sum records checksums for all direct and indirect dependencies used in a build (and hence your go.sum will frequently have more modules listed than your go.mod).

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

The minimal version selection algorithm is used to select the versions of all modules used in a build. For each module in a build, the version selected by minimal version selection is always the semantically highest of the versions explicitly listed by a require directive in the main module or one of its dependencies.

As an example, if your module depends on module A which has a require D v1.0.0, and your module also depends on module B which has a require D v1.1.1, then minimal version selection would choose v1.1.1 of D to include in the build (given it is the highest listed require version). [...] To see a list of the selected module versions (including indirect dependencies), use go list -m all.

是的,go list -m all 列出了应用程序真正“使用”的模块(根据您提供的 link 的文档)。 “已用”是指在构建时选择的包,用于编译您的应用程序的 go 代码。

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