Go模块已经为Go开发带来了秩序,但也存在一些潜在的杂乱。治理模块尤其是伪版本可能很难题,尤其是在要举行一些最新更改的情况下。

JFrog GoCenter是一个免费的版本话棋模块堆栈,现在它包罗了一些主要的更新,可以辅助你坚持这个最佳实践。首先让我们看看伪版本是若何事情的,以及您可以期望从这些更改中获得什么。我们还提供了一些指导,让您在升级到1.13或更高版本时保持Go的构建事情。

Go 的模块版本化

对Go模块举行版本化是一个要害特征,它为开发人员提供了一种方式来确保他们的应用程序使用他们想要的依赖项。在对模块举行版本控制时,应用程序可以指定依赖的模块版本,由于我们知道模块版本与其他组件运行时兼容问题

Go模块版本是通过在底层源存储库中符号其修订来分配的。go下令使用尺度形式vX.Y.Z的语义版本控制,以此来形貌模块的版本。版本号凭据API的转变而转变,如下图:

从这个尺度花样中,可以对照模块版本,以确定哪个应该被认为是最当前的,哪个应该被认为是最不当前的。

使用Pseudo-Versions(伪版本)

版本化的Go模块是已经公布的,供一样平常使用的模块,应该是大多数开发人员的首选。然则,在某些情况下,您不能公布模块的最新版本。

例如,一个团队可能需要在开发时代共享一个暂且版本。特别是当一个依赖的项目还没有公布版本时,以是它还没有被符号上版本。类似地,您可能需要针对尚未符号(打tag)的提交举行开发。

要使用未符号版本的模块作为依赖项,必须通过其伪版本标识符引用它。伪版本的花样如下:

伪版本有三种可接受的形式:

· Vx.0.0-yyyymmddhhmms-abcdefxyz,当在目的提交之前没有使用适当的主版本举行早期版本提交时

· vX.Y.Z-pre.0.yyyymmddhhmms -abcdefxyz。当目的提交之前的最新版本提交是vX.Y.Z-pre时,

· vX.Y.(Z + 1) 0.yyyymmddhhmms -abcdefxyz。当目的提交之前的最新版本提交是vX.Y.Z时,

作为一种最佳实践,伪版本字符串不应该是手工输入的。go下令将接受通俗的提交散列并自动将其转换为伪版本。此方式有助于凭据天生的时间戳对照修订。

例如,一个go get下令可能只使用模块查询的提交散列(githash):

同时,这里存在无法让go下令自动天生伪版本存在问题:

·伪版本介入最小版本选择。若是它的版本前缀不准确,那么伪版本的优先级可能比随后的版本更高,从而有用地将模块牢固到提交

·伪版本中的提交日期提供了伪版本之间的总顺序,因此若是它被编辑,就会打乱顺序

只管有这样的建议,但有时我们会手工修改的go模块中可能存在一个伪版本。在其他情况下,完整的伪版本字符串可能由第三方工具天生。

更严酷的规则Go 1.13

GO的发行版1.12,Go对伪版本引用举行了修改。大多数涉及伪版本的操作都接受版本字符串和日期的随便组合,而且只要该修订存在,就会剖析为基础修订(通常是Git提交散列,git hash)。

然而Go 1.13的公布带来了更严酷的规则,以解决上面提到的问题。Go 1.13对“Go”下令接受的伪版本举行了限制,使一些以前接受但不规范的版本无效。

现在,go客户端将针对版本控制元数据对伪版本的差别元素执行一些验证:

· 版本前缀的花样必须为vX.0.0,或者从命名修订版本的祖先上的标签派生,或者从包罗命名修订版本本身上的构建元数据的标签派生。

· 日期字符串必须与修订版的UTC时间戳匹配。

· 修订的简称必须使用与go下令天生的字符相同的字符数。(对于git使用的SHA-1散列,为12位数字的前缀。)

· 仅当对应的主要版本需要伪版本,而且仅当基础模块没有go.mod文件时,伪版本才包罗“ +不兼容”( ‘+incompatible’)后缀

