官方围棋模块文档

2020-09-12 03:38:24

从1.11开始,Go就包含了对这里建议的版本化模块的支持。VGo的最初原型是在2018年2月宣布的。2018年7月,版本化模块登陆围棋主资源库。

从GO 1.14开始,模块支持被认为可以投入生产使用,并且鼓励所有用户从其他依赖项管理系统迁移到模块。如果您由于GO工具链中的问题而无法迁移,请确保该问题有未解决的问题字段。(如果问题不在Go1.16里程碑上,请说明为什么它会阻止您迁移,以便对其进行适当的优先排序)。您还可以提供体验报告以获得更详细的反馈。

现在可以使用GOMODCACHE环境变量设置模块缓存的位置。GOMODCACHE的默认值是GOPATH[0]/pkg/mod,这是此更改之前模块缓存的位置。

现在有一种解决方法可用于Windows";访问被拒绝";访问模块缓存的GO命令中的错误,这些错误是由外部程序并发扫描文件系统引起的(请参见问题#36568)。默认情况下未启用解决方法,因为当低于1.14.2和1.13.10的GO版本与同一模块缓存同时运行时,使用该解决方法是不安全的。可以通过显式设置环境变量GODEBUG=modcacheunzipinplace=1来启用它。

当主模块包含顶级供应商目录并且其go.mod文件指定go 1.14或更高版本时,对于接受该标志的操作,go命令现在缺省为-mod=vendor。

现在,当go.mod文件为只读且不存在顶级供应商目录时,默认设置为-mod=readonly。

-modcacherw是一个新标志,它指示go命令将模块缓存中新创建的目录保留为默认权限,而不是将其设置为只读。

-modfile=file是一个新标志,它指示go命令读取(并可能写入)备用go.mod文件,而不是模块根目录中的文件。

当显式启用模块感知模式(通过设置GO111MODULE=ON)时,如果不存在go.mod文件,则大多数模块命令的功能较有限。

GO工具现在默认从https://proxy.golang.org,的公共GO模块镜像下载模块,并且还默认根据https://sum.golang.org.的公共GO校验和数据库验证下载的模块(无论来源如何。如果您有私有代码,您很可能应该配置GOPRIVATE设置(如go env-w GOPRIVATE=*.corp.com,github.com/ret/repo),或者配置更细粒度的GONOPROXY或GONOSUMDB,它们支持不太频繁的用例。有关更多详细信息,请参阅文档。

GO111MODULE=AUTO如果找到任何go.mod,即使在GOPATH内部,也会启用模块模式。(在GO 1.13之前,GO111MODULE=AUTO永远不会在GOPATH内启用模块模式)。

Go Get参数已更改:Go Get-u(不带任何参数)现在只升级当前包的直接和间接依赖项,而不再检查整个模块。

去找你吧。/..。从模块根目录升级模块的所有直接和间接依赖项,现在排除测试依赖项。

Go get不再支持-m(因为由于其他更改,它将在很大程度上与go get-d重叠;您通常可以将go get-mfoo替换为go get-dfoo)。

快速入门和新概念部分对于刚开始使用模块的人尤其重要。“如何……”一节涵盖了更多关于力学的细节。此页面上包含的内容最多的是回答更具体问题的FAQ;至少有必要浏览一下这里列出的FAQ一行程序。

详细信息将在本页面的其余部分中介绍,但这里有一个从头开始创建模块的简单示例。

Go.mod文件已更新,以包括您的依赖项的显式版本,其中v1.5.2为Semver标记:

像go build或go test这样的标准命令将根据需要自动添加新依赖项以满足导入(更新go.mod并下载新依赖项)。

当需要时,可以使用诸如go get [email protected]、go get foo@master(使用mercurial时为foo@default)、go get foo@e3702bed2等命令,或通过直接编辑go.mod来选择更具体版本的依赖项。

Go list-m all-查看将在构建中用于所有直接和间接依赖项的最终版本(详细信息)。

Go list-u-m all-查看所有直接和间接依赖项的可用次要项和补丁程序升级(详细信息)。

去找你吧。/..。或者去找-u=patch。/...。(从模块根目录)-将所有直接和间接依赖项更新为最新的次要或修补程序升级(忽略预发布)(详细信息)。

去建吧。/..。或者去测试一下。(从模块根目录)-构建或测试模块中的所有包(详细信息)。

进行mod整理-从go.mod中删除任何不再需要的依赖项,并添加操作系统、体系结构和构建标记的其他组合所需的任何依赖项(详细信息)

替换指令或gohack-使用依赖项的派生、本地副本或精确版本(详细信息)。

在阅读了关于新概念的下面四个部分之后,您将有足够的信息开始使用大多数项目的模块。回顾上面的目录(包括那里的FAQ一行程序)以熟悉更详细的主题列表也很有用。

这些部分提供了对主要新概念的高级介绍。有关更多细节和基本原理,请参阅Russ Cox的这段40分钟的介绍性视频,该视频描述了设计背后的理念、官方提案文档或更详细的初始VGo博客系列。

模块是作为单个单元一起版本化的相关围棋包的集合。

大多数情况下,版本控制存储库只包含存储库根目录中定义的一个模块。(单个存储库中支持多个模块,但这通常会导致比每个存储库一个模块更多的持续工作)。

模块必须根据semver进行语义版本化,通常采用v(主要).(次要).(补丁)的形式,如v0.1.0、v1.2.3或v1.5.0-rc.1。前导v是必需的。如果使用Git,TAG RELEASED将使用其版本提交。公共和私有模块存储库和代理正在变得可用(请参阅下面的常见问题解答)。

模块由GO源文件树定义,该树的根目录中有一个go.mod文件。模块源代码可能位于GOPATH之外。有四个指令:MODULE、REQUIRED、REPLACE和EXCLUDE。

模块通过模块指令在其go.mod中声明其身份,该指令提供模块路径。模块中所有包的导入路径将模块路径共享为公共前缀。模块路径和从go.mod到软件包目录的相对路径共同确定软件包的导入路径。

例如,如果要为存储库github.com/user/mymod创建模块,该存储库将包含两个包,导入路径分别为github.com/user/mymod/foo和github.com/user/mymod/bar,则go.mod文件中的第一行通常会将模块路径声明为模块github.com/user/mymod,相应的磁盘结构可能是:

在Go源代码中,包是使用包括模块路径在内的完整路径导入的。例如,如果在上面的示例中,我们在go.mod中将模块标识声明为模块github.com/user/mymod,则使用者可以执行以下操作:

EXCLUDE和REPLACE指令只在当前(“主”)模块上操作。生成主模块时,将忽略主模块以外的模块中的EXCLUDE和REPLACE指令。因此,REPLACE和EXCLUDE语句允许主模块完全控制其自身的构建,而不受依赖项的完全控制。(有关何时使用替换指令的讨论,请参阅下面的常见问题解答)。

如果向源代码添加go.mod中要求尚未涵盖新导入,大多数GO命令(如';GO BUILD&39;和';GO TEST&39;)将自动查找正确的模块,并将新的直接依赖项的最高版本作为必需指令添加到模块的go.mod中。例如,如果您的新导入对应于其最新标记发布版本为v1.2.3的依赖项M,则您的模块go.mod将以Required M v1.2.3结束,这表示模块M是允许版本>;=v1.2.3的依赖项(<;v2,假设v2与v1不兼容)。

最小版本选择算法用于选择构建中使用的所有模块的版本。对于构建中的每个模块,通过最小版本选择选择的版本在语义上始终是由主模块或其依赖项之一中的Required指令显式列出的版本中的最高版本。

例如,如果您的模块依赖于具有Required D v1.0.0的模块A,并且您的模块还依赖于具有Required D v1.1.1的模块B,那么最小版本选择将选择D的v1.1.1包含在构建中(假设它是列出的最高Required版本)。此1.1.1版本的选择保持一致,即使稍后D的1.2.0版本可用。这是模块系统如何提供100%可重复构建的示例。准备好后,模块作者或用户可以选择升级到D的最新可用版本,或者选择D的显式版本。

有关最小版本选择算法的简要原理和概述,请参阅官方建议书的高保真版本部分,或查看更详细的VGo博客系列。

要查看所选模块版本(包括间接依赖项)的列表,请使用go list-m all。

公共使用的软件包在发展过程中应该尽量保持向后兼容性。GO1兼容性准则在这里是一个很好的参考:不要删除导出的名称,鼓励使用带标签的复合文字,等等。如果需要不同的功能,请添加新名称,而不是更改旧名称。如果需要完全中断,请使用新的导入路径创建一个新包。";

最后一句特别重要-如果您破坏了兼容性,您应该更改包的导入路径。对于GO 1.11模块,该建议被正式化为导入兼容性规则:

";如果旧程序包和新程序包具有相同的导入路径,则新程序包必须向后兼容旧程序包。";

当v1或更高版本的包进行向后不兼容的更改时,Recall Semver需要重大的版本更改。同时遵循导入兼容性规则和次要版本的结果称为语义导入版本控制,其中主版本包含在导入路径中-这确保了每当主版本因兼容性中断而增加时,导入路径都会更改。

作为语义导入版本控制的结果,选择加入GO模块的代码必须符合以下规则:

如果模块是v2或更高版本,则模块的主要版本必须作为/vn包含在go.mod文件中使用的模块路径的末尾(例如,模块github.com/my/mod/v2,需要github.com/my/mod/v2 v2.0.1)和软件包导入路径中(例如,import";github.com/my/mod/v2/mypkg";)。这包括GO GET命令中使用的路径(例如,GO GET github.com/my/mod/[email protected])。注意在该示例中既有/v2又有@v2.0.1。考虑这一问题的一种方法是,模块名称现在包含/v2,因此无论何时使用模块名称,都要包含/v2)。

