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

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

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

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

我可以看到两种方法。

I.版本模块

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

例如,我的Go库可以定义模块v1和v2,因此您可以执行以下操作:

要么:

根据您的需要。必须对v1或v2进行任何更改,以免破坏任何API或正常工作的功能。

二。分叉

这样可以完全控制Go代码所需的外部依赖版本。

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

然后,您将不得不分叉所有外部依赖项,这似乎有点过大。但是,它将完全控制版本。您可以将fork保持在您正在使用代码的版本上,并且只有在检查新版本的依赖项不会破坏任何内容之后才更新fork。

有什么想法吗?

2018年2月:如果将vgo集成到工具链中,则下面介绍的销售方法(在2015/2016年)可能最终消失。
请参阅下面的答案。

2015年8月版:Go 1.5带有内置(但仍处于试验阶段)的供应商支持。设置环境变量GO15VENDOREXPERIMENT将使go build和朋友在./vendor目录以及GOPATH中查找软件包。有关更多详细信息,请参见VonC的答案和设计文档。

三,供应商

AFAIK,这是最广泛使用的方法,可确保您的构建具有可复制性和可预测性。 Go团队本身在回购中使用供应商。 Go团队现在正在讨论统一的依赖清单文件格式。从Go工具链开发人员邮件列表中:

In Google’s internal source tree, we vendor (copy) all our dependencies into our source tree and have at most one copy of any given external library. We have the equivalent of only one GOPATH and rewrite our imports to refer to our vendored copy. For example, Go code inside Google wanting to use"golang.org/x/crypto/openpgp" would instead import it as something like"google/third_party/golang.org/x/crypto/openpgp".

(...)

Our proposal is that the Go project,

  • officially recommends vendoring into an"internal" directory with import rewriting (not GOPATH modifications) as the canonical way to pin dependencies.

  • defines a common config file format for dependencies & vendoring

  • makes no code changes to cmd/go in Go 1.5. External tools such as"godep" or"nut" will implement 1) and 2). We can reevaluate including such a tool in Go 1.6+.

注意:2015年6月,Go 1.5中首次提供了对卖家的支持!

参见c / 10923 /:

When GO15VENDOREXPERIMENT=1 is in the environment, this CL changes the resolution of import paths according to the Go 1.5 vendor proposal:

  • If there is a source directory d/vendor, then, when compiling a source file within the subtree rooted at d, import"p" is interpreted as import"d/vendor/p" if that exists.
  • When there are multiple possible resolutions, the most specific (longest) path wins.
  • The short form must always be used: no import path can contain"/vendor/" explicitly.
  • Import comments are ignored in vendored packages.

2016年1月更新:Go 1.6将使供应商成为默认供应商。
如文章"使用GO15VENDOREXPERIMENT现在可以使用更便宜的工具"中所述:

1.6 brings support for /vendor/ to most tools (like the oracle) out of the box; use the Beta to rebuild them.

  • 问题12278已解决。
  • goimports仍然存在问题,并且有一个CL可以选择

2018年8月更新:此(下面介绍的vgo)现在通过Go 1.11和模块实现。

3年后的2018年2月更新。

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

vgo项目。

1
go get -u golang.org/x/vgo

This proposal:

  • keeps the best parts of go get,
  • adds reproducible builds,
  • adopts semantic versioning,
  • eliminates vendoring,
  • deprecates GOPATH in favor of a project-based workflow, and
  • provides a smooth migration path from dep and its predecessors.

vgo semver

它基于新的MVS("最低版本选择")算法:

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

您可以看到:

  • Go&Versioning中的第一篇文章
  • 该主题中的讨论
  • Jon Calhoun对那个线程的分析
  • Sam Boyer在" vgo和dep的思想"中提出的对策:
    他领导了go dep的私人倡议
  • Russ,Sam和Jesse Frazelle之间的第一次辩论(YouTube)!

2018年5月:Artifactory建议使用vgo代理

The recent release of Artifactory 5.11 added support for vgo-compatible Go registries (and go proxy) giving the community a variety of capabilities when developing with Go.
Here are just a few of them:

  • Local repositories in Artifactory let you set up secure, private Go registries with fine-grained access control to packages according to projects or development teams.
  • A remote repository in Artifactory is a caching proxy for remote Go resources such as a GitHub project. Accessing a go proxy through Artifactory removes your dependency on the network, or on GitHub since all dependencies needed for your Go builds are cached in Artifactory and are therefore locally available. This also removes the risk of someone mutating or removing a dependency from version control, or worse, force-pushing changes to a remote Git tag thus changing what should be an immutable version which can create a lot of confusion and instability for dependent projects.
  • A virtual repository aggregates both local and remote Go registries giving you access to all Go resources needed for your builds from a single URL, hiding the complexity of using a combination of both local and remote resources.
  • 真正期待能够使用基于项目的工作流来开发Go(我认为您的意思是项目可以存在于gopath之外而没有问题)。 特别是有更多信息吗?
  • @DavidAlsh除了research.swtch.com/vgo-cmd的"构建和隔离规则"部分外,没有多少其他内容。 同时,Artifactory提出了与vgo(!)兼容的代理:jfrog.com/blog/goproxy-artifactory-go-registries

如果使用mvn-golang-wrapper,也可能只是在maven中描述依赖项,在这种情况下,如下所示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<plugin>
 <groupId>com.igormaznitsa</groupId>
 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>