gomod的版本选择策略

Go modules的历史

  • 1.11版本引入了Go Modules,默认GO111MODULE=off,需要手动修改至on才启动module模式。
  • 1.13版本中默认GO111MODULE=auto,会自动检测是否包含go.mod,如果包含则启用module模式。
  • 从1.14版本GoMod可供生产使用,并且鼓励所有用户从其他依赖关系管理系统迁移到Go Mod。
  • 1.16版本默认GO111MODULE=on,即一直启动module模式。

版本选择

通过require module version可以在go.mod文件中直接声明依赖项的版本,如require M v1.2.3

如果在go.mod文件中未直接require声明引入依赖的版本,在运行go build/go test等命令时会自动查找合适的module,并使用最新的版本作为require直接添加到go.mod文件中。

例如:import对应依赖M最新标记的release版本是1.2.3go.mod文件中将会出现require M v1.2.3,这表示M是允许>=v1.2.3版本的依赖项(<v2,给定v2被视为与v1不兼容)。

当项目中引入多个依赖,且部分存在依赖的同时有多个版本被引入时,Go是如何处理的呢?

更多内容分享,欢迎关注公众号:Go开发笔记

最小版本选择算法

最小版本选择算法用于选择build中使用的所有modules的版本。对于build中的每个module,通过最小版本选择算法选择的版本始终是主module或其依赖项之一通过require指令显式列出的版本中语义最高的版本,简单来说就是:使用require中的最高版本。

例如:如果你的module,依赖的module A需要require D v1.0.0,依赖的module B需要require D v1.1.1,最小版本选择算法将会选择D的v1.1.1版本用于build。即使后期D有v1.2.0版本可用,未显式requirego.mod中,仍将使用v1.1.1版本用于build。

D v1.0.0 -> module A
                      --> mymod(D v1.1.1)
D v1.1.1 -> module B

检查选择的版本

如何查看build时选择的版本呢?

可以通过运行go list -m命令进行检查。

go list -m all可以查看所有依赖module的build版本。
go list -m moduleName可以查看指定依赖module的build版本。