当 Go 首次发布时,开发人员需要的东西和
go
工具提供的东西之间的差距变得很明显。这个差距是供应商包的管理,这很快导致
Godep
和
GPM
等应用程序的兴起来满足这一需求。随着 Go 1.5 的发布,
go
工具链发生了变化,开始在本地解决这个差距。在这篇文章中,我将讨论它的工作原理以及如何利用它。
需求
Go 中的包需要存在于
GOPATH
中。当包在
GOPATH
之外或者当你在
GOPATH
中有多个目录时,
go
工具链会做出某些假设和问题。
传统上,您在
GOPATH
中只能有一个版本的包,并使用
go get
检索 master 分支上的最新版本。它未设置为检索特定版本。当两个开发人员将不同版本的依赖包获取到他们正在使用的包时会发生什么?或者,当您处理两个需要相同依赖项的不同版本的包时会发生什么?您很容易以无法重现的环境告终。
为了解决这个问题,Godep 和 GPM 等工具介入了这个问题。例如,Godeps 允许您拍摄依赖包的快照以存储在子目录中,然后其他人可以恢复该版本。
要是 Go 工具链能帮助解决这个问题就好了。
供应商名录
随着 Go 1.5 的发布,有一个新的选择加入功能(计划在未来默认启用)。它提供了一种以 Go 工具可以使用的方式指定供应商包的方法。
首先,您需要将环境变量
GO15VENDOREXPERIMENT
设置为
1
。这就是您目前选择加入的方式。一旦你这样做了,你的项目就会有一个包含你的依赖项的特殊供应商目录。布局看起来像:
- GOPATH/github.com/example/foo
|
- main.go
- vendor/
|
- github.com/
|
- foo/bar
- Masterminds/vcs
您的项目通常位于
GOPATH
中。但是,您的项目依赖项可以位于
vendor/
目录中。当
go
查找源代码中引用的包时,它将在
vendor/
目录中查找,然后在
GOPATH
中查找,然后在
GOROOT
中查找(标准库包如
fmt
所在的位置)。
这允许您拥有特定于包的依赖包的版本,而不会受到黑客攻击。
这甚至可以递归地工作。例如,如果你的一个依赖包有一个 vendor 目录,其中有依赖项,那么它们也会被解析。而且,如果两个依赖包具有相同依赖项的不同版本,则将使用正确的那个。
这种递归性质可能会引入横向问题,因此我建议在使用它时要格外小心。
管理工具
1.5 中的
go
工具所做的只是我刚才描述的。那么,如何管理
vendor/
目录中的包呢?
这是我会有点自以为是的地方。当 Go 1.5 发布时,我们将 Glide 转为一个支持工具。目标是帮助其他人通过这种处理依赖项的新方法取得成功。
Glide 提供了一种在
vendor/
目录中记录、获取和管理依赖项的方法,同时可以干净地使用
go
工具链。它试图补充 Go 中的功能。
你可以使用 Glide 在不同的环境和开发者之间重复安装相同的依赖版本。您可以将其视为类似于 npm 、 composer 、 bundler 和其他语言使用的包管理器的东西。
如果你想从供应商那里提供依赖项,即将依赖包的源文件存储在你的源代码控制系统中,Glide 也可以工作。
Glide 有很多其他的管理功能,我们计划继续沿着这条路发展,尝试让事情变得简单。
注意:在
vendor/
目录中还有其他用于管理依赖项的工具。选择一个工具时,请确保您了解该工具的用途及其用途。
光明的未来
其他语言和平台已经形成了一些很好的模式,Go 工具链和周围的生态系统正朝着好的方向发展。我期待着我们的光明未来。