概述
对于习惯了 Java 和 Python 的程序员来说,对于包的管理都有着比较大的期望,当然,虽然 Java 和 Python 的包管理也是存在着一些问题,但是相比起 golang 来说,那也是好得多了。
在尝试 golang 一段时间之后,我发现 golang 的一个比较大的问题就是包管理不容易,例如我引用了一个 package:github.com/prometheus/prometheus,然后在 build 的时候先 go get -d
一遍,这里虽然 golang 可以很智能得帮我下载需要的 package,但是,下载的版本却默认是最新的。当然,这也不能怪 go get
这个命令,毕竟你也没告诉它是什么版本,所以给你个最新的也不奇怪,但是,如果我就是不要最新的怎么办?好像目前 go get 还没有这个功能(或者不能简单使用?)
golang 默认包管理
我最开始的做法是先用 go get -d
把需要的包 download 下来,然后再切换到 $GOPATH,之后再 checkout 我需要的版本,这个过程很是繁琐和无趣,非常让人沮丧。不过,好在在我搜索了一会之后,我发现 golang 也没有想象中的那么糟糕,在 Golang 1.5(现在都 1.9 了) 之后,它已经意识到这个问题了,并且给除了一个解决方案,那就是 vendor。
从 golang 1.6 之后,golang 会默认设置环境变量 GO15VENDOREXPERIMENT 为 1
,然后当你使用 go get
时,他会在你的当前包的目录下建立一个 vendor 目录,然后将对应的 package 都 download 到这个目录下,但是,还是需要你在这个目录里面切换到你需要的版本,好处就是你切换过一次,以后就不用切换了。这样的话,当你在代码中引用一个 package 时,golang 的查找顺序是:
- 当前包下的 vendor 目录。
- 向上级目录查找,直到找到 src 下的 vendor 目录。
- 在 GOPATH 下面查找依赖包。
- 在 GOROOT 目录下查找
glide
好像使用 vendor 并没有太多得帮助到我们,一个显而易见的好处就是团队协作方面是不需要担心版本不一致了;然而,问题也很明显,我们平时开发中,每每新建一个项目就需要这么搞一遍也是挺糟心的。程序员总是懒得,所以,有人受不了这些繁琐事了,决定自己搞点大事情,所以就有了很多社区的 package manager tool,我认为目前比较有气候的是 godep 和 glide。在浅尝了两个之后,我觉得 glide 更符合我对于 package manager tool 的期待,但是,并没有完全吻合,只是说够用了。
glide 的安装很简单,直接 brew install glide
就可以的,其他 OS 应该也差不远。装完之后,那么直接使用 glide init
或者 glide create
即可,然后你就会发现你的目录下会有一个新的 glide.yaml 的 YAML 文件,里面描述了 package 的信息,但是只是依赖信息,并没有版本信息。
此后,你需要使用 glide up
命令,它会建立 glide.lock 文件,里面会记录 package 的版本信息。例如我随便创建了一个,差不多就是这个样子:
如果你需要指定版本信息,除了编辑 glide.lock 这个粗暴的方法之外,官方建议使用一个更加友善的方式就是使用这条命令:
$ glide get "github.com/gin-gonic/gin#v1.2"
我尝试了一下,之前因为 zsh 的设置问题导致使用失败,不过修改了一下之后,发现运行得还不错,和普通的 get 的区别就是后面加上了一个 #
符号,然后后面接上 版本号,如果你喜欢,加上分支名,commit id,tag 等都是可以的。