管理模块源代码

当您开发供他人使用的模块时,您可以通过遵循本主题中描述的存储库约定,帮助确保其他开发人员更容易使用您的模块。

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

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

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 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