Go 1.16中的新模块更改

2021-02-19 09:56:56

我们希望您喜欢Go 1.16!此发行版具有很多新功能,尤其是对于模块而言。发行说明简要描述了这些更改,但让我们深入探讨其中的一些更改。

现在即使没有go.mod,go命令仍默认以模块感知模式构建软件包。这是在所有项目中使用模块的重要一步。

通过将GO111MODULE环境变量设置为off,仍然可以在GOPATH模式下构建软件包。您还可以将GO111MODULE设置为auto以仅在当前目录或任何目录中存在go.mod文件时启用模块感知模式。父目录。以前是默认目录。请注意,您可以使用go env -w永久设置GO111MODULE和其他变量:

我们计划在Go 1.17中放弃对GOPATH模式的支持,换句话说,Go 1.17将忽略GO111MODULE。如果您的项目不是以模块感知模式构建的,那么现在是时候迁移了。如果有问题阻止您为了避免迁移,请考虑提交问题或经验报告。

以前,当go命令发现go.mod或go.sum存在问题,例如缺少require指令或缺少sum时,它将尝试自动解决问题。我们收到很多反馈,认为这种行为令人惊讶,特别是对于像go list这样的命令通常不会产生副作用。自动修复总是不希望的:如果任何所需模块都不提供导入的软件包,则go命令会添加新的依赖项,可能会触发通用依赖项的升级。即使导入路径拼写错误,也会导致(失败的)网络查找。

在Go 1.16中,支持模块的命令会在go.mod或go.sum中发现问题后报告错误,而不是尝试自动解决问题。在大多数情况下,错误消息会建议使用命令来解决问题。

$ go buildexample.go:3:8:没有必需的模块提供软件包golang.org/x/net/html;添加它:go get golang.org/x/net/html$ go get golang.org/x/net/html$ go build

和以前一样,go命令可以使用vendor目录(如果有的话)(请参见供应商)。go get和go mod tidy之类的命令仍会修改go.mod和go.sum,因为它们的主要目的是管理依赖性。

go install命令现在可以通过指定@version后缀来安装特定版本的可执行文件。

使用此语法时,go install从该确切的模块版本安装命令,而忽略当前目录和父目录中的所有go.mod文件。(没有@version后缀,go install继续像往常一样运行,构建程序使用当前模块的go.mod中列出的版本要求和替换。)

我们曾经建议使用go get -u程序来安装可执行文件,但是这种用法与go get的含义造成了太多混淆,因为go get在go.mod中添加或更改模块版本要求,并且为了避免意外地修改go.mod,人们开始建议更复杂的命令,例如:

为了消除使用哪个版本的歧义,使用此安装语法时,程序的go.mod文件中可能存在哪些指令,因此存在一些限制。特别是,在以下位置不允许使用replace和exclude指令。从长远来看,一旦新的go install program @ version在足够的用例下可以正常使用,我们计划停止安装命令二进制文件,请参阅问题43684。

您是否曾经在准备就绪之前意外地发布了模块版本,或者在发布版本后立即发现需要快速修复的问题?已发布版本中的错误很难纠正。要保持模块构建的确定性,版本不能即使在删除或更改版本标签后,proxy.golang.org和其他代理也可能已经缓存了原始标签。

模块作者现在可以使用go.mod中的retract指令来缩回模块版本。缩回版本仍然存在并且可以下载(因此依赖它的构建不会中断),但是go命令不会自动选择它解决诸如@latest之类的版本时。 go get and go list -m -u将打印有关现有用途的警告。

例如,假设一个流行的库example.com/lib的作者发布了v1.0.5,然后发现了一个新的安全问题,他们可以向其go.mod文件中添加一个指令,如下所示:

接下来,作者可以标记并推送新的最高版本v1.0.6,然后,已经依赖v1.0.5的用户在检查更新或升级相关程序包时将收到撤消通知。消息中可能包含收回指令上方注释中的文本。

$ go list -m -u allexample.com/lib v1.0.0(已撤消)$ go get .go:警告:example.com/[email protected]:被模块作者撤回:软件包foo中的远程触发崩溃。请参阅CVE-2021-01234.go:切换到最新的未收回版本,运行:go get example.com/lib@latest

要获得基于浏览器的交互式指南,请在play-with-go.dev上查看Retract Module Versions。有关语法的详细信息,请参阅retract指令文档。

go命令可以从类似proxy.golang.org的镜像中下载模块源代码,也可以使用git,hg,svn,bzr或化石直接从版本控制存储库中下载模块源代码。直接版本控制访问非常重要,尤其是对于非n 39;不能在代理服务器上使用,但这也可能是安全问题:恶意服务器可能会利用版本控制工具中的错误来运行意外的代码。

Go 1.16引入了一个新的配置变量GOVCS,它使用户可以指定允许哪些模块使用特定的版本控制工具。 GOVCS接受以逗号分隔的pattern:vcslist规则列表.pattern是路径.match模式匹配模块路径的一个或多个前导元素。特殊模式public和private匹配public和private modules(private定义为匹配的模块vcslist是由管道分隔的允许版本控制命令列表或关键字all或off的列表。

通过此设置,可以使用git下载github.com上具有路径的模块;无法使用任何版本控制命令下载evil.com上的路径,并且可以使用git或hg下载所有其他路径(*匹配所有内容)。

如果未设置GOVCS,或者模块不匹配任何模式,则go命令使用默认值:公共模块允许使用git和hg,私有模块允许使用所有工具。仅允许Git和Mercurial的原理是 这两个系统最关注作为不受信任的服务器的客户端运行的问题,相比之下,Bazaar,Fossil和Subversion主要用于受信任的,经过身份验证的环境中,没有像攻击面那样受到严格审查。 ,默认设置为: 我们希望您发现这些功能有用。 我们已经在努力开发Go 1.17的下一组模块功能,尤其是延迟模块加载,这应该使模块加载过程更快,更稳定。与往常一样,如果遇到新的错误,请让我们 了解问题追踪器。 祝您编码愉快!