近日,Golang发布了1.16新版本。该版本引入了很多新特性,包括模块方面的改进,今天就让我们深入了解一下。gomodule默认启用go命令现在默认以模块感知模式构建包,即使项目中没有go.mod,这将对模块的整体使用起到重要作用。但是当环境变量GO111MODULE设置为off时,GOPATH模式仍然可用。如果GO111MODULE设置为auto,则检测项目当前目录或任何父目录,如果存在go.mod文件,则启用模块感知模式。这曾经是默认设置。如果想永久设置这个选项,可以使用goenv-wsetting:goenv-wGO111MODULE=auto据悉,Golang将在下一个版本1.17中完全放弃对GOPATH模式的支持。Golang1.17会忽略GO111MODULE变量设置。如果项目是在非模块感知模式下构建的,请记住进行迁移。不再自动更改go.mod和go.sum之前,当go命令发现问题时,go.mod或go.sum中的配置是一个不完整的require命令或者没有设置sum值,go命令会自动尝试完成问题。但该机制可能存在问题,会导致副作用:如果所需模块未提供require所需的包,则go命令会添加新的依赖项,这可能会触发公共依赖项的升级。一些明显拼写错误的路径也可能需要时间来执行网络查找。在Go1.16中,支持模块的命令会在go.mod或go.sum发现问题后尝试自动修复时报告错误。在大多数情况下,错误消息会建议使用命令来解决它。注意goget和gomodtidy仍然会修改go.mod和go.sum。安装特定版本的模块我们知道goinstall现在可以通过指定@version后缀来安装特定版本的可执行文件。例如goinstallgolang/x/tools/gopls@v0.6.5使用这种语法时,goinstall使用确切的模块版本安装命令,忽略当前目录和go.mod父目录下的所有文件。建议使用goget-uprogram安装可执行文件,但这种用法与goget添加或更改模块版本要求的含义混淆。为了避免不小心修改go.mod,一般使用比较复杂的命令,例如:cd$HOME;GO111MODULE=ongogetprogram@latest在Go1.16中,可以默认使用goinstallprogram@latest的语法。为了消除关于使用go.mod的歧义,在使用此安装语法时,对程序文件中可能存在的指令有一些限制。特别是,replace和exclude指令是不允许的,至少目前是这样。模块回滚你可能遇到过不小心发布模块版本的尴尬情况,或者发布版本后立即发现问题需要快速修复的场景。版本发布中的错误很难纠正。为了维护确定性的模块构建,版本在发布后不能修改。即使版本标签被移除或更改,它也可能被proxy.golang其他代理缓存。在新版本中,模块作者可以通过go.mod中的retract命令撤销模块版本。还原的版本仍然存在并且可以下载(因此依赖它的版本不会中断),但是goget和golist命令在解析@latest等标签时将不再自动选择它,并且会打印一行这样的如以下示例警告信息。例如,假设某个库的cc/lib开发人员发布了v1.0.5,然后发现了一个新的安全问题。开发人员可以像这样向他们的go.mod文件添加指令://Remote-triggeredcrashinpackagecc.SeeCVE-2021-xxxx.retractv1.0.5然后可以标记并推送v1.0.6最新修复版本。此后,v1.0.5在检查更新或升级依赖包时通知已经依赖它的用户时会撤消通知。通知消息可能包含撤回声明上方注释中的文本。golist-m-uallcc/libv1.0.0(retracted)goget.go:warning:cc/lib@v1.0.5:retractedbymoduleauthor:Remote-triggeredcrashinpackagecc.SeeCVE-2021-xxxx.go:toswitchtothelatestunretractedversion,运行:gogetcc/lib@latestbased在GOVCS上进行版本控制go命令可以直接从源镜像下载源码,比如proxy.golang。也可以直接从通用版本管理存储库中获取,例如git、hg、svn、bzr或fossil。从版本控制直接访问很重要,尤其是对于代理中不可用的私有模块,但这也是一种安全风险,因为版本控制工具中的错误可能会被恶意利用并运行精心设计的代码。Go1.16引入了一个新的配置变量GOVCS,用户可以通过它指定允许哪些模块使用特定的版本控制工具。GOVCS接受以逗号分隔的模式列表:vcslist规则。pattern是路径。匹配模式以匹配一个或模块路径。特殊模式public将public和private模块与private匹配(private定义为与模式GOPRIVATE匹配的模块;public一切)。vcslist是允许的版本控制命令的关键字分隔列表或全部或关闭。例如:GOVCS=github.com:git,evil.com:off,*:git|hg以上语句设置可以使用github下载git模块。evil.com为禁止站点路径,*可以匹配下载其他模块(使用git和hg。如果没有设置GOVCS,或者模块不匹配任何模式,go命令使用以下默认值:git和hgallow对于公共模块,所有工具都允许用于私有模块。只允许Git和Mercurial的原因是这两个系统通常作为默认情况下不受信任的客户端运行。Bazaar、Fossil和Subversion主要用于受信任的、经过身份验证的环境,并且不像攻击面那样受到严格审查。也就是说,默认设置是:GOVCS=public:git|hg,private:all