· 纵然从署理剖析了模块之后,go客户端也会实验从校验和服务器获取校验和内容,该服务器(Go sumdb)将执行相同的伪版本验证规则,并拒绝提供校验和内容,防止署理举行伪装

1.13之前的Go版本不执行有关伪版本组件的这些规则。这意味着,纵然用户不应该手动天生伪版本,也可以在多个伪版本中使用相同的提交哈希,而不会泛起任何问题。

若何修复不准确的伪版本

为了迁移到1.13,开发人员必须纠正所有不符合上述要求的伪版本引用。否则go客户端会符号一个异常:

go get golang.org/x/sys@v0.0.0-20190726090000-fde4db37ae7a: invalid

pseudo-version: does not match version-control timestamp (2019-08-13T06:44:41Z)

幸运的是,通过建立伪版本引用的go.mod文件很容易做到这一点。

若是go.mod文件require指令的伪版本不准确,可以通过以下方式更正此错误:

  1. 用提交哈希字符串替换完整的伪版本引用

运行go mod tidy以使go客户端执行准确的替换。

[if !supportLists]2. [endif]若是其中一个通报依赖项引用了无效的伪版本,则可以replace在go.mod文件中使用指令来强制更正:

GoCenter 若何应对上述转变

GoCenter的目的是与Go版本无关(纵然在1.13之前,我们也支持所有Go模块版本)。JFrog的社区工程团队已经对GoCenter举行了主要的更新,以支持Go 1.13的所有版本,我们正在举行进一步的更新,以知足Go 1.14的要求。

GoCenter现在通过重定向到准确的伪版原本辅助您遵从伪版本验证。当请求模块下载错误的伪版本时,GoCenter将使用准确的版本修改.info中的元数据。

要使用GoCenter,请设置GOPROXY

针对Go 1.12

对于Go 1.12用户,GoCenter将更新Go。用准确的伪版本保留在其存储库中的go.mod文件。GoCenter仍将提供在此更改之前在GoCenter中处置的不准确的伪版本。

针对Go 1.13

Go 1.13用户将收到一条错误新闻,指出准确的伪版本。

以便在go.mod文件中更新准确的伪版本,Go 1.13用户只需要改变Go get包罗伪版本中的提交哈希(git hash)部门。

若是希望笼罩此行为并让GoCenter提供前面处置的错误伪版本,则可以设置GOSUMDB= off。

Go 1.14对于Go Module的调换

正如我们所注意到的,JFrog正在修改GoCenter以支持Go 1.14。以下是该版本中可能会影响模块操作的一些更改,您可能希望领会这些更改:

1. Go下令标志

· go get下令不再接受-mod标志

· 若是没有顶级供应商目录而且go.mod文件是只读的,则默认设置-mod = readonly

· 引入了-modfile = file新符号,该符号指示go下令读取/写入备用go.mod文件,还将使用备用go.sum文件。只管仍必须存在名为go.mod的文件才气确定模块的根目录

2.go.mod文件更改

· 除非明确要求或已经要求,go get不会升级到+不兼容的主要版本

· go下令(go mod tidy除外)不会删除require指令,该指令指定主模块的其他依赖项已经隐含的间接依赖项的版本

· 设置-mod = readonly标志时,go下令不会因缺少go指令或任何错误而失败

3. 模块下载

· go下令现在在模块模式下支持Subversion存储库

· Go下令现在包罗来自模块署理和其他HTTP服务器的纯文本错误新闻的摘要。仅当错误新闻是有用的UTF-8且由垄断图形字符和空格组成时,才会显示错误新闻。

和GoCenter一起前进

随着Go模块获得更大的接受度,尺度肯定会改变。您可以依赖JFrog GoCenter来跟上这些转变,并在需求生长时辅助您战胜障碍。

若是你还没有探索GoCenter的免费Go模块库,我们约请你去探索!它有一个厚实的UI,可以辅助您检查所有600,000多个Go模块的数据,可以辅助您获得对所使用的GoLang依赖项的壮大支持。

**学习更多技术知识可以关注我们的在线课堂

关注微信民众号:JFrog杰蛙DevOs, 获取课程通知**