准备,设置,GoCenter!为Go模块转换项目

更新:截至2021年5月1日,GoCenter中央存储库已经关闭,所有功能都已弃用。有关中心日落的更多信息,请阅读弃用博客文章

自从引入Go的新依赖管理系统走1.11后来,GoLang开发人员接受了包版本控制解决方案。这样做的人可以使用GoCenter存储库的不可变公共去模块,获得更快的围棋构建用更多的健壮可靠的Go管道

但是,将现有项目转换为使用Go模块并不总是那么容易,特别是如果项目已经通过GoLang在包管理解决方案方面的许多早期尝试而发展。

为了帮助GoLang社区正确地采用Go模块,我们将采用开源etcdKubernetes使用的键值数据存储,通过转换过程。这是展示最佳实践的一个很好的真实示例,因为它足够复杂,可以呈现一些常见的挑战,包括代码生成器的使用以及需要正确感知模块的静态分析工具。

Go模块转换最佳实践

这个转换过程通过成功的测试得到了验证,结果可以在a中看到Pull请求正在更新544个文件

第一步:准备行动。国防部文件

对于以前从未使用过模块的项目(所以没有go.mod文件),或任何现在已弃用的依赖项管理解决方案,该过程将非常简单。你只需要跑步Go mod tidy整洁在项目的根目录中。这将生成一个新的、已填充的go.mod文件中包含模块的依赖项。

但是,如果项目使用了这些较旧的解决方案之一,例如dep、glide、govendor或godep,则需要运行mod init生成填充的go.mod文件。该命令遵循旧格式中描述的依赖项版本。

事实证明,etcd项目,有一个go.mod文件,尽管它从未在项目的构建系统中启用。问题是模块名没有正确的版本标识符,因为当前版本标记是v2 +。这需要改变为v3由于…的含义语义导入版本控制

这包括执行以下程序:

  1. 更新etcd的go.mod文件来修复模块名称以包含v3后缀。去更新。国防部文件
  2. 更新所有导入以包含版本号。我们编写了一个脚本,使我们更容易更改所有引用。完成后,更改如下所示:更新进口

步骤2:启用Go模块

为了使go客户端能够使用go模块,需要设置GO111MODULE =对

因为,正如我们所指出的,etcd项目已经开始尝试了。国防部文件, one might expect that this had already been done. But it has not, and that absence confirms that the project isn’t already using go modules.

注意:从Go 1.13开始,这个步骤将不再需要,因为Go模块将默认启用。

步骤3:更新测试中的导入

在上面的过程中,我们更新了go。Mod用于组成etcd主模块的文件,以便使用v3版本标签。,主模块现在被标记为v3,我们还需要更新etcd项目测试中的导入v3同时,确保它们导入了正确版本的主模块。

步骤4:其他更新

在进行了这些更改之后,您可能期望状态良好—毕竟,应用程序模块现在已经全部转换为使用go模块,并使用了适当的版本标记。

不过,还没那么快。一旦开始运行测试,就会发现需要处理另外两个场景:

  1. 静态分析etcd使用了golint、gosimple、staticcheck、ineffassign等工具,但其中一些工具不是模块感知的,无法识别模块路径,也无法通过必要的检查。在etcd的情况下,下面没有v3文件夹etcd-io / etcd但是导入(或模块路径)包含v3,例如etcd-io etcd / v3其他工具是模块感知的,但必须在Go 1.12的最新版本中可用。如果构建系统在1.11上,它们也需要移动到1.12。
  2. 代码生成器比如protobuf。更新.proto文件,以便生成具有正确版本导入的代码。

第五步:使用GoCenter

在构建过程中,您可能会注意到在etcd管道的各个阶段执行了许多go get命令。

加快GoLang应用程序的构建时间,并且为了保证etcd管道中使用的Go模块版本的不可变性和可用性,请更新etcd构建以使用GoCenter-这就像设置一样简单GOPROXY = https://gocenter.io

争取更多

正如您所看到的,将Go项目转换为使用Go模块很简单,但是有一些细节可能会减慢您的速度。通过选择这个具有如此丰富的遗产的项目来演示流程,我们相信我们已经触及了需要处理的大多数场景,为您提供了一个可能面临的很好的示例。