【问题标题】:How should I use vendor in Go 1.6?我应该如何在 Go 1.6 中使用 vendor?
【发布时间】:2016-09-11 05:54:51
【问题描述】:

首先我阅读了这个答案:Vendoring 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。

【问题讨论】:

标签: go vendor


【解决方案1】:

使用 Go1.6,在您阅读时内置了供应商。这是什么意思?只需要记住一件事:

在使用go buildgo rungo工具时,首先会检查依赖项是否位于./vendor/中。如果是这样,请使用它。如果没有,请恢复到$GOPATH/src/ 目录。

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

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

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

一种更简单的方法,而不是手动复制所有内容

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

让我提两个与供应商文件夹一起使用并且不会与您对抗的方法:

  • godep
  • 总督

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

例如,假设您已在 $GOPATH/src/ou/ 项目中使用正常的 GOPATH/src/github 安装您的依赖项安装了所有依赖项并正常工作。您的项目运行并且您的测试验证一切都与您拥有的 repos 的确切版本一起工作。以 Godep 为例,您可以从项目根文件夹 $GOPATH/src/ou/ 运行它:

godep save ./...

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

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

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

过度使用依赖管理工具

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

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

绝对使用依赖管理。

但是,在现实中过度使用锁定大量依赖项的简单项目......

您可能只需要锁定 1 个依赖项;否则,您需要最新版本的 MySQL 驱动程序和测试断言框架来修复错误。

这是使用 ./vendor/ 文件夹而不是依赖项管理工具的真正亮点:您只需要复制需要锁定的存储库。

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

嘿,这个 repo 需要在这个版本中保留。所有其他都很好,使用最新的并经常使用go get -u ./... 进行更新;但是,这个更新版本失败了,所以不要升级这个 repo。

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

供应商文件夹中的 20 个存储库中的一个或多个存储库可能存在问题,也可能不存在问题。您可能无法更新它们。您可能无法获得最新的 MySQL 驱动程序。我们根本不知道哪个可能会或可能不会导致问题,只是锁定了在我运行godep save 时有效的东西。所以,是的,升级需要您自担风险。

就个人而言,我遇到过几次。一个依赖项通过重大更改进行了更新,我们有数十个依赖于它的 repos。仅在 /vendor 中提供一个 repo 允许我们使用该一个版本的依赖项,而 go get ./... 继续正常运行,以便所有其他 repo 获取最新版本。我们在 PSQL 和 MySQL 等中使用了最新的错误修复(这些错误不断得到修复!)等等。

【讨论】:

  • @Joakim 我很确定 $GOPATH/src/ 文件夹中的目录本身被视为项目。在您的示例中, ./src/vendor 被视为一个名为“vendor”的项目。相反,创建一个项目文件夹,如$GOPATH/src/acmecorp/。然后,其中有一个供应商文件夹,例如$GOPATH/src/acmecorp/vendor。然后 CD 到 $GOPATH/src/acmecorp/ 并构建你的项目。阅读如何组织你的 Go 代码:golang.org/doc/code.html#Organization
  • 关于依赖管理过度的好点!甚至没有人讨厌:D
  • 当您将模块的代码复制到您的vendor 目录时,请记住,如果原始代码是 GitHub 存储库,它将包含一个 .git.github 文件夹。如果您将这些目录提交到您的存储库并将其推送到 GitHub,则代码将注册为子模块,而不是在您的 GitHub 存储库中。如果您想要一个子模块,这可能没问题,但如果您不只是在推送到 GitHub 之前从 vendor 目录中删除 .git.github 文件夹。
  • 请注意,您自己的代码不能存在于$GOPATH 结构之外以使vendor 工作。
  • 好吧,好吧,如果你想要一个,看来你可以使用 golang.org/src/go/build/build.go?s=9943:9963#L352,它是 go build 代码的一部分。
猜你喜欢
  • 1970-01-01
  • 2016-06-30
  • 1970-01-01
  • 2019-09-21
  • 2013-11-13
  • 1970-01-01
  • 1970-01-01
  • 2019-10-07
  • 2019-06-02
相关资源
最近更新 更多