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?