让Go Module重新Respect Go Vendor (二)

失宠的Vendor目录


Vendor目录是Golang从1.5版本开始引入的,为项目开发提供了一种离线保存第三方依赖包的方法。但是到了Golang 1.11之后,由于引入了Module功能,在运行go build时,优先引用的是Module依赖包的逻辑,所以Vendor目录就被“无视”了,进而可能会发生以下编译错误(中间一个是因为当前的GOPATH不对,这是个伏笔):


让Go Module重新Respect Go Vendor (二)_第1张图片


Module说,还是很想他


上篇文章提到过go mod有很多子命令,其中就有个go mod vendor命令,运行试试,不出意外地报错了:

640?wx_fmt=png


报错信息说找不到main module,应该是每次使用module功能都得先go mod init一把,那么试试go mod init github.com/nevermosby/mydocker,结果令人惊奇:

640?wx_fmt=png


go mod init命令竟然是respectGodep功能的!!!来看看生成的go.mod文件:

让Go Module重新Respect Go Vendor (二)_第2张图片

对比Godep.json原文件相关内容:

让Go Module重新Respect Go Vendor (二)_第3张图片

发生了以下映射关系:

  • Deps变成了require

  • ImportPath内容被沿用下来,毕竟是依赖包名称

  • Comment被直接舍弃了,Nice to have的东西一般都是这个下场

  • v0.0.0-20151204141443-446d1c146faa,这段很有趣,v0.0.0是为了符合go module版本控制的规范做的workround; 20151204141443-446d1c146faa是代表了这个依赖包当初被引入时最新一次commit的时间和hash值(取了前12位),应该是通过Rev这个commit反查出来的


这么看来,Godep作为Dependency tools for go的前身,相比go vendor,与go module还是更近一点。那实在喜欢go vendor的我们该如何是好?

Module说,那我们重新开始


还记得刚开始执行的go mod vendor命令么,让我们再试试。。。这次运行完毕没有任何报错了,所以他们俩终于“有情人终成眷属”了?!有疑问找help文档:

640?wx_fmt=png

帮助文档告诉我们,这个操作的本质是把原有vendor目录里的内容,reset成当前程序所需的全部依赖包,即把执行go mod init后下载的相关依赖包(都被下载到了GOPATHpkg目录)全部复制到原有vendor目录下了,通过git status可以证明这件事情:

让Go Module重新Respect Go Vendor (二)_第4张图片

不难发现,原有vendor目录里的依赖包内容发生了改变,选一个看看diff

640?wx_fmt=png


是权限发生了改变,可以侧面证明文件有被覆盖更新的痕迹。

终于真相大白了,要跟go module重新开始的前提,就是你得先变成他喜欢的样子。。。

好日子终于要开始了?


来吧,试试go build能否成功,这次咱们长个心眼,提前看看帮助文档里有没有与go module相关的内容。。。果不其然,有个可选参数:

go build -mod=vendor

运行试试。。。编译成功了,生成了可执行文件,运行它,结果符合期待。。。

你是不是跟我一样,发现了不得了的事情了,联系文章开头的伏笔,发现了通过go module机制,编译go语言项目竟然可以不用指定GOPATH了。

使用这个命令,让官方告诉你modules本质意义


客观上,从事物持续发展的眼光看这个问题,回答一定是yes!

那么主观上,怎么让自己信服呢?运行下面的命令,来看Golang官方的解释:

让Go Module重新Respect Go Vendor (二)_第5张图片

令人惊奇的是,Google竟然把洋洋洒洒近2万个单词组成的文章,塞进了帮助文档里,不知道算不算彩蛋。上面只是摘取了部分文字,如果大家感兴趣,可以到这个 gist 看全文。

从上面摘取的第一段文字来看Module的设计定位:

  • 在Go项目扮演着包管理员的角色

  • 是源代码互相通信和版本管理的单元

  • 会被go命令行工具强烈支持

  • 基于GOPATH的编译方案将被其取代


因此,官方其实已经下了决心,要大力推广Go Module概念了,大家收拾收拾,可以重新站队了。

PS:官网文档里其实还有这么一段:

If GO111MODULE=off, then the go command never uses the new module support. Instead it looks in vendor directories and GOPATH to find dependencies; we now refer to this as “GOPATH mode.”


所以,让Module Respect Vendor 最简单的方法,就是设置环境变量GO111MODULE为off


你可能感兴趣的:(让Go Module重新Respect Go Vendor (二))