Go 1.16 中 Go Module 功能的更新

未匹配的标注

本文为官方 Go Blog 的中文翻译,详见 翻译说明

杰伊·康罗德(Jay Conrod)
2021年2月18日

我们希望你享受1.16!此版本具有很多新功能,尤其是模块。 发行说明简要描述这些变化,让我们深入探索其中一些更改。

默认情况下打开 Modules

现在,go命令在默认情况下以模块感知模式构建包,即使不存在go.mod。这是在所有项目中使用模块的一大步。

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

go env -w GO111MODULE=auto

我们计划在1.17中删除对GoPath模式的支持。换句话说,Go 1.17将忽略go111module。如果您有未在模块感知模式下构建的项目,现在是迁移的时候了。如果遇到迁移的问题,请考虑提交问题经验报告

没有自动更改Go.mod和go.sum

以前,当go命令发现go.modgo.sum的问题, 如缺少require指令或缺少sum,它将尝试自动解决问题。 我们收到了很多反馈,认为这种行为令人惊讶,特别是对于像go list这样通常没有副作用的命令。自动修复并不总是可取的: 如果任何必需的模块都没有提供导入的包,go命令将添加一个新的依赖项,可能会触发公共依赖项的升级。如果输入路径拼写错误,也会导致网络查找(失败)。

在 Go 1.16 中,模块感知命令在发现go.modgo.sum中的问题后会报告一个错误,而不是尝试自动修复问题。在大多数情况下,错误信息会推荐一个命令来解决这个问题。

$ go build
example.go:3:8: no required module provides package golang.org/x/net/html; to add it:
    go get golang.org/x/net/html
$ go get golang.org/x/net/html
$ go build

和以前一样,go命令可以使用vendor目录,如果它存在的话(详见Vendoring)。像go getgo mod tidy这样的命令仍然会修改go.modgo.sum,因为它们的主要目的是为了管理依赖关系。

安装一个特定版本的可执行文件

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

go install golang.org/x/tools/gopls@v0.6.5

当使用这个语法时,go install从那个确切的模块版本安装命令,忽略了当前目录和父目录中的任何go.mod文件。(如果没有@version后缀,go install继续像以前一样操作,使用当前模块的go.mod中列出的版本要求和替换来构建程序。)

我们曾经建议用go get -u program来安装可执行程序,但这种用法对go getgo.mod中添加或改变模块版本要求的意义造成了太多的混淆。而且为了避免意外地修改go.mod,人们开始建议使用更复杂的命令,比如。

cd $HOME; GO111MODULE=on go get program@latest

现在我们都可以用go install program@latest代替。详见go install

为了消除关于使用哪个版本的歧义,在使用这种安装语法时,对程序的go.mod文件中可能出现的指令有一些限制。特别是,"替换 "和 "排除 "指令是不允许的,至少目前是这样。从长远来看,一旦新的go install program@version在足够多的使用情况下运行良好,我们计划让go get停止安装命令二进制文件。详情见issue 43684

模块撤回

你是否曾经不小心在模块准备好之前就发布了一个版本?或者你是否在一个版本发布后马上发现了一个问题,需要迅速修复?发布的版本中的错误是很难纠正的。为了保持模块构建的确定性,一个版本在发布后不能被修改。即使你删除或改变了一个版本标签,proxy.golang.org和其他代理可能已经有了原始缓存。

模块作者现在可以使用go.mod中的retract指令撤回模块版本。被撤回的版本仍然存在并可以被下载(因此依赖于它的构建不会被破坏),但go命令在解析@latest等版本时不会自动选择它。 go getgo list -m -u将打印关于现有使用的警告。

例如,假设一个流行的库example.com/lib的作者发布了v1.0.5,然后发现了一个新的安全问题。他们可以在他们的go.mod文件中添加一条指令,就像下面这样。

//在软件包foo中发生远程触发的崩溃。参见CVE-2021-01234。
retract v1.0.5

接下来,作者可以标记并推送版本v1.0.6,新的最高版本。在这之后,已经依赖v1.0.5的用户在检查更新或升级依赖的软件包时,将被通知撤回的消息。通知信息可能包括retract指令上面的注释文本。

$ go list -m -u all
example.com/lib v1.0.0 (retracted)
$ go get .
go: warning: example.com/lib@v1.0.5: retracted by module author:
    Remote-triggered crash in package foo. See CVE-2021-01234.
go: to switch to the latest unretracted version, run:
    go get example.com/lib@latest

对于一个交互式的、基于浏览器的指南,请查看 play-with-go.dev 上的 Retract Module Versions。语法细节见retract指令文档

用 GOVCS 控制版本控制工具

go命令可以从镜像中下载模块源代码,如proxy.golang.org,或直接从使用githgsvnbzrfossil的版本控制库中下载。直接的版本控制访问是很重要的,特别是对于那些在代理上不可用的私有模块,但这也是一个潜在的安全问题:一个版本控制工具的错误可能被恶意的服务器利用来运行非预期的代码。

Go 1.16 引入了一个新的配置变量GOVCS,让用户指定哪些模块可以使用特定的版本控制工具。 GOVCS接受一个以逗号分隔的pattern:vcslist规则列表。pattern是一个path.Match模式,匹配模块路径的一个或多个前导元素。特殊模式publicprivate匹配公共和私有模块(private被定义为由GOPRIVATE中的模式匹配的模块;public是其他一切)。vcslist是一个管道分隔的允许的版本控制命令的列表,或者关键字alloff

比如说。

GOVCS=github.com:git,evil.com:off,*:git|hg

有了这个设置,路径在github.com的模块可以用git下载;路径在evil.com的模块不能用任何版本控制命令下载,所有其他路径(*匹配所有)可以用githg下载。

如果没有设置GOVCS,或者一个模块没有匹配任何模式,go命令使用这个默认值:githg允许用于公共模块,所有工具都允许用于私有模块。只允许 Git 和 Mercurial 的理由是,这两个系统作为不受信任的服务器的客户端运行的问题最受关注。相比之下,Bazaar、Fossil 和 Subversion 主要被用于可信的、经过验证的环境中,没有被作为攻击面进行仔细检查。也就是说,默认设置是。

GOVCS=public:git|hg, private:all

更多细节见版本控制工具GOVCS

下一步是什么?

我们希望你觉得这些功能很有用。我们已经在为 Go 1.17 的下一组模块功能努力工作了,特别是lazy module loading,它应该使模块加载过程更快、更稳定。像往常一样,如果你遇到新的错误,请在问题跟踪器上告诉我们。编码愉快!

本文章首发在 LearnKu.com 网站上。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://learnku.com/docs/go-blog/update-...

译文地址:https://learnku.com/docs/go-blog/update-...

上一篇 下一篇
Summer
贡献者:3
讨论数量: 0
发起讨论 只看当前版本


暂无话题~