前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Golang 1.16 中 Module 有什么变化?

Golang 1.16 中 Module 有什么变化?

作者头像
frank.
发布2021-03-09 18:21:01
2K0
发布2021-03-09 18:21:01
举报

01

介绍

Golang 1.16 已经正式发布了,其中 Modules 有一些变化:

  • 默认开启 Modules。
  • 不自动修改 go.modgo.sum
  • 通过指定 @version 后缀安装特定版本可执行文件。
  • 新增 retract 指令撤回 Module 版本。
  • 使用新增配置变量 GOVCS 指定特定模块使用特定版本控制工具。

本文来深入探讨一下 golang 1.16 关于 Modules 的一些变化。

02

默认开启 Modules

golang 1.16 默认开启 Modules,即使不存在 go.mod,Go 命令现在默认情况下也会在 module-aware(模块感知)模式下构建包。

在 golang 1.16 中,通过设置关闭 GO111MODULE 环境变量,在 GOPATH 模式下构建包仍然是可能的。您还可以将 GO111MODULE 设置为 auto,以便在当前目录或任何父目录中存在 go.mod 文件时启用 module-aware (模块感知)模式。您还可以使用 go env -w 永久设置 GO111MODULE 和其他变量,:

代码语言:javascript
复制
go env -w GO111MODULE=auto

Go 官方计划在 Go 1.17 中放弃对 GOPATH 模式的支持。换句话说,Go 1.17 将忽略 GO111MODULE。如果您的项目不在 module-aware (模块感知)模式下构建,则现在是时候迁移至 module-aware (模块感知)模式了。

03

不自动修改 go.modgo.sum

在 golang 1.16 之前版本中,当 go 命令发现 go.modgo.sum 存在问题时,如缺少 require 指令或缺少 sum,它将尝试自动解决问题。Go 官方收到很多反馈,这种行为是令人惊讶的,特别是对于 go 命令,如 go list,通常没有副作用。自动修复并不总是可取的:如果任何所需模块不提供导入的包,Go 命令将添加新的依赖项,可能触发常见依赖项的升级。即使输入路径拼写错误,也会导致(失败的)网络查找。

在 golang 1.16 中,module-aware (模块感知)命令在 go.modgo.sum 中发现问题后报告错误,而不是尝试自动解决问题。在大多数情况下,错误消息中列出建议命令来解决问题,例如:

代码语言:javascript
复制
$ 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 getgo mod tidy 命令仍然修改 go.modgo.sum,因为他们的主要目的是管理依赖关系。

04

通过指定 @version 后缀安装特定版本可执行文件

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

代码语言:javascript
复制
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 get -u program 安装一个可执行文件, 但这种使用给 go get 安装或更改在 go.mod文件中 requirements 的 module 版本时造成了太多的混乱。

为了避免意外修改 go.mod,Go 用户开始建议更复杂的命令,如:

代码语言:javascript
复制
cd $HOME; GO111MODULE=on go get program@latest

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

为了消除使用哪个版本的模糊性,在使用此安装语法 go install program@latest 时,Go 程序的 go.mod 文件中可能存在几个限制的指令。特别是,至少目前不允许 replaceexclude 指令。从长远来看,一旦新的 go install program@version 在大多数使用情况下工作的很好的前提下,Go 官方计划在未来某个版本中让 go get 命令停止安装二进制文件。

05

新增 retract 指令撤回 Module 版本

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

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

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

代码语言:javascript
复制
// Remote-triggered crash in package foo. See CVE-2021-01234.
retract v1.0.5

接下来,作者可以 tag 和 push 版本 v1.0.6,新的最高版本。在此之后,已依赖 v1.0.5 的用户在检查更新或升级依赖包时将收到撤回通知。通知消息可能包括收回指令上方注释的文本。例如:

代码语言:javascript
复制
$ 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 的管道分隔列表。例如:

代码语言:javascript
复制
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 那样受到很好的审查。即默认设置为:

代码语言:javascript
复制
GOVCS=public:git|hg,private:all

07

Module 未来发展

我们希望您发现这些功能很有用。我们已经开始开发 Go 1.17 的模块功能,特别是懒惰的模块加载,这应该使模块加载过程更快,更稳定。

08

总结

本文主要介绍了 Golang 1.16 针对 Module 做的一些变化。通过 Go 官方的这些 Module 变化,切实解决了 Go 用户在使用 Go 时的实际问题。Go 官方也表示会在 Golang 1.17 计划彻底去除 GOPATH 模式,所以,如果您的项目目前还没有迁移到 Module 模式,是时候开始迁移了。

关注公众号,获取微信群加入方式。


推荐阅读:

Golang 1.16 新增 embed 包怎么使用?

Go Modules 介绍与基本操作

GOPATH 模式怎么迁移至 Modules 模式?

保持 Modules 的兼容性

怎么发布 Go Modules v1 版本?

Go Modules 如何创建和发布 v2 及更高版本?

参考资料:

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

本文参与?腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-02-19,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 Go语言开发栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com