Golang 1.16中Module机制更新

系统
最近,Golang发布了一个新版本1.16。版本引入了很多新功能,其中在模块方面的改进,今天我们就一起来深入学习一下。

最近,Golang发布了一个新版本1.16。版本引入了很多新功能,其中在模块方面的改进,今天我们就一起来深入学习一下。

默认情况下开启go module

go命令现在默认情况下以模块感知模式构建软件包,即使项目中没有go.mod也默认启动,这将对模块的全面使用起到重要作用。但是通过环境变量GO111MODULE设置为 off下,GOPATH模式仍然可用。

如果将GO111MODULE设置为auto,则会检测项目当前目录或任何父目录,如果其中存在go.mod文件,就会启用模块感知模式。这以前是默认设置。

如果要永久设置该选项,可以使用go env -w设置:

  1. go env -w GO111MODULE=auto 

据悉,Golang下个版本1.17中将完全放弃对GOPATH模式的支持。Golang1.17会忽略GO111MODULE变量设置。如果项目是以非模块感知模式构建的,请记得迁移。

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

此前,当go命令发现问题,go.mod或go.sum中的配置为不全的require指令或未设置sum值,go命令会自动尝试补全解决这个问题。但是该机制可能存在问题,会导致副作用:如果必需的模块未提供require所需的软件包,则go命令会添加新的依赖项,这可能会触发常见依赖项的升级。有些明显拼写错误路径也会耗费时间去从进行网络查询。

在Go 1.16中,支持模块的命令在发现问题后,go.mod或go.sum尝试自动修复问题时会报告错误。在大多数情况下,错误消息建议你通过命令来解决。

注意go get和go mod tidy还是会修改go.mod和go.sum。

安装特定版本模块

我们知道可以通过通过指定@version后缀让go install现安装特定版本的可执行文件。比如

  1. go install golang /x/tools/gopls@v0.6.5 

使用该语法时,go install使用确切模块版本安装命令,而会忽略go.mod当前目录和父目录中的所有文件。

曾建议go get -u program安装一个可执行文件,但是该用法与go get中添加或更改模块版本要求的含义容易造成了混淆。为了避免意外修改go.mod,一般使用更复杂的命令,例如:

  1. cd $HOME; GO111MODULE=on go get program@latest 

在Go 1.16中,默认可以使用go install program@latest的语法。

为了消除关于使用go.mod的歧义,使用此安装语法时,程序文件中可能存在的指令有一些限制。特别是,至少目前不允许使用replace和exclude指令。

模块回退

大家可能遇到过意外发布了模块版本的尴尬处境,或者在发布需要快速修复的版本后又马上发现问题问题的场景,版本发布中的错误很难纠正。为了保持模块构建的确定性,发布版本后不能对其进行修改。即使删除或更改了版本标签,proxy.golang其他代理也可能对其进行了缓存。

在新版本中,模块作者可以在go.mod中retract指令撤消模块版本。回退的版本仍然存在并且可以下载(因此依赖它的版本不会中断),但是go get和go list命令在解析诸如@latest标签时候,不会再自动选择它,而且会打印一条诸如下面例子的告警信息信息。

例如,假设一个库的cc/lib开发者发布了v1.0.5,然后发现一个新的安全问题。开发者可以将指令添加到其go.mod文件中,如下所示:

  1. // Remote-triggered crash in package cc. See CVE-2021-xxxx. 
  2. retract v1.0.5 

然后可以标记并推送v1.0.6最新修复版本。此后,v1.0.5当检查更新或升级从属软件包时,就会通知已依赖的用户将撤消通知。通知消息可能包含retract语句上面注释中的文本。

  1. go list -m -u all 
  2. cc/lib v1.0.0 (retracted) 
  3. go get . 
  4. go: warning: cc/lib@v1.0.5: retracted by module author: 
  5. Remote-triggered crash in package cc. See CVE-2021-xxxx. 
  6. go: to switch to the latest unretracted version, run: 
  7. go get cc/lib@latest 

基于GOVCS进行版本控制

go命令可以直接从源码镜像下载源码,比如proxy.golang。也可以直接从常见版本管理仓库,比如git,hg,svn,bzr,或fossil。直接从版本控制访问非常重要,尤其是对于代理中不可用的私有模块而言,但这也是个安全风险点,版本控制工具中的bug可能被恶意利用,并运行精心设置的代码。

Go 1.16引入了一个新的配置变量GOVCS,用户可以通过它指定允许哪些模块使用特定的版本控制工具。GOVCS接受以逗号分隔的pattern:vcslist规则列表。pattern是一个path.Match模式匹配的一个或一个模块路径。特殊模式public与private匹配的公共模块和私有模块(private被定义为由模式匹配的模块GOPRIVATE;public其他所有内容)。vcslist是允许的版本控制命令或关键字分隔的列表all或off。比如:

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

上面的语句设置可以使用github来下载git模块。evil.com为禁止使用的站点路径,*可以匹配下载其他模块(使用git和hg。

如果GOVCS未设置,或者模块与任何模式都不匹配,则go命令使用以下默认值:git和hg允许用于公共模块,并且允许使用所有工具用于私有模块。仅允许使用Git和Mercurial的原因是,这两个系统常常默认作为,默认不受信任客户端运行。而Bazaar,Fossil和Subversion主要用于受信任的,经过身份验证的环境,并且没有像攻击面那样受到严格的审查。即,默认设置为:

  1. GOVCS=public:git|hg,private:all 

 

责任编辑:赵宁宁 来源: 今日头条
相关推荐

2021-07-28 13:03:42

Golang熔断语言

2011-08-24 16:59:59

LuaModule

2021-07-22 09:43:09

Golang语言并发机制

2023-10-22 20:20:37

FiberGo

2022-08-12 12:23:55

golangmap数据结构

2021-06-01 19:11:20

Go函数NotifyConte

2023-06-30 12:06:39

C++

2023-11-13 21:55:12

Go编程

2020-10-13 08:36:30

React 架构机制

2021-02-19 09:01:37

Go项目模块

2022-03-07 16:30:10

数据库ORM开发人员

2022-01-21 10:58:39

JavaScriptGolangPython

2023-01-27 23:11:25

GolangNetHttp

2021-09-01 09:40:44

Docker开发人员扩展

2022-04-13 08:04:40

项目应用程序代码

2010-07-07 18:34:43

UML公共机制

2020-10-27 18:45:45

GolangGraphQ开发

2023-10-24 16:03:34

GoGolang

2023-10-28 16:30:19

Golang开发

2023-11-20 22:44:09

Golang并发
点赞
收藏

51CTO技术栈公众号