在Go 1.5中打包版本管理 [英] Package version management in Go 1.5
问题描述
我用Go去弄脏自己的手,当我理解并欣赏Go的基础时, 的原理,我想要理解放弃内置的软件包版本控制方法在它们的依赖获取工具中 如果我理解正确, 事实并非如此简单,因为软件包版本控制将需要一个策略来处理冲突的传递依赖,例如 从Java背景来看,似乎这个限制带来了一些风险,问题等等: 第三方公共API的产品/软件包的演变和破坏是不可避免的,因此版本控制必须是在工具链恕我直言,一级公民。 企业采用可能会受到阻碍,开发团队可能会回避这种语言,因为: go get
和 import
语句。 / p>
go获取
并且 import
获取来自 HEAD
的包,它们无法引用分支或标签。虽然有 gopkg.in 这样的工具可以绕过这个限制,但官方工具链:
X
取决于 A
和 B
,每一个都取决于在不同版本的 C
中。
HEAD
意味着它们无法控制或者冻结他们的第三方代币,导致潜在的不可预测的最终产品。可能缺乏人力来保持他们的产品不断更新,并用上游的 HEAD $进行测试c $ c>(并非世界上每家公司都是Google:))。
<尽管我明白,后一种风险可以 - 而且必须 - 通过持续集成来缓解,但它并不能解决问题的根本根源。
什么信息我错过了吗?如何在人力有限的企业中部署Go时处理上游更改包?
解决方案href =https://golang.org/s/go15vendor =noreferrer> vendoring 作为Go 1.5的一部分,作为一项实验性功能,如果go命令使用<$在它的环境中,c $ c> GO15VENDOREXPERIMENT = 1 ,并且将成为Go 1.6中的完整功能。另请参阅供应商目录。
<导致Go 1.5 Vedor实验的原始讨论可以在这里。
vendoring的本质是您创建一个名为 vendor
的文件夹,而您把你的代码依赖的软件包的确切版本。 供应商
文件夹内的代码只能由源自 vendor
的父目录树中的代码导入,而您可以使用导入路径从 vendor
导入包,就好像 vendor
应该是 workspace / src
文件夹(也就是说,使用导入路径省略前缀并包含vendor元素)。
示例:
/ home / user / goworkspace /
src /
mymath /
mymath.go
vendor /
github.com/somebob/math
math.go
在这个例子 github.com/somebob/math
是一个由 mymath
包使用的外部包(来自 mymath.go
)。它可以从 mymath.go
中使用,如果它被导入的话:
importgithub.com/somebob/math
<并不是 import mymath / vendor / github.com / somebob / math
这会很糟糕。)
I'm getting my hands dirty with Go, and while I understand and appreciate the principle of simplicity that Go was built upon, I'd like to grasp the rationale behind forgoing a built-in package versioning method in their dependency-fetching tool go get
and the import
statement.
If I understand correctly, go get
and import
fetch the package from HEAD
and they are unable to refer to a branch or a tag. While there are tools like gopkg.in that circumvent this limitation, the official toolchain:
- Forces developers to create separate repos for major (breaking) versions of their products.
- It doesn't allow consumers to downgrade between minor or micro versions in case bugs are found in newer ones.
Truth be told, things are not so easy because package versioning would require a strategy to deal with conflicting transitive dependencies, e.g. X
depends on A
and B
, each of which depend on different versions of C
.
Coming from a Java background, it does appear that this limitation poses some risks and problems, amongst others:
Product/package evolution and breakage of public APIs of 3rd party deps is unavoidable, therefore versioning must be a first-class citizen in the toolchain IMHO.
The Git-repo-per-version policy is highly inefficient:
- The overall Git history of the package is lost or scattered across repos (merges between versions, backports, etc.)
- Conflicts with transitive dependencies may still occur, and will go about undetected because the language nor the toolchain impose any semantics to allow detection in the first place.
Enterprise adoption may be hindered and development teams may shy away from the language, given that:
- Always dragging in
HEAD
means that they can't control or freeze their 3rd party deps, leading to a potentially unpredictable end product. - May lack the manpower to keep their product constantly updated and tested with upstream's
HEAD
(not every company in the world is Google :)).
- Always dragging in
While I do understand that the latter risk can be – and must be – mitigated with Continuous Integration, it does not solve the underlying root of the problem.
What information am I missing? How do you deal with package upstream changes when deploying Go in an enterprise with limited manpower?
It is being addressed by vendoring which is part of Go 1.5 as an experimental feature, it can be enabled if the go command is run with GO15VENDOREXPERIMENT=1
in its environment, and will be a "full" feature in Go 1.6. Also see Vendor Directories.
The original discussion that led to the Go 1.5 Vedor Experiment can be found here.
The essence of vendoring is that you create a folder named vendor
, and you put the exact version of the packages that your code relies on. Code inside the vendor
folder is only importable by the code in the directory tree rooted at the parent of vendor
, and you can import packages from vendor
with an import path as if vendor
would be the workspace/src
folder (that is, with an import path that omits the prefix up to and including the vendor element).
Example:
/home/user/goworkspace/
src/
mymath/
mymath.go
vendor/
github.com/somebob/math
math.go
In this example github.com/somebob/math
is an external package used by mymath
package (from mymath.go
). It can be used from mymath.go
if it is imported like:
import "github.com/somebob/math"
(And not as import mymath/vendor/github.com/somebob/math
which would be bad.)
这篇关于在Go 1.5中打包版本管理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!