Golang 1.16 中 Modules的主要变化更新
01介绍
Golang1.16已经正式发布了,其中Modules有一些变化:
- 默认开启Modules。
- 不自动修改go.mod和go.sum。
- 通过指定@version后缀安装特定版本可执行文件。
- 新增retract指令撤回Module版本。
- 使用新增配置变量GOVCS指定特定模块使用特定版本控制工具。
golang1.16默认开启Modules,即使不存在go.mod,Go命令现在默认情况下也会在module-aware(模块感知)模式下构建包。
在golang1.16中,通过设置关闭GO111MODULE环境变量,在GOPATH模式下构建包仍然是可能的。您还可以将GO111MODULE设置为auto,以便在当前目录或任何父目录中存在go.mod文件时启用module-aware(模块感知)模式。您还可以使用goenv-w永久设置GO111MODULE和其他变量,:
goenv-wGO111MODULE=auto
Go官方计划在Go1.17中放弃对GOPATH模式的支持。换句话说,Go1.17将忽略GO111MODULE。如果您的项目不在module-aware(模块感知)模式下构建,则现在是时候迁移至module-aware(模块感知)模式了。
03不自动修改go.mod和go.sum
在golang1.16之前版本中,当go命令发现go.mod或go.sum存在问题时,如缺少require指令或缺少sum,它将尝试自动解决问题。Go官方收到很多反馈,这种行为是令人惊讶的,特别是对于go命令,如golist,通常没有副作用。自动修复并不总是可取的:如果任何所需模块不提供导入的包,Go命令将添加新的依赖项,可能触发常见依赖项的升级。即使输入路径拼写错误,也会导致(失败的)网络查找。
在golang1.16中,module-aware(模块感知)命令在go.mod或go.sum中发现问题后报告错误,而不是尝试自动解决问题。在大多数情况下,错误消息中列出建议命令来解决问题,例如:
$gobuild example.go:3:8:norequiredmoduleprovidespackagegolang.org/x/net/html;toaddit: gogetgolang.org/x/net/html $gogetgolang.org/x/net/html $gobuild
golang1.16与Go之前版本一样,如果vendor目录存在,Go命令可能会使用vendor目录。goget和gomodtidy命令仍然修改go.mod和go.sum,因为他们的主要目的是管理依赖关系。
04通过指定@version后缀安装特定版本可执行文件
goinstall命令现在可以通过指定@version后缀安装特定版本的可执行文件,例如:
goinstallgolang.org/x/tools/gopls@v0.6.5
如果使用@version后缀,goinstall命令使用该确切Module版本,忽略当前目录和父目录中的任何go.mod文件中的Module版本。
如果没有@version后缀,goinstall继续运行,因为它一直有,建立程序使用当前模块的go.mod文件中requirements列表和replacements列表列出的版本。
为了消除使用哪个版本的模糊性,在使用此安装语法goinstallprogram@latest时,Go程序的go.mod文件中可能存在几个限制的指令。特别是,至少目前不允许replace和exclude指令。从长远来看,一旦新的goinstallprogram@version在大多数使用情况下工作的很好的前提下,Go官方计划在未来某个版本中让goget命令停止安装二进制文件。
05新增retract指令撤回Module版本
您是否在模块版本准备好之前意外地发布了该版本?或者,您是否在发布需要快速修复的版本后发现了问题?已发布版本中的错误很难更正。为了保持模块生成的确定性,版本发布后无法修改。即使您删除或更改了版本标签,proxy.golang.org和其他代理可能已经有原始缓存。
模块作者现在可以使用go.mod中的retract指令retract模块版本。retract的版本仍然存在,可以下载(因此依赖于它的构建不会中断),但go命令在解决@latest等版本时不会自动选择它。goget和golist-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的用户在检查更新或升级依赖包时将收到撤回通知。通知消息可能包括收回指令上方注释的文本。例如:
$golist-m-uall example.com/libv1.0.0(retracted) $goget. go:warning:example.com/lib@v1.0.5:retractedbymoduleauthor: Remote-triggeredcrashinpackagefoo.SeeCVE-2021-01234. go:toswitchtothelatestunretractedversion,run: gogetexample.com/lib@latest
06使用新增配置变量GOVCS指定特定模块使用特定版本控制工具
go命令可以从镜像proxy.golang.org或直接从版本控制存储库下载模块源代码,使用git、hg、svn、bzr或fossil。直接版本控制访问很重要,尤其是对于代理上不可用的私有模块,但它也可能是一个安全问题:版本控制工具中的错误可能被恶意服务器利用来运行恶意代码。
Go1.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主要用于受信任的、经过验证的环境中,而且没有像attacksurfaces那样受到很好的审查。即默认设置为:
GOVCS=public:git|hg,private:all
07Module未来发展
我们希望您发现这些功能很有用。我们已经开始开发Go1.17的模块功能,特别是懒惰的模块加载,这应该使模块加载过程更快,更稳定。
08总结
本文主要介绍了Golang1.16针对Module做的一些变化。通过Go官方的这些Module变化,切实解决了Go用户在使用Go时的实际问题。Go官方也表示会在Golang1.17计划彻底去除GOPATH模式,所以,如果您的项目目前还没有迁移到Module模式,是时候开始迁移了。
到此这篇关于Golang1.16中Modules的主要变化更新的文章就介绍到这了,更多相关GolangModules变化内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。