Python 程序员的 Golang 学习指南(IV): 包管理篇
Golang
  • 调试篇
  • 打包篇

在第一篇文章我们有提到,Golang 官方并没有推荐最佳的包管理方案,对于像我这样习惯了 Python 包管理的开发者,自然还是希望有像 pip 一样好用的工具,帮助我们进行依赖管理,下面就让我们对 Golang 的包管理机制一探究竟。

Golang 包管理机制

go getgo get
名称 主命令 说明
Mercurial hg Mercurial是一种轻量级分布式版本控制系统,采用Python语言实现,易于学习和使用,扩展性强。
Git git Git最开始是Linux Torvalds为了帮助管理 Linux 内核开发而开发的一个开源的分布式版本控制软件。但现在已被广泛使用。它是被用来进行有效、高速的各种规模项目的版本管理。
Subversion svn Subversion是一个版本控制系统,也是第一个将分支概念和功能纳入到版本控制模型的系统。但相对于Git和Mercurial而言,它只算是传统版本控制系统的一员。
Bazaar bzr Bazaar是一个开源的分布式版本控制系统。但相比而言,用它来作为VCS的项目并不多。

比如,我们现在需要获取 godep 这个项目,可以执行如下命令:

  1. $ go get github.com/tools/godep
go getgo install-d
  1. $ go get -d github.com/tools/godep
go getWorkspaceWorkspace
  • bin 目录用于放置编译好的可执行文件,为了使得这里的可执行文件可以方便的运行, 可在 shell 中设置 PATH 环境变量。
  • src 目录用于放置代码源文件,在进行 import 时,是使用这个位置作为根目录的。自己编写的代码也应该放在这下面。
  • pkg 用来放置安装的包的链接对象(Object)的。这个概念有点类似于链接库,Go 会将编译出的可连接库放在这里, 方便编译时链接。不同的系统和处理器架构的对象会在 pkg 存放在不同的文件夹中。

Golang 包管理现状

go getWorkspace
  1. 第三方包的版本控制。如果没有明确指定依赖的第三方包的版本,团队开发很容易导入不一样的版本,导致项目无法正常运行。
  2. 第三方包没有内容安全审计,很容易引入代码 Bug,这是泛中心化包管理普遍存在的问题。
  3. 依赖的完整性无法校验,程序编译时无法保障百分百成功。

因此,我们必须借助第三方工具来解决这些问题。

第三方解决方案

这里我从官方推荐包管理工具中挑选了几个比较常用的工具:Godep, Govendor 以及 Glide,作下简单介绍。

  • godep save

这个命令做了以下几件事:

  1. 查找项目中所用到的所有的第三方包。
  2. 在项目目录下创建 Godeps 目录,Godeps/Godeps.json 是依赖文件,包括了 go 的版本,用到的第三方包的引入路径,版本号等信息,json 文件需要一并加入到版本控制里。
  3. 所有依赖的第三方包的代码会被拷贝到 vendor/ 下,并且移除了 .git 这样的版本控制信息。
  • godep restore
godep restore$GOPATHgo get
  • govendor init
govendor init
  • govendor add +external
govendor add +externalgodep save
  • govendor fetch
govendor fetch

这样,我们只需对 vendor/vendor.json 进行版本控制,即可对第三包依赖关系进行控制。

  • glide init
glide initglide create
  • glide install
glide install

总结

上面我们分别对 Godep, Govendor 以及 Glide 这三种工具做了简单的介绍,对于 Python 开发者,个人还是比较认同 Govendor 的方式,因为其很容易实现类似 Virtualenv 的模式,从而实现不同程序使用不同版本依赖的目的。

当然,如果你是 Node.js 的开发者,可能对于 Godep 有更加熟悉的感觉,而对于 Ruby 开发者,gom 会让你感到更加亲切。

因此,针对第三方包管理工具的选择,现阶段还完全交由开发者做裁定,这里就“仁者见仁,智者见智”了。

相关链接:
http://www.infoq.com/cn/articles/golang-package-management
https://io-meter.com/2014/07/30/go's-package-management/
https://github.com/golang/go/wiki/PackageManagementTools