incompatible 标示 本文未发布 发布文章
为了确保从 GOPATH
到模块的顺利过渡,go
命令可以通过添加一个 go.mod
文件,从尚未迁移到模块的软件库下载并以模块感知模式构建软件包。
当 go
命令从版本库中 直接下载一个指定版本的模块时,它会查找模块路径的版本库 URL,将版本映射到版本库中的一个修订版,然后在该修订版中提取版本库的存档。如果 模块的路径等于 版本根目录,并且版本根目录不包含 go.mod
文件,go
命令在模块缓存中合成一个 go.mod
文件,其中包含一个 module
指令,而没有其他内容。由于合成的 go.mod
文件不包含其依赖的 require
指令,依赖它们的其他模块可能需要额外的 require
指令(带有 //间接
注释),以确保每个依赖模块在每次构建时都被获取相同的版本。
当 go
命令从一个 代理 下载模块时,它将 go.mod
文件与其他模块内容分开下载。如果原始模块没有 go.mod
文件,代理应该提供一个合成的 go.mod
文件。
+incompatible
版本
一个在主版本 v2 或更高版本发布的模块必须在其模块路径上有一个匹配的 主版本后缀。例如,如果一个模块以 v2.0.0
发布,其路径必须有/v2
后缀。这允许 go
命令将一个项目的多个主要版本视为不同的模块,即使它们是在同一个仓库开发的。
在go
命令添加到go
命令时,引入了主要版本后缀要求,并且许多存储库已经使用主要版本2
或更高版本标记了释放。为了与这些存储库保持兼容性,go
命令将+incompatible
后缀添加到具有主要版本2或更高版本的版本,而无需go.mod
文件。+incompatible
表示版本是与具有较低主要版本号的版本相同的模块;因此,go
命令可以自动升级到更高的+incompatible
版本,即使它可能会破坏构建。
考虑以下示例要求:
require example.com/m v4.1.2+incompatible
版本v4.1.2 +incompatible
是指语义版标签v4.1.2
在提供模块example.com/m
的存储库中。模块必须位于存储库根目录(即,Module 根路径也必须是example.com/m
),并且不得存在go.mod
文件。该模块可以具有较低的主要版本号,如v1.5.2
,而go
命令可以自动升级到v4.1.2 +incompatible
,从这些版本中(有关如何升级工作的信息,请参阅最小版本选择(MVS)。
标记版本v2.0.0
后迁移到模块的存储库通常应该发布一个新的主要版本。在上面的示例中,作者应该使用路径example.com/m/v5
创建一个模块,并且应该发布版本v5.0.0
。作者还应更新模块中包的导入以使用前缀example.com/m/v5
而不是example.com/m
。有关一个更详细的示例,请参见Go Modules: v2 and Beyond。
请注意,+incompatible
后缀不应显示在存储库中的标记上;将忽略像v4.1.2 +incompatible
。后缀仅出现在go
命令使用的版本中。有关版本和标记之间的区分,请参阅映射版本以提交。
另请注意,+incompatible
后缀可能会显示在伪版本上。例如,v2.0.1-20200722182040-012345abcdef +incompatible
可以是有效的伪版本。
最小模块兼容性
在主要版本2或更高版本上释放的模块是在其模块路径的主要版本后缀。模块可以在其存储库中的主要版本子目录中。这对构建 GOPATH
模式时,这对程序包的包装具有导入包中的包的含义。
通常在 GOPATH
模式中,包存储在与其目录中的存储库的根路径)与其目录匹配的目录中在存储库中。例如,在子目录sub
中,带有根路径example.com/repo
的存储库中的包将被存储在$ GOPATH/src/emmate.com/repo/中sub
并且将被导入example.com/repo/sub
。
对于具有主要版本后缀的模块,可能希望在目录$GOPATH/src/emply.com/repo/v2/sub
中找到包example.com/repo/v2/sub
。这将需要模块在其存储库的v2
子目录中开发。go
命令支持这一点,但不需要它(请参阅映射版本以提交)。
如果模块不是在主要版本子目录中开发,则其在GOPATH
中的目录将不包含主要版本后缀,并且可以在没有主要版本后缀的情况下导入其软件包。在上面的示例中,该包将在$GOPATH/src/ emment.com/repo/sub
中找到,并且将被导入example.com/repo/sub
。
这为旨在建在模块模式和GOPATH
模式下的包的问题:模块模式需要一个后缀,而GOPATH
模式没有。
为解决此问题,在 Go 1.11中添加了最小的模块兼容性,并被回到 Go 1.9.7和1.10.3。当导入路径被解析为GOPATH
模式下的目录时:
- 在解决表单
$modpath/$vn/$dir
中的导入时:$modpath
是一个有效的模块路径,$vn
是一个主要版本后缀,$dir
是一个可能的空子目录,
- 如果满足以下所有内容:
- 封装
$modpath/$vn/$dir
不存在于任何相关vendor
目录。 go.mod
文件存在于与导入文件相同的目录中,或者在任何父目录中,到$GOPATH/src
root,- 没有
$GOPATH[i]/src/$modpath/$vn/$suffix
目录存在(对于任何根目录$GOPATH[i]
), - 文件
$GOPATH[d]/src/wrmodpath/2.mod
存在(对于某些根目录$GOPATH[d]
)并将模块路径称为$modpath/$vn
,
- 封装
- 然后导入
$modpath/$vn/$dir
已解析为目录$GOPATH[d]/src/$modpath/$dir
。
此规则允许已迁移到模块的软件包,以导入已在内置于GOPATH
模式中迁移到模块的其他包的程序,即使未使用主要版本子目录。
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。