New module changes in Go 1.16

Go1.16引入了多项改进,包括默认开启模块支持,不再自动修复go.mod和go.sum文件,以及通过@version安装特定版本的可执行文件。此外,新版本还引入了模块回退功能,允许作者撤销已发布的版本,并通过GOVCS控制版本控制工具的使用。
摘要由CSDN通过智能技术生成

 

Jay Conrod
2021年2月18日

我们希望您喜欢Go 1.16!此版本具有许多新功能,尤其是对于模块。该发行说明描述这些变化短暂,但让我们来看看其中的几个深入。

默认情况下开启模块

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

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

go env -w GO111MODULE=auto

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

不会自动更改go.mod和go.sum

此前,当go命令发现问题,go.modgo.sum像一个丢失的require指令或丢失的总和,它会自动尝试解决这个问题。我们收到了很多反馈,认为这种行为令人惊讶,尤其是对于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目录(如果存在的话)(有关详细信息,请参见供应商)。命令likego getgo mod tidy仍会修改go.modand go.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 get中添加或更改模块版本要求的含义造成了太多混淆go.mod。为了避免意外修改go.mod,人们开始建议更复杂的命令,例如:

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

现在我们都可以go install program@latest代替使用。有关go install详细信息,请参见。

为了消除关于使用哪个版本的歧义go.mod,使用此安装语法时,程序文件中可能存在哪些指令有一些限制。特别是,至少目前不允许使用replaceexclude指令。从长远来看,一旦新功能go install program@version可以在足够的用例中正常运行,我们计划go get停止安装命令二进制文件。有关详细信息,请参见问题43684

模块缩回

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

现在,模块作者可以使用中的指令撤消模块版本。缩回的版本仍然存在并且可以下载(因此依赖它的版本不会中断),但是在解析诸如的版本时,该命令不会自动选择它。 并且,将打印现有用途的警告。retractgo.modgo@latestgo getgo list -m -u

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

// Remote-triggered crash in package foo. See CVE-2021-01234.
retract v1.0.5

接下来,作者可以标记并推送v1.0.6新的最高版本version。此后,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

使用GOVCS控制版本控制工具

go命令可以从像一面镜子下载模块的源代码proxy.golang.org或直接从一个版本控制库使用githgsvnbzr,或fossil。直接版本控制访问非常重要,尤其是对于代理中不可用的私有模块而言,但这也可能是安全问题:版本控制工具中的错误可能被恶意服务器利用以运行意外的代码。

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

例如:

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

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

如果GOVCS未设置,或者模块与任何模式都不匹配,则该go命令使用以下默认值:githg允许用于公共模块,并且允许使用所有工具用于私有模块。仅允许使用Git和Mercurial的原因是,这两个系统最关注作为不受信任服务器的客户端运行的问题。相反,Bazaar,Fossil和Subversion主要用于受信任的,经过身份验证的环境,并且没有像攻击面那样受到严格的审查。即,默认设置为:

GOVCS=public:git|hg,private:all

有关更多详细信息,请参见控制版本控制工具GOVCS

下一步是什么?

我们希望您发现这些功能有用。我们已经在努力开发Go 1.17的下一组模块功能,尤其是延迟模块加载,这应该使模块加载过程更快,更稳定。与往常一样,如果您遇到新的错误,请在问题跟踪器上告知我们。祝您编码愉快!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值