10

Go 1.16中Module功能新变化

 3 years ago
source link: https://mp.weixin.qq.com/s?__biz=MzA4ODg0NDkzOA%3D%3D&%3Bmid=2247489480&%3Bidx=1&%3Bsn=2f8ce508cdf7d08b9c56140009a9c4e9
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

原文:https://blog.golang.org/go116-module-changes

作者:Jay Conrod

翻译:Kevin

希望您喜欢Go 1.16! 这个版本有很多新功能,特别是对Module而言。发行说明中简要介绍了这些变化,但让我们深入发掘一下其中的一些变化。

Module功能默认开启

go命令现在默认以module-aware模式构建包,即使没有 go.mod 文件存在。这是向在所有项目中使用Module功能迈出的一大步。

通过设置 GO111MODULE 环境变量为 off ,仍然可以在 GOPATH 模式下构建包。你也可以将 GO111MODULE 设置为 auto ,只有当当前目录或任何父目录中存在 go.mod 文件时才启用module-aware模式。这在以前是默认的。请注意,您可以使用 go env -w 来永久地设置 GO111MODULE 和其他变量。

go env -w GO111MODULE=auto

我们计划在 Go 1.17 中放弃对 GOPATH 模式的支持。换句话说,Go 1.17将忽略 GO111MODULE 。如果您的项目没有以module-aware模式构建,现在是时候迁移了。如果有问题妨碍您迁移,请考虑提交问题或体验报告。

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

在之前的版本中,当 go 命令发现 go.modgo.sum 有问题时,比如缺少 require 指令或缺少 sum ,它会尝试自动修复问题。我们收到了很多反馈,认为这种行为是出乎大家意料的,尤其是对于像 go list 这样通常不会产生副作用的命令。自动修复并不总是可取的:如果一个导入的包没有被任何需要的Module提供, go 命令会添加一个新的依赖关系,可能会触发普通依赖关系的升级。即使是拼写错误的导入路径也会导致(失败的)网络查找。

在 Go 1.16 中,module-aware命令在发现 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

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

在特定版本上安装可执行文件

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

go install golang.org/x/tools/[email protected]

当使用这种语法时, go install 命令会从该Module的制定版本安装,而忽略当前目录和父目录中的任何 go.mod 文件。(如果没有@version后缀,go install会像往常一样继续运行,使用当前Module的go.mod中列出的版本要求和替换来构建程序。)

我们曾经推荐使用 go get -u 程序来安装可执行文件,但这种使用方式对 go.mod 中添加或更改Module版本需求的意义造成了太多的混淆。而为了避免意外修改 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。

Module撤回

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

Module作者现在可以使用 go.mod 中的 retract 指令撤回Module版本。撤回的版本仍然存在,并且可以被下载(所以依赖它的构建不会中断),但在解析 @latest 这样的版本时, go 命令不会自动选择它, go 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 版本,即新的最高版本。在这之后,已经依赖v1.0.5的用户在检查更新或升级依赖的软件包时,就会被通知版本撤回。通知信息可能会包含来自 retract 指令上方注释的文字。

$ go list -m -u all
example.com/lib v1.0.0 (retracted)
$ go get .
go: warning: example.com/[email protected]: 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 这样的镜像中下载Module源代码,或者直接从使用 githgsvnbzrfossil 的版本管理仓库中下载。直接的版本控制访问是很重要的,特别是对于那些在代理上无法使用的私有Module,但这也是一个潜在的安全问题:版本控制工具中的一个bug可能会被恶意服务器利用,运行非预期的代码。

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

例如

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

在此设置下,路径在 github.com 上的Module可以使用 git 下载;路径在 evil.com 上的Module不能使用任何版本管理程序下载,其他所有路径(*匹配所有)可以使用 githg 下载。

如果没有设置 GOVCS ,或者一个Module不符合任何模式, go 命令就会使用这个默认值:公共Module允许使用 githg ,私有Module允许使用所有工具。只允许 GitMercurial 的理由是,这两个系统作为不受信任的服务器的客户端运行的问题最受关注。相比之下, BazaarFossilSubversion 主要是在受信任的、经过认证的环境中使用,作为攻击面的审查程度不高。也就是说,默认的设置是

GOVCS=public:git|hg,private:all

更多细节请参见使用 GOVCS控制版本管理工具

下一步?

我们希望您觉得这些功能很有用。我们已经在努力为Go 1.17开发新的Module功能,特别是 懒惰Module加载 ,这将使Module加载过程更快、更稳定。和以往一样,如果您遇到新的bug,请在问题跟踪上告诉我们。Happy coding!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK