Golang依赖管理的最佳实践

问题描述 投票:38回答:4

在Golang中,我们可以在GitHub上指定开源库作为依赖项。例如:

import "github.com/RichardKnop/somelibrary"

这将尝试根据您的Go版本查找分支,如果我理解正确,则默认为master。

因此无法导入依赖项的特定版本,例如:

import "github.com/RichardKnop/somelibrary#v1.4.8"

那么在Go中管理依赖关系的最佳实践是什么?

我可以看到两种方法。

I.版本模块

是否为具有重大变化的主要版本创建新模块?

例如,我的Go库可以定义模块v1和v2,那么你可以这样做:

import "github.com/RichardKnop/somelibrary/v1"

要么:

import "github.com/RichardKnop/somelibrary/v2"

根据您的需要。对v1或v2所做的任何更改都不需要破坏任何API或工作功能。

II。分叉

这将使您完全控制Go代码所需的外部依赖项版本。

例如,您可以将github.com/RichardKnop/somelibrary分叉到您自己的GitHub帐户中,然后在您的代码中执行以下操作:

import "github.com/ForkingUser/somelibrary"

然后你必须分叉所有外部依赖,这似乎有点矫枉过正。但是,它可以让您完全控制版本。您可以将叉子保留在您知道正在使用代码的版本中,并且只有在检查新版本的依赖项不会破坏任何内容后才能更新分叉。

思考?

go
4个回答
11
投票

注意:2015年6月,第一次支持售卖出现在Go 1.5中!

c/10923/

GO15VENDOREXPERIMENT=1在环境中时,此CL根据Go 1.5供应商提议更改导入路径的分辨率:

  • 如果有一个源目录d/vendor,那么,当编译一个源自d的子树中的源文件时,import "p"被解释为import "d/vendor/p"(如果存在)。
  • 当存在多种可能的分辨率时,最具体(最长)的路径获胜。
  • 必须始终使用简短形式:没有导入路径可以明确包含“/vendor/”。
  • 在vendored包中忽略导入注释。

2016年1月更新:Go 1.6将使默认销售。 并且在the article "MOST GO TOOLS NOW WORK WITH GO15VENDOREXPERIMENT"中有详细说明:

1.6开箱即用支持/vendor/到大多数工具(如oracle);使用Beta重建它们。


15
投票

2018年2月:如果将vgo集成到工具链中,下面提出的销售方法(2015/2016)可能会消失。 见my answer below


2015年8月版:Go 1.5附带内置(但仍为实验性)的支持。设置环境变量GO15VENDOREXPERIMENT将使go build和朋友在./vendor目录以及GOPATH中查找包。有关详细信息,请参阅VonC's answerdesign document


III. Vendoring

AFAIK,这是确保您的构建具有可重现性和可预测性的最广泛使用的方法。 Go团队本身在他们的回购中加入了uses vendoring。 Go团队现在讨论统一依赖清单文件格式。来自Go toolchain developers mailing list

在Google的内部源代码树中,我们将所有依赖项供应(复制)到源代码树中,并且最多只有一个任何给定外部库的副本。我们只相当于一个GOPATH并重写我们的导入以引用我们的销售副本。例如,想要使用“golang.org/x/crypto/openpgp”的Google内部的Go代码会将其导入为“google / third_party / golang.org / x / crypto / openpgp”之类的内容。

(...)

我们的建议是Go项目,

  • 官方建议使用导入重写(不是GOPATH修改)作为引入依赖关系的规范方法来销售到“内部”目录。
  • 为依赖项和vendoring定义了一个通用的配置文件格式
  • 在Go 1.5中没有对cmd / go进行代码更改。诸如“godep”或“nut”之类的外部工具将实现1)和2)。我们可以在Go 1.6+中重新评估包括这样的工具。

7
投票

2018年8月更新:这个(下面提到的vgo)现在用Go 1.11 and modules实现。

3年后的2018年2月更新。

来自核心Golang开发团队的Russ Cox开发了一种新方法。

vgo项目。

go get -u golang.org/x/vgo

这个提议:

  • 保持go get最好的部分,
  • 增加可重复的构建,
  • 采用语义版本控制,
  • 消除了装修,
  • 弃用GOPATH以支持基于项目的工作流程,以及
  • 提供了dep及其前辈的平稳迁移路径。

vgo semver

它基于一个新的MVS ("Minimal Version Selection") algorithm

https://research.swtch.com/version-select-2.png

你可以看到:


2018年5月:Artifactory proposes a vgo proxy

最近发布的Artifactory 5.11增加了对vgo兼容的Go注册表(以及代理)的支持,在使用Go进行开发时为社区提供了各种功能。 以下是其中一些:

  • Artifactory中的本地存储库允许您根据项目或开发团队为程序包设置安全的私有Go注册表,并具有细粒度的访问控制。
  • Artifactory中的远程存储库是远程Go资源(如GitHub项目)的缓存代理。通过Artifactory访问go代理会消除您对网络或GitHub的依赖性,因为Go构建所需的所有依赖项都缓存在Artifactory中,因此在本地可用。这也消除了某人变异或从版本控制中删除依赖关系的风险,或者更糟糕的是,强制推动对远程Git标记的更改,从而改变应该是不可变版本,这可能会为依赖项目造成很多混乱和不稳定。
  • 虚拟存储库聚合本地和远程Go注册表,使您可以从单个URL访问构建所需的所有Go资源,从而隐藏了使用本地和远程资源组合的复杂性。

0
投票

也可以只描述maven中的依赖关系,如果要使用mvn-golang-wrapper,如果它在maven中看起来像下面的文本

<plugin>
 <groupId>com.igormaznitsa</groupId>
 <artifactId>mvn-golang-wrapper</artifactId>
 <version>1.1.0</version>
 <executions>
  <execution>
    <id>golang-get</id>
     <goals>
       <goal>get</goal>
     </goals>
     <configuration>
       <packages>
         <package>github.com/gizak/termui</package>
       </packages>
       <buildFlags>
         <flag>-u</flag>
       </buildFlags>
       <goVersion>1.6</goVersion>
     </configuration>
   </execution>
</plugin>
© www.soinside.com 2019 - 2024. All rights reserved.