管理模块源代码

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

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

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

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,您将有以下内容:

  • 模块路径:example.com/mymodules/module1
  • 版本标签:module1/v1.2.3
  • 用户导入的包路径:example.com/mymodules/module1/package1
  • 用户 require 指令中指定的模块路径和版本:example.com/mymodules/module1 v1.2.3

Diagram illustrating two modules in a single repository