[Go]Golang 1.16 中 Modules的主要变化更新

本文转载,目的方便查阅html

01介绍git

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

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

02默认开启 Modulesgolang

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

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

 go env -w GO111MODULE=auto服务器

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

03不自动修改 go.mod 和 go.sumide

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

在 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 getgo 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-triggered crash in package foo. See CVE-2021-01234.
retract v1.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 模式,是时候开始迁移了。

相关文章
相关标签/搜索