对于习惯了 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 会默认设置环境变量 GO15VENDOREXPERIMENT1,然后当你使用 go get 时,他会在你的当前包的目录下建立一个 vendor 目录,然后将对应的 package 都 download 到这个目录下,但是,还是需要你在这个目录里面切换到你需要的版本,好处就是你切换过一次,以后就不用切换了。这样的话,当你在代码中引用一个 package 时,golang 的查找顺序是:

glide

好像使用 vendor 并没有太多得帮助到我们,一个显而易见的好处就是团队协作方面是不需要担心版本不一致了;然而,问题也很明显,我们平时开发中,每每新建一个项目就需要这么搞一遍也是挺糟心的。程序员总是懒得,所以,有人受不了这些繁琐事了,决定自己搞点大事情,所以就有了很多社区的 package manager tool,我认为目前比较有气候的是 godepglide。在浅尝了两个之后,我觉得 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 等都是可以的。

Reference

  1. golang/go PackageManagementTools
  2. Glide: Vendor Package Management for Golang
  3. golang使用vendor目录来管理依赖包
  4. compare glide and godep
  5. 采用Glide对Golang进行包管理
  6. Golang 套件管理工具 Glide