我应该如何在 Go 1.6 中使用供应商?

How should I use vendor in Go 1.6?

首先我读了这个答案:,然后我用它作为我的例子。

我的gopath是GOPATH="/Users/thinkerou/xyz/",如下:

thinkerou@MacBook-Pro-thinkerou:~/xyz/src/ou$ pwd
/Users/baidu/xyz/src/ou
thinkerou@MacBook-Pro-thinkerou:~/xyz/src/ou$ ls
main.go vendor

现在,我用go get,然后变成这样:

thinkerou@MacBook-Pro-thinkerou:~/xyz/src/ou$ ls
main.go vendor
thinkerou@MacBook-Pro-thinkerou:~/xyz/src/ou$ cd vendor/
thinkerou@MacBook-Pro-thinkerou:~/xyz/src/ou/vendor$ ls
vendor.json
thinkerou@MacBook-Pro-thinkerou:~/xyz/src/ou/vendor$ cd ../..
thinkerou@MacBook-Pro-thinkerou:~/xyz/src$ ls
github.com ou
thinkerou@MacBook-Pro-thinkerou:~/xyz/src$ cd github.com/
thinkerou@MacBook-Pro-thinkerou:~/xyz/src/github.com$ ls
zenazn

vendor.json是这样的:

{
    "comment": "",
    "package": [
        {
            "path": "github.com/zenazn/goji"
        }
    ]
}

那么,我应该使用什么指令呢?为什么没有用vendor?我的go版本是1.6.2.

在 Go1.6 中,vendoring 是在您阅读时内置的。这是什么意思?只有一件事要记住:

When using the go tools such as go build or go run, they first check to see if the dependencies are located in ./vendor/. If so, use it. If not, revert to the $GOPATH/src/ directory.

Go 1.6 中的实际“查找路径”依次为:

./vendor/github.com/zenazn/goji
$GOPATH/src/github.com/zenazn/goji
$GOROOT/src/github.com/zenazn/goji

话虽如此,go get 将继续安装到您 $GOPATH/src 中;并且,go install 将安装到 $GOPATH/bin 用于二进制文件或 $GOPATH/pkg 用于包缓存。

那么,我该如何使用 ./vendor?!?!

呵呵,有了上面的知识,其实很简单:

mkdir -p $GOPATH/src/ou/vendor/github.com/zenazn/goji
cp -r $GOPATH/src/github.com/zenazn/goji/ $GOPATH/src/ou/vendor/github.com/zenazn/goji

简而言之,要使用 vendoring,您可以使用相同的 github.com/zenazn/goji 完整路径将文件复制到您的 vendor director 中。

现在,go build/install/run 工具将看到并使用您的供应商文件夹。

无需手动复制所有内容的更简单方法

与其查找和复制所有 25 个以上的供应商项目、管理它们的版本、更新其他项目等...不如使用 依赖管理工具。那里有很多,稍微谷歌一下就会找到几个。

让我提两个与 vendor 文件夹一起工作并且不会与你作对的:

  • godep
  • 政府官员

简而言之,这些工具将检查您的 ou 代码,找到远程依赖项,然后将它们 复制到您的 $GOPATH/src 你的 $GOPATH/src/ou/vendor 目录(实际上,当你 运行 他们时你所在的当前目录)。

例如,假设您使用正常的 GOPATH/src/github 安装依赖项,并在 $GOPATH/src/ou/ 项目中安装并正常工作。您的项目 运行s 和您的测试验证一切都在使用您拥有的回购协议的确切版本。以 Godep 为例,您可以从您的项目根文件夹 运行 $GOPATH/src/ou/:

godep save ./...

这会将您的项目使用的所有依赖项复制到您的 ./vendor 文件夹中。

Godep 是迄今为止最受欢迎的。他们在 Gopher Slack 组上有自己的 Slack 频道。而且,这是我在我的团队中使用的。

Govendor 是我读到的另一种选择,它具有很好的同步功能。不过我没用过。

过度使用依赖管理工具

这纯粹是个人意见,我敢肯定仇恨者会投反对票...但是由于我需要完成关于这个主题的博客 post,所以让我在这里提一下,大多数人都太担心依赖性了Go 中的管理。

是的,需要将回购锁定到您所依赖的版本,这样您就可以确保您的系统在生产环境中构建。是的,需要确保不会对依赖项中断某事的方式进行重大更改。

绝对使用依赖管理。

但是,过度使用简单的项目会锁定大量的依赖项,而实际上...

You may only need to lock in only 1 dependencies; otherwise, you want the latest version of MySQL drivers and test assertion frameworks for bug fixes.

这就是除了依赖管理工具之外使用 ./vendor/ 文件夹的真正好处:您只需要复制需要您锁定的存储库。

您有选择地选择一个行为不当的存储库并将其放入您的 ./vendor/ 文件夹中。通过这样做,您是在告诉您的消费者:

Hey, this one repo needs to be held back at this revision. All others are fine and use the latest of those and update often with go get -u ./...; but, this one failed with newer versions so don't upgrade this one repo.

但是,如果使用依赖管理工具一揽子保存所有依赖项,您基本上是在告诉您的消费者:

There may or may not be a problem with one or more repos out of the 20 in the vendor folder. You may or may not be able to update them. You may or may not be able to get the latest MySQL driver. We simply don't know which may or may not be causing problems and just locked in something that worked at the time that I ran godep save. So yeah, upgrade at your own risk.

就我个人而言,我 运行 多次参与其中。依赖项已更新为重大更改,我们有数十个依赖它的回购协议。仅供应 /vendor 中的那个 repo 允许我们使用那个版本的依赖项,而 go get ./... 继续 运行 通常所有其他 repo 获取最新版本。我们 运行 修复了 PSQL 和 MySQL 以及其他方面的最新错误(这些问题有持续的修复!)等等。