我应该使用 go mod 提交供应商目录吗?

hon*_*gsy 5 go go-modules

我在 go1.12 上使用 go 模块来处理我的 Go 依赖项。将vendor/目录也提交到版本控制中是最佳实践吗?

这与提交`vendor`目录是否最佳实践有关在使用dep. 使用dep,提交vendor/是获得真正可重复构建的唯一方法。go 模块呢?

icz*_*cza 14

除非您需要修改供应商的软件包,否则您不应该这样做。Go 模块已经为您提供了可重现的构建,因为该go.mod文件记录了您的依赖项的确切版本和提交哈希,该go工具将尊重并遵循这些。

vendor目录可以通过运行go mod vendor命令重新创建,并且默认情况下甚至会被忽略,go build除非您要求它与-mod=vendor标志一起使用它。

阅读更多详情:

Go wiki:如何使用模块的 vendoring?卖点会消失吗?

命令 go:模块和销售

命令 go:制作依赖项的供应商副本

  • @icza 直到什么时候?Go 代理公共服务提供什么保证,当项目从 github 中删除时,他们将继续提供 Go 模块(以及持续多长时间)?如果由于 github 和 Go 代理服务的某些审查而删除了依赖项怎么办?关键是所有这些假设和期望都不在我们的控制之下,而供应商中提交的包是本地的,并且在我们的项目中完全在我们的控制之下。 (5认同)
  • 如果您不打算将供应的模块提交到存储库,那么供应的意义何在? (4认同)
  • 还有一些其他情况,供应商模块可能有意义,可能值得一提:如果模块是从不切实际或无法从 CI/构建脚本访问的私有存储库导入的,或者如果您担心它可能会因以下原因而消失:不稳定的服务器或其他东西,或者如果您正在使用 [GopherJS,它还不支持模块](https://jhall.io/posts/gopherjs-with-modules/) :) (2认同)
  • 在我看来,这个答案并不好,甚至可能对新的 Go 开发者有害。从 github 中删除依赖项目时会发生什么?为什么 kubernetes 项目(以及许多其他项目)放置并提交他们的供应商文件夹? (2认同)

lub*_*ben 5

我想给出一些支持提交vendor,go.mod和 的论据go.sum

我同意接受的答案的论点,即它在技术上是不必要的并且会使 repo 膨胀。

但这里有一个反驳的清单:

  • 构建项目不依赖于 Github/Gitlab/... 或 Go 代理服务器上可用的某些代码。开源项目可能会因为审查、作者激励、许可变更或其他一些我目前无法想到的原因而消失,这确实发生在 JavaScript 包管理器 npm 上,并破坏了许多项目不在您的回购中,不在您的代码中。

  • 我们可能使用了内部或 3rd 方 Go 模块(私有),这些模块也可能消失或变得不可访问,但如果它们在供应商中提交,它们就是我们项目的一部分。没有任何意外中断。

  • 私有 Go 模块可能不遵循语义版本控制,这意味着 Go 工具在即时获取它们时将依赖最新的提交哈希。回购历史记录可能会被重写(例如 rebase),并且您、同事或您的 CI 工作可能最终会针对他们使用的依赖项使用不同的代码。

  • 提交供应商可以改进您的代码审查过程。通常,我们总是在单独的提交中提交依赖项更改,因此如果您很好奇,可以轻松查看它们。

这是一个与膨胀 repo 相关的有趣观察。如果我进行代码审查并且一个团队成员包含了一个包含 300 个文件的新依赖项(或更新了一个包含 300 个文件更改的依赖项),我会非常好奇地深入研究并开始讨论代码质量,需要进行此更改或替代 Go 模块。这实际上可能会降低二进制文件的大小和整体复杂性。

如果我只是go.mod在新的合并请求中看到一个新行,我什至不会考虑它。

  • 每次执行 CI 作业时,执行编译和构建步骤的 CI/CD 作业不需要浪费时间和网络来下载依赖项。所有需要的依赖都是本地的和存在的 ( go build -mod vendor)

这些就在我的头上,如果我想起了别的,我会在这里添加。