如果模块是版本v0或v1,请不要在模块路径或导入路径中包含主版本。

一般来说,具有不同导入路径的包是不同的包。例如,数学/rand与crypto/rand是不同的软件包。如果不同的导入路径是由于导入路径中显示的主版本不同而导致的,也是如此。因此,example.com/my/mod/mypkg是一个与example.com/my/mod/v2/mypkg不同的包,两者可以在单个构建中导入,这除了有助于解决菱形依赖问题之外,还允许根据v1模块的v2替换来实现v1模块,反之亦然。

有关语义导入版本控制的更多详细信息,请参阅go命令文档的模块兼容性和语义版本控制部分,有关语义版本控制的更多信息,请参阅https://semver.org。

到目前为止,本节主要关注选择加入模块并导入其他模块的代码。但是,将主要版本放在v2+模块的导入路径中可能会造成与较旧版本的Go或尚未选择加入模块的代码不兼容。为了帮助实现这一点,上面描述的行为和规则有三个重要的过渡性特殊情况或例外。随着时间的推移,随着更多的包选择加入模块,这些过渡性异常将变得不那么重要。

使用以gopkg.in开头的导入路径的现有代码(如gopkg.in/yaml.v1和gopkg.in/yaml.v2)即使在选择加入模块之后,也可以继续将这些形式用于其模块路径和导入路径。

模块可以导入没有选择加入模块本身的v2+包。具有有效v2+semver标签的非模块v2+软件包将在导入模块的go.mod文件中记录为+不兼容的后缀。+不兼容后缀表示即使v2+包有一个有效的v2+semver标记(如v2.0.0),但v2+包并没有主动选择加入模块,因此假定创建该v2+包时并不了解语义导入版本控制的含义以及如何在导入路径中使用主要版本。因此,当在模块模式下操作时,Go工具会将非模块v2+包视为该包的v1版本系列的(不兼容)扩展,并假定该包没有语义导入版本控制意识,并且+不兼容后缀表示Go工具正在这样做。

为了帮助实现向后兼容性,GO版本1.9.7+、1.10.3+和1.11进行了更新,使得使用这些版本构建的代码可以更轻松地正确使用v2+模块,而不需要修改先前存在的代码。此行为称为最小模块兼容性,仅当GO工具禁用全模块模式时才生效,例如,如果您在GO 1.11中设置了GO111MODULE=OFF,或者正在使用GO版本1.9.7+或1.10.3+。在GO 1.9.7+、1.10.3+和1.11中依赖此最低模块兼容性机制时,未选择加入模块的软件包将不会在任何导入的v2+模块的导入路径中包含主要版本。相反,选择加入模块的包必须在导入路径中包含主版本才能导入任何v2+模块(以便在Go工具在完全支持语义导入版本控制的全模块模式下操作时正确导入v2+模块)。

有关发布v2+模块所需的确切机制,请参阅下面的发布模块(v2或更高版本)";一节。

在$GOPATH/src树之外的目录中调用go命令,并且当前目录或其任何父目录中有一个有效的go.mod文件,并且环境变量GO111MODULE未设置(或显式设置为AUTO)。

请注意,在GOPATH之外,不需要将GO111MODULE设置为激活模块模式。

$export GO111MODULE=ON#手动激活模块模式$cd$GOPATH/src/<;项目路径>;#例如,cd$GOPATH/src/you/hello。

此步骤从任何现有的dep Gopkg.lock文件或其他总共支持的9种依赖项格式中的任何一种进行转换,添加与现有配置匹配的Required语句。

Go mod init通常能够使用辅助数据(如VCS元数据)自动确定适当的模块路径,但如果Go mod init声明它不能自动确定模块路径,或者如果您需要以其他方式覆盖该路径,则可以将模块路径作为可选参数提供给Go mod init,例如:

请注意,如果您的依赖项包括v2+模块,或者如果您正在初始化v2+模块,那么在运行go mod init之后,您可能还需要编辑go.mod和.go代码,以添加/VN来导入路径和模块路径,如上面";语义导入版本控制一节中所述。即使go mod init自动转换来自dep或其他依赖项管理器的依赖项信息,这也适用。(正因为如此,在运行go mod init之后,通常在成功运行go build之前,您不应该运行go mod tidy。/...。或类似,这是本节中显示的序列)。

构建模块。当从模块的根目录执行时,./...。模式与当前模块中的所有包匹配。Go Build将根据需要自动添加缺少的或未转换的依赖项,以满足此特定构建调用的导入:

(可选)运行模块测试以及所有直接和间接依赖项的测试,以检查不兼容性:

在标记发布之前,请参阅下面的如何准备发布部分。

有关所有这些主题的更多信息,可以在golang.org上找到官方模块文档的主要入口点。

依赖项的日常升级和降级应使用';Go Get';来完成,这将自动更新go.mod文件。或者,您也可以直接编辑go.mod。

此外,像';go build';、';go test';甚至';go list';这样的GO命令将根据需要自动添加新依赖项以满足导入(更新go.mod并下载新依赖项)。

Go list-u-f';{{if(and(and(not(or.Main.Indirect)).Update)}}{{.Path}}:{{.Version}}->;{{.Update.Version}}{{end}}&39;-m all 2&>;/dev/null。

要升级到当前模块的所有直接和间接依赖项的最新版本,可以从模块根目录运行以下命令:

去找你吧。/..。要使用最新的次要版本或补丁版本(并添加-t以同时升级测试依赖项),请执行以下操作。

去拿-u=patch。/...。要使用最新的修补程序版本(并添加-t以同时升级测试依赖项),请执行以下操作。

去获取foo最新版本的foo更新。Go get foo等同于Go get foo@Latest-换句话说,如果没有指定@version,@Latest就是默认值。

在本节中,";LATEST";是带有semver标记的最新版本,如果没有semver标记,则是已知的最新提交。除非存储库中没有其他半版本标记(详细信息),否则不会将预发布标记选为最新的标记。

一个常见的错误是认为go get-u foo只获得最新版本的foo。实际上,go get-u foo或go get-u foo@Latest中的-u表示还可以获得foo的所有直接和间接依赖项的最新版本。升级foo的一个常见起点是不带a-u的Go Get Foo或Go Get foo@Latest(工作正常后,考虑Go get-u=patch foo、Go get-u=patch、Go get-u foo或Go get-u)。

要升级或降级到更具体的版本,请转到Get';允许通过向程序包参数添加@Version后缀或&34;模块查询来覆盖版本选择,例如Go Get [email protected]、Go Get foo@e3702bed2或Go Get Foo@<;v1.6.2';。

使用诸如go get foo@master(使用Mercurial的foo@default)之类的分支名称是获取最新提交的一种方式,而不管它是否有semver标记。

通常,不解析到Semver标记模块查询将被重新解析。

.