为了账号安全,请及时绑定邮箱和手机立即绑定

Go 1.5 中的包版本管理

Go 1.5 中的包版本管理

Go
慕盖茨4494581 2021-12-07 10:22:36
我开始接触 Go,虽然我理解并欣赏Go 所基于的简单原则,但我想了解在他们的依赖获取工具中放弃内置包版本控制方法背后的基本原理go get和该import声明。如果我理解正确,go get并import从中获取包HEAD,他们将无法引用分支或标签。虽然有像gopkg.in这样的工具可以绕过这个限制,但官方工具链:强制开发人员为其产品的主要(破坏性)版本创建单独的存储库。它不允许消费者在小版本或微型版本之间降级,以防在较新的版本中发现错误。说实话,事情并没有那么容易,因为包版本控制需要一种策略来处理冲突的传递依赖关系,例如X依赖A和B,每个依赖于不同版本的C.从 Java 背景来看,这个限制确实带来了一些风险和问题,其中包括:产品/包的演变和 3rd 方 deps 公共 API 的损坏是不可避免的,因此版本控制必须是工具链中的一等公民恕我直言。在Git的回购每版的政策是非常低效的:包的整体 Git 历史丢失或分散在存储库中(版本、向后移植等之间的合并)与传递依赖的冲突可能仍然会发生,并且不会被检测到,因为语言和工具链首先强加了任何允许检测的语义。鉴于以下情况,企业采用可能会受到阻碍,开发团队可能会回避该语言:总是拖延HEAD意味着他们无法控制或冻结他们的第 3 方部门,从而导致可能无法预测的最终产品。可能缺乏人力来保持他们的产品不断更新和与上游的测试HEAD(并非世界上的每家公司都是谷歌:))。虽然我确实理解后一种风险可以——而且必须——通过持续集成来减轻,但它并没有解决问题的根本根源。我缺少什么信息?在人力有限的企业中部署 Go 时,如何处理包上游变化?
查看完整描述

2 回答

?
浮云间

TA贡献1829条经验 获得超4个赞

它正在由作为 Go 1.5 的一部分作为实验性功能的vendoring解决,如果 go 命令GO15VENDOREXPERIMENT=1在其环境中运行,则可以启用它,并且将成为 Go 1.6 中的“完整”功能。另请参阅供应商目录。


可以在此处找到导致 Go 1.5 Vedor 实验的原始讨论。


vendoring 的本质是创建一个名为 的文件夹vendor,然后放置代码所依赖的包的确切版本。里面的代码vendor文件夹仅通过在父根的目录树中的代码可导入vendor,您可以从导入包vendor与导入路径,仿佛vendor将是workspace/src文件夹(也就是,与导入路径省略了前缀达并包括供应商元素)。


例子:


/home/user/goworkspace/

    src/

        mymath/

            mymath.go

            vendor/

                github.com/somebob/math

                    math.go

在此示例中github.com/somebob/math是mymath包 (from mymath.go)使用的外部包。mymath.go如果它是像这样导入的,则可以使用它:


import "github.com/somebob/math"

(而不是那样import mymath/vendor/github.com/somebob/math会很糟糕。)


查看完整回答
反对 回复 2021-12-07
?
天涯尽头无女友

TA贡献1831条经验 获得超9个赞

虽然 Go 没有标准包管理器,但有足够的选项来使构建可重现(即使在人力有限的企业中)。

  1. 供应商,@icza 在另一个答案中对此进行了描述。这几乎完全等同于在 Java 中检入版本控制的 jar 文件。在 maven 流行之前,这是 ant 构建工具非常常见的方法。实际上vendoring要好得多,因为您不会丢失源代码。

  2. 这是第一个选项的细微变化。您可以在构建期间通过检查依赖项的预定义版本来填充 vendor 文件夹,而不是检查 vendored 源代码。有一些工具(例如滑翔)可以自动化这个过程。

  3. 最后,您可以在内部存储库中维护所有第 3 方库的预定义版本并将其添加到 GOPATH。这种方法在https://blog.gopheracademy.com/advent-2015/go-in-a-monorepo/中有详细描述

请注意,不兼容的传递依赖不是 Go 特有的。它们也存在于 Java(和大多数其他语言)中,尽管 Java 有一种机制可以通过使程序更复杂来部分解决这个问题——类加载器。请注意,Go 将在编译时报告所有不兼容性,而在 Java 中,某些不兼容性仅在运行时触发(因为后期链接)。

Java 工具链没有版本的概念。它由外部工具 - maven 提供。我相信当 Go 变得更加成熟和流行时,将会出现一个类似的标准依赖管理工具。


查看完整回答
反对 回复 2021-12-07
  • 2 回答
  • 0 关注
  • 196 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信