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

更新:自2021年5月1日起,GoCenter中央存储库已被淘汰,所有功能已弃用。有关中心日落的更多信息,请阅读弃用博客文章
自从引进Go的新依赖管理系统在走1.11后来,GoLang开发人员已经接受了包版本控制解决方案。可以使用GoCenter存储库的不可变公共去模块,获得更快的Go构建用更多健壮可靠的Go管道.
但是将现有项目转换为使用Go模块并不总是容易的,特别是如果该项目是通过GoLang早期对包管理解决方案的许多尝试而发展起来的。
为了帮助GoLang社区正确地采用Go模块,我们将采用开源etcdKubernetes使用的键值数据存储。这是展示最佳实践的一个很好的现实示例,因为它足够复杂,可以呈现一些常见的挑战,包括代码生成器和静态分析工具的使用,这些工具需要正确地识别模块。
Go模块转换最佳实践
此转换过程已通过成功的测试得到验证,结果可在拉请求更新544个文件.
步骤1:准备出发。国防部文件
对于一个以前从未使用过模块的项目(因此没有go.mod文件),或者任何现在已弃用的依赖项管理解决方案,这个过程将非常简单。你只需要跑整理衣柜在项目的根目录中。这将生成一个新的、已填充的go.mod文件中包含模块的依赖项。
但是,如果项目使用了旧的解决方案之一,例如dep、glide、govendor或godep,那么您将需要运行mod init来生成go.mod文件。此命令支持旧格式中描述的依赖项版本。
这个etcd项目,做有一个go.mod文件,尽管它从未在项目的构建系统中启用。问题是模块名没有正确的版本标识符,因为当前的版本标记是v2 +.这需要改变v3由于的含义语义导入版本控制.
这包括执行以下步骤:
- 更新etcd的go.mod文件来修复模块名称,以包含
v3后缀。
- 更新所有导入以包含版本号。我们编写了一个脚本,以便更容易地更改所有引用。完成后,该更改如下所示:

步骤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模块,并使用了正确的版本标记。
不过,不要这么快。一旦开始运行测试,就会发现需要处理的两个附加场景:
- 静态分析etcd使用了诸如golint、gosimple、staticcheck、ineffassign等工具,但其中一些工具不是模块感知的,因此无法识别模块路径,无法通过必要的检查。在etcd的情况下,没有v3文件夹etcd-io / etcd但是导入(或模块路径)包含v3,例如etcd-io etcd / v3.其他工具是模块感知的,但必须在Go 1.12的最新版本中可用。如果构建系统在1.11,它们也需要迁移到1.12。
- 代码生成器如protobuf被使用。更新.proto文件,以便生成带有正确版本导入的代码。
第五步:引入GoCenter
在构建过程中,您可能会注意到在etcd管道的不同阶段执行了许多go get命令。
来加快GoLang应用程序的构建时间,为了保证etcd管道中使用的Go模块版本的不可变性和可用性,更新etcd构建以使用GoCenter-这就像设置一样简单GOPROXY = https://gocenter.io.
追求更多
正如您所看到的,将Go项目转换为使用Go模块是很简单的,但是有一些细节可能会减慢您的速度。通过选择这个具有如此丰富的遗产的项目来演示过程,我们相信我们达到了需要处理的大多数场景,为您提供了可能面临的问题的良好示例。
