Go 1.5中的包版本管理

时间:2016-01-13 19:47:38

标签: go

我用Go弄脏了手,虽然我理解并欣赏Go所建立的简单的原则,但我想了解背后的理由。在依赖项提取工具-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSLog(@"didSelectRowAtIndexPath Row %ld",(long)indexPath.row); } go get语句中使用内置包版本控制方法

如果我理解正确,importgo get会从import获取包,但他们无法引用分支或标记。虽然有像gopkg.in这样的工具可以绕过这个限制,但官方的工具链是:

  1. 强制开发人员为其产品的主要(破碎)版本创建单独的回购。
  2. 如果在较新版本中发现错误,则不允许消费者在次要版本或微型版本之间降级。
  3. 说实话,事情并不那么容易,因为软件包版本控制需要一种策略来处理冲突的传递依赖关系,例如: HEAD取决于XA,每个B取决于C的不同版本。

    来自Java背景,似乎这种限制带来了一些风险和问题,其中包括:

    1. 产品/包装的演变和第三方公共API的破坏是不可避免的,因此版本控制必须是工具链恕我直言中的一等公民。

    2. Git-repo-per-version 政策效率极低:

      • 包的整体Git历史记录在repos中丢失或分散(版本,backport等之间的合并)
      • 与传递依赖的冲突可能仍然会发生,并且将不会被发现,因为语言和工具链强加了任何语义以允许首先进行检测。
    3. 企业采用可能受阻,开发团队可能会回避语言,因为:

      • 始终拖入HEAD意味着他们无法控制或冻结他们的第三方代表,从而导致潜在的无法预测的最终产品。
      • 可能缺乏人力来保持他们的产品不断更新并使用上游HEAD进行测试(并非世界上每家公司都是谷歌)。
    4. 虽然我确实理解后一种风险可以 - 并且必须 - 通过持续集成来缓解,但它并不能解决问题的根本原因。

      我错过了哪些信息?在人力资源有限的企业中部署Go时,如何处理包上游变更?

2 个答案:

答案 0 :(得分:7)

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

可以找到导致Go 1.5 Vedor实验的原始讨论here

vendoring的本质是您创建一个名为vendor的文件夹,并放置代码所依赖的软件包的确切版本。 vendor文件夹中的代码只能由源自vendor父目录树的目录树中的代码导入,您可以使用导入路径从vendor导入包,就好像{{1将是vendor文件夹(即,使用导出路径省略前缀并包括供应商元素)。

示例:

workspace/src

在此示例中,/home/user/goworkspace/ src/ mymath/ mymath.go vendor/ github.com/somebob/math math.go github.com/somebob/math包(来自mymath)使用的外部包。如果导入如下,则可以从mymath.go使用它:

mymath.go

(而不是import "github.com/somebob/math" 哪个不好。)

答案 1 :(得分:1)

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

  1. 供应,在@icza的另一个答案中描述。这几乎完全等同于在Java中检入版本化的jar文件。在maven变得流行之前,这是使用ant构建工具的非常常见的方法。实际上,销售要好得多,因为你不能丢失源代码。

  2. 这是第一个选项的轻微变化。您可以通过检查预定义的依赖项版本,在构建期间填充供应商文件夹,而不是检查已售出的源代码。有自动完成此过程的工具(例如滑行)。

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

  4. 中详细介绍了此方法

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

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