01介绍
Golang 1.16 已经正式发布了,其中 Modules 有一些变化:
- 默认开启 Modules。
- 不自动修改 go.mod 和 go.sum。
- 通过指定 @version 后缀安装特定版本可执行文件。
- 新增 retract 指令撤回 Module 版本。
- 使用新增配置变量 GOVCS 指定特定模块使用特定版本控制工具。
golang 1.16 默认开启 Modules,即使不存在go.mod
,Go 命令现在默认情况下也会在module-aware
(模块感知)模式下构建包。
在 golang 1.16 中,通过设置关闭GO111MODULE
环境变量,在GOPATH
模式下构建包仍然是可能的。您还可以将GO111MODULE
设置为auto
,以便在当前目录或任何父目录中存在go.mod
文件时启用module-aware
(模块感知)模式。您还可以使用go env -w
永久设置GO111MODULE
和其他变量,:
goenv-wGO111MODULE=auto
Go 官方计划在Go 1.17
中放弃对GOPATH
模式的支持。换句话说,Go 1.17
将忽略GO111MODULE
。如果您的项目不在module-aware
(模块感知)模式下构建,则现在是时候迁移至module-aware
(模块感知)模式了。
03不自动修改go.mod和go.sum
在 golang 1.16 之前版本中,当 go 命令发现go.mod
或go.sum
存在问题时,如缺少require
指令或缺少sum
,它将尝试自动解决问题。Go 官方收到很多反馈,这种行为是令人惊讶的,特别是对于 go 命令,如go list
,通常没有副作用。自动修复并不总是可取的:如果任何所需模块不提供导入的包,Go 命令将添加新的依赖项,可能触发常见依赖项的升级。即使输入路径拼写错误,也会导致(失败的)网络查找。
在 golang 1.16 中,module-aware
(模块感知)命令在go.mod
或go.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
golang 1.16 与 Go 之前版本一样,如果vendor
目录存在,Go 命令可能会使用vendor
目录。go get
和go mod tidy
命令仍然修改go.mod
和go.sum
,因为他们的主要目的是管理依赖关系。
04通过指定@version后缀安装特定版本可执行文件
go install
命令现在可以通过指定@version
后缀安装特定版本的可执行文件,例如:
go install golang.org/x/tools/gopls@v0.6.5
如果使用@version
后缀,go install
命令使用该确切 Module 版本,忽略当前目录和父目录中的任何go.mod
文件中的 Module 版本。
如果没有@version
后缀,go install
继续运行,因为它一直有,建立程序使用当前模块的go.mod
文件中 requirements 列表和 replacements 列表列出的版本。
为了消除使用哪个版本的模糊性,在使用此安装语法go install program@latest
时,Go 程序的 go.mod 文件中可能存在几个限制的指令。特别是,至少目前不允许replace
和exclude
指令。从长远来看,一旦新的go install program@version
在大多数使用情况下工作的很好的前提下,Go 官方计划在未来某个版本中让go get
命令停止安装二进制文件。
05新增retract指令撤回 Module 版本
您是否在模块版本准备好之前意外地发布了该版本?或者,您是否在发布需要快速修复的版本后发现了问题?已发布版本中的错误很难更正。为了保持模块生成的确定性,版本发布后无法修改。即使您删除或更改了版本标签,proxy.golang.org
和其他代理可能已经有原始缓存。
模块作者现在可以使用go.mod
中的retract
指令 retract 模块版本。retract 的版本仍然存在,可以下载(因此依赖于它的构建不会中断),但 go 命令在解决@latest
等版本时不会自动选择它。go get
和go list -m -u
会打印有关现有用途的警告。
例如,假设一个流行的库的作者example.com/lib
发布 v1.0.5,然后发现一个新的安全问题。他们可以添加指令到他们的go.mod
文件,例如:
//Remote-triggeredcrashinpackagefoo.SeeCVE-2021-01234.
retractv1.0.5
接下来,作者可以 tag 和 push 版本 v1.0.6,新的最高版本。在此之后,已依赖 v1.0.5 的用户在检查更新或升级依赖包时将收到撤回通知。通知消息可能包括收回指令上方注释的文本。例如:
$ 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
06使用新增配置变量 GOVCS 指定特定模块使用特定版本控制工具
go 命令可以从镜像proxy.golang.org
或直接从版本控制存储库下载模块源代码,使用 git、hg、svn、bzr 或 fossil。直接版本控制访问很重要,尤其是对于代理上不可用的私有模块,但它也可能是一个安全问题:版本控制工具中的错误可能被恶意服务器利用来运行恶意代码。
Go 1.16 引入了一个新的配置变量 GOVCS,它允许用户指定哪些模块允许使用特定的版本控制工具。GOVCS 接受一个逗号分隔的模式列表:vcslist 规则。
模式是一条path.Match
。匹配模式匹配模块路径的一个或多个主要元素。公共和私有的特殊模式匹配公共和私有模块(私有定义为与 GOPRIVATE 中的模式匹配的模块;公共是其他一切模块)。vcslist 是允许版本控制命令或关键字 all 或 off 的管道分隔列表。例如:
GOVCS=github.com:git,evil.com:off,*:git|hg
使用此设置,可以使用 git 下载带有github.com
路径的模块;无法使用任何版本控制命令下载evil.com
上的路径,使用 git 或 hg 下载所有其他路径(*
匹配所有内容)的模块。
如果未设置环境变量 GOVCS,或者如果模块与任何模式不匹配,Go 命令将使用 GOVCS 的默认值:允许 git 和 hg 用于公共模块,并且允许所有工具用于私有模块。
设置只允许使用 Git 和 Mercurial 的理由是,这两个版本控制工具最关注作为不受信任服务器的客户端运行的问题。相比之下,Bazaar、Fossil 和 Subversion 主要用于受信任的、经过验证的环境中,而且没有像 attack surfaces 那样受到很好的审查。即默认设置为:
GOVCS=public:git|hg,private:all
07Module 未来发展
我们希望您发现这些功能很有用。我们已经开始开发 Go 1.17 的模块功能,特别是懒惰的模块加载,这应该使模块加载过程更快,更稳定。
08总结
本文主要介绍了 Golang 1.16 针对 Module 做的一些变化。通过 Go 官方的这些 Module 变化,切实解决了 Go 用户在使用 Go 时的实际问题。Go 官方也表示会在 Golang 1.17 计划彻底去除GOPATH
模式,所以,如果您的项目目前还没有迁移到 Module 模式,是时候开始迁移了。
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。