在Golang中锁定外部依赖版本的最有效方法是什么?

23
默认情况下,Go会通过在主分支(Github)或默认分支(Mercurial)中抓取最新版本来获取导入的依赖项,如果在您的GOPATH中找不到该依赖项。虽然这种工作流程很容易理解,但对于严格控制来说有点困难。因为所有的软件更改都会涉及一些风险,我希望以可管理和可重复的方式减少潜在更改的风险,并避免在运行干净构建(通过CI服务器)或准备部署时意外地捕获依赖项的更改,特别是不小心选择了一个错误的依赖项。

我应该采取什么最有效的方式来锁定/捕获包依赖关系,使自己不会发现无法重现旧包,甚至更糟的是,在准备发布时出现意外的错误?

---- 更新 ----

有关Go打包的当前状态的其他信息. 尽管我最终(截至2013年7月20日)在第三方文件夹中捕获了依赖项并进行了更新管理(如Camlistore),但我仍在寻找更好的方法......

这里有一个很棒的选项列表.

此外,请务必查看Go 1.5供应商/实验,以了解Go将如何处理未来版本中的问题。


我听到的建议是:手动从外部源导入,并使用相对路径而不是自动路径。 - Dan
8
相对路径并不被推荐使用,因为有传言称Go工具将会彻底移除对其的支持。 - mna
5个回答

9
你可能会发现Camlistore的方式很有意思。
可以查看third party directory,尤其是update.plrewrite-imports.sh脚本。这些脚本更新外部存储库,必要时更改导入,并确保将外部存储库的静态版本与camlistore代码一起检入。
这意味着camlistore具有完全可重复的构建,因为它是自包含的,但第三方组件可以在camlistore开发人员的控制下进行更新。

7

有一个项目可以帮助您管理依赖关系。请查看gopack


5

godep

我在去年早些时候(2014年)开始使用godep,并对其非常满意(它符合我在原始问题中提到的关注点)。我不再使用自定义脚本来管理依赖项的vendoring,因为godep会处理它。它非常出色,无论时间或计算机软件包状态如何,都可以确保不引入漂移。它与现有的go get机制一起工作,并引入了根据Godeps/godeps.json固定(godep save)和恢复(godep restore)的能力。

快去看看吧:

https://github.com/tools/godep


1

Go语言中没有此功能的内置工具。但是您可以在本地磁盘或云服务上分叉依赖项,并仅在审核后合并上游更改。


1
第三方仓库完全在您的控制之下。'go get' 克隆最新版本,没错,但是您可以自由检出已被 go get 克隆或者您自己克隆的仓库的任何修订版本。只要不运行 'go get -u',已经存在于硬盘上的第三方仓库就不会被更改。
实际上,默认情况下,您本地克隆的外部依赖始终被锁定。

11
尽管需要明确的是,这种默认行为仅锁定了此特定计算机上的依赖项。如果您在另一台计算机上安装完全相同的软件包,则可能会下载和安装完全不同版本的第三方依赖项。在社区中有大多数人接受的更好方法出现之前,对于大型项目来说,分叉依赖项或将依赖项检入版本控制(请参见Camlistore答案)似乎是下一个最好的选择。 - mna
3
好的,我明白了。但正如@PuerkitoBio所暗示的那样,我无法保证机器没有在运行 go get 时无意中引入了一个不同版本的软件包(取决于它们何时运行)而不采取其他步骤(例如分叉或将第三方存储库软件包检入源代码控制等)。我的意图是找出人们在处理这个问题时采取了哪些额外步骤(特别是涉及多台开发者计算机或重新构建CI计算机时)。 - Matt Self
@PuerkitoBio 当然,但假设所有依赖库都托管在GitHub上,您可以通过克隆所使用的存储库来保留状态。这不是消除超过95%的所有担忧的方法吗? - aholbreich

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接