前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >让Go Module重新Respect Go Vendor(二)

让Go Module重新Respect Go Vendor(二)

作者头像
nevermosby
发布2020-05-11 17:21:00
2K0
发布2020-05-11 17:21:00
举报

失宠的Vendor目录

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

Module说,还是很想他

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

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

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

代码语言:javascript
复制
module github.com/nevermosby/mydocker

require (
    github.com/Sirupsen/logrus v0.0.0-20151204141443-446d1c146faa
    github.com/urfave/cli v0.0.0-20161122043610-0bdeddeeb0f6
    golang.org/x/sys v0.0.0-20151211033651-833a04a10549
)

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

代码语言:javascript
复制
"Deps": [
        {
            "ImportPath": "github.com/Sirupsen/logrus",
            "Comment": "v0.8.7-53-g446d1c1",
            "Rev": "446d1c146faa8ed3f4218f056fcd165f6bcfda81"
        },
        {
            "ImportPath": "github.com/urfave/cli",
            "Comment": "v1.19.1",
            "Rev": "0bdeddeeb0f650497d603c4ad7b20cfe685682f6"
        },
        {
            "ImportPath": "golang.org/x/sys/unix",
            "Rev": "833a04a10549a95dc34458c195cbad61bbb6cb4d"
        }
    ]

发生了以下映射关系:

  • 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文档:

代码语言:javascript
复制
$ go mod help vendor
usage: go mod vendor [-v]

Vendor resets the main module's vendor directory to include all packages needed to build and test all the main module's packages.
It does not include test code for vendored packages.

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

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

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

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

好日子终于要开始了?

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

代码语言:javascript
复制
go build -mod=vendor

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

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

预知后事如何,请看下回——“最终章,引入Go Module的本质”

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年10月2日2,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 失宠的Vendor目录
  • Module说,还是很想他
  • Module说,那我们重新开始
  • 好日子终于要开始了?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档