文章目录

  • 一、包管理历史
  • 二、vendor 机制的进步
  • 三、Go Vendor
  • 参考链接



一、包管理历史

Golang 的包管理一直被大众所诟病的一个点,但是我们可以看到现在确实是在往好的方向进行发展。下面是官方的包管理工具的发展历史:

  • 在 1.5 版本之前,所有的依赖包都是存放在 GOPATH 下,没有版本控制。这个类似 Google 使用单一仓库来管理代码的方式。这种方式的最大的弊端就是 无法实现包的多版本控制,比如项目 A 和项目 B 依赖于不同版本的 package,如果 package 没有做到完全的向前兼容,往往会导致一些问题。
  • 1.5 版本推出了 vendor 机制。所谓 vendor 机制,就是每个项目的根目录下可以有一个 vendor 目录,里面存放了该项目的依赖的 package。go build 的时候会先去 vendor 目录查找依赖,如果没有找到会再去 GOPATH 目录下查找。
  • 1.9 版本推出了实验性质的包管理工具 dep,这里把 dep 归结为 Golang 官方的包管理方式可能有一些不太准确。关于 dep 的争议颇多,比如为什么官方后来没有直接使用 dep 而是弄了一个新的 modules,具体细节这里不太方便展开。
  • 1.11 版本推出 modules 机制,简称 mod。modules 的原型其实是 vgo,关于 vgo,可以自行搜索。

除此之外,社区也一直在有几个活跃的包管理工具,使用广泛且具有代表性的主要有下面几个:

  • godep
  • glide
  • govendor

二、vendor 机制的进步

Go 1.5 引入了vendor 机制,但是需要手动设置环境变量 GO15VENDOREXPERIMENT= 1,Go编译器才能启用。

从Go1.6起,默认开启 vendor 目录查找,vendor 机制就是在包中引入 vendor 目录,将依赖的外部包复制到 vendor 目录下,编译器在查找外部依赖包时,优先在 vendor 目录下查找。整个查找第三方包的流程如下:

  • 在当前vendor目录(如果当前目录存在vendor目录的话)查找依赖包;
  • 如果当前目录不存在vendor目录,则到上一级目录继续查找;
  • 重复步骤2,直到到达$GOPATH/src目录,查找vendor目录中是否存在依赖包;
  • 如何没有查找到依赖包,则继续在$GOROOT目录查找;
  • 如果没有查找到,则继续在$GOPATH/src目录查找。

在发布 1.6 版本时,该环境变量的值已经默认设置为 1 了,该值可以使用 go env 命令查看。在发布 1.7 版本时,已去掉该环境变量,默认开启 vendor 特性。

优点:

vendor 将原来放在 $GOPATH/src 的第三方包放到当前工程的 vendor 目录中进行管理。它为工程独立的管理自己所依赖第三方包提供了保证,多个工程独立地管理自己的第三方依赖包,它们之间不会相互影响。 vendor 将原来包共享模式转换为每个工程独立维护的模式,vendor的另一个好处是保证了工程目录下代码的完整性,将工程代码复制到其他Go编译环境,不需要再去下载第三方包,直接就能编译,这种隔离和解耦的设计思路是一大进步。

缺点:

但vendor也有缺点,那就是对外部依赖的第三方包的版本管理。

我们通常使用 go get -u 更新第三方包。默认的是将工程的默认分支的最新版本拉取到本地,但并不能指定第三方包的版本。而在实际包升级过程中,如果发现新版本有问题,则不能很快回退,这是个问题。好在Go官方为了解决该问题推出了包依赖管理工具dep。与此同时,社区也有很多包管理工具,比较常用的有godep、govendor、glide。


三、Go Vendor

govendor 是一个基于 vendor 机制实现的 Go 包依赖管理命令行工具。与原生 vendor 无侵入性融合,也支持从其他依赖管理工具迁移,可以很方便的实现同一个包在不同项目中不同版本、以及无相互侵入的开发和管理。

功能:

  • 支持从项目源码中分析出依赖的包,并从 $GOPATH 复制到项目的 vendor 目录下;
  • 无法精确的引用外部包进行版本控制,不能指定引用某个特定版本的外部包;只是在开发时,将其拷贝过来,但是一旦外部包升级,vendor下的代码不会跟着升级;
  • 用 vendor/vendor.json 进行包和版本管理;
  • 支持用 govendor add/update 命令从 $GOPATH 中复制依赖包;
  • 如果忽略了 vendor/*/ 文件,可用 govendor sync 恢复依赖包;
  • 可直接用 govendor fetch 添加或更新依赖包;
  • 可用 govendor migrate 从其他 vendor 包管理工具中一键迁移到 govendor;
  • 支持 Linux,macOS,Windows,甚至现有所有操作系统;
  • 支持 Git、Hg、SVN,BZR(必须指定一个路径);

参考链接

  1. Go包管理详解
  2. Go Vendor简介
  3. linux go vendor目录,Go 包依赖管理工具 —— govendor