管理模块源码

当您开发模块供他人使用时,遵循本主题所述的仓库约定可以帮助确保其他开发者更容易使用您的模块。

本主题描述了管理模块仓库时可能采取的操作。有关从一个版本修订到另一个版本时的工作流步骤序列的信息,请参阅模块发布和版本控制工作流

此处描述的一些约定是模块中必需的,而另一些则是最佳实践。本文档假定您熟悉管理依赖项中描述的基本模块使用实践。

Go 支持以下仓库用于发布模块:Git、Subversion、Mercurial、Bazaar 和 Fossil。

有关模块开发的概述,请参阅开发和发布模块

Go 工具如何找到您发布的模块

在 Go 分散式系统发布模块和检索其代码时,您可以发布模块,同时将代码保留在您的仓库中。Go 工具依赖于命名规则,这些规则包含指示模块名称和版本号的仓库路径和仓库标签。当您的仓库遵循这些要求时,Go 工具(例如 go get 命令)可以从您的仓库下载您的模块代码。

当开发者使用 go get 命令获取其代码导入的包的源码时,该命令会执行以下操作:

  1. 从 Go 源码中的 import 语句,go get 在包路径中识别模块路径。
  2. 使用从模块路径派生的 URL,该命令在模块代理服务器或直接在其仓库中定位模块源码。
  3. 通过将模块的版本号与仓库标签匹配来定位要下载的模块版本的源码,以便在仓库中发现代码。如果尚不知道要使用的版本号,go get 将定位最新的发布版本。
  4. 检索模块源码并下载到开发者的本地模块缓存。

在仓库中组织代码

遵循此处描述的约定可以简化维护并改善开发者使用您的模块的体验。将模块代码放入仓库通常与其他代码一样简单。

以下图示说明了一个包含两个包的简单模块的源码层次结构。

Diagram illustrating a module source code hierarchy

您的初始提交应包含下表中列出的文件:

文件描述
LICENSE 模块的许可证。
go.mod

描述模块,包括其模块路径(实际上是其名称)及其依赖项。更多信息请参阅go.mod 参考

模块路径将在 module 指令中给出,例如:

module example.com/mymodule

有关选择模块路径的更多信息,请参阅管理依赖项

尽管您可以编辑 go.mod 文件,但通过 go 命令进行更改会更可靠。

go.sum

包含表示模块依赖项的加密哈希值。Go 工具使用这些哈希值来验证下载的模块,尝试确认下载的模块是真实的。如果此验证失败,Go 将显示安全错误。

当没有依赖项时,该文件将为空或不存在。除了使用 go mod tidy 命令(该命令会删除不必要的条目)外,您不应编辑此文件。

包目录和 .go 源码文件。 构成模块中 Go 包和源码的目录和 .go 文件。

在命令行中,您可以创建一个空仓库,添加将作为初始提交一部分的文件,并带有一条消息进行提交。以下是使用 git 的示例:

$ git init
$ git add --all
$ git commit -m "mycode: initial commit"
$ git push

选择仓库范围

当代码应独立于其他模块中的代码进行版本控制时,您可以在模块中发布代码。

将您的仓库设计为在其根目录托管单个模块将有助于保持维护更简单,尤其是在随着时间的推移发布新的次版本和修订版本、分支到新的主版本等时。但是,如果您的需求需要,您也可以在单个仓库中维护模块集合。

每个仓库一个模块源码

您可以维护一个包含单个模块源码的仓库。在这种模式下,您将 go.mod 文件放在仓库根目录,Go 源码放在下面的包子目录中。

这是最简单的方法,使您的模块随着时间的推移可能更容易管理。这有助于您避免需要用目录路径作为模块版本号的前缀。

Diagram illustrating a single module's source in its repository

单个仓库中包含多个模块源码

您可以从单个仓库发布多个模块。例如,您可能在单个仓库中有构成多个模块的代码,但希望分别对这些模块进行版本控制。

作为模块根目录的每个子目录都必须有自己的 go.mod 文件。

在子目录中获取模块代码会改变发布模块时必须使用的版本标签的形式。您必须使用作为模块根目录的子目录的名称作为标签版本号部分的前缀。有关版本号的更多信息,请参阅模块版本编号

例如,对于下面的模块 example.com/mymodules/module1,版本 v1.2.3 将具有以下内容:

Diagram illustrating two modules in a single repository