Idea for versioning in the new Go package manager.

270 views
Skip to first unread message

Martin Bertschler

unread,
Oct 26, 2016, 3:45:09 AM10/26/16
to golang-nuts
Hello Gophers!

Yesterday I attended a tech meetup and was introduced to the Elm language. The one thing that really stuck with me was how the Elm package manager handles semantic versioning for the package developers. As soon as things are added to the packages API, the minor version of the package is automatically bumped, and if the existing API of the package is changed, the major version is bumped.

I think this could be a great idea for the new package manager, since the whole Go ecosystem values stability and great tooling a lot. Some benefits of this feature that I can imagine:
  • Not having to think about the next version number, especially in small projects where I just want to publish some new code. Let the tool just choose one for you.
  • No accidental changes the public API during development, the tool would point out the API changes to you before publishing. If you didn't intend the change you could fix it.
  • Always correct usage of semantic versioning, that the whole ecosystem can depend on. This could enable automatic updates to always the newest patch version. 
Implementing it should not be hard because we already have things like https://golang.org/cmd/api/.

The full specification on how Elm handles that can be found here: https://github.com/elm-lang/elm-package

What are your thoughts on this matter?

Best,
Martin

Axel Wagner

unread,
Oct 26, 2016, 4:42:13 AM10/26/16
to Martin Bertschler, golang-nuts
I thought about this too, but came to the conclusion that this would first require a good definition of what "API breakage" actually means.

In it's strictest interpretation as "any go package that imports this will continue to build", there are literally no changes you could make to the API that wouldn't require a major version bump. Which is a correct, but useless implementation of semantic versioning.

So you need to make exceptions for (at least) dot-imports and embedding. But I don't really think it's reasonable to require people to not embed things. It's a powerful and important mechanism of composition.

Leaving aside my general belief, that semantic versioning is a broken idea, there still is the additional issue that the API isn't mapped completely by the type system. There are things (usually described in comments) that can break, that can't be automatically determined. So at the very least, you'd also need a way to override this mechanism and manually inject breakage-points (while, at the same time preserving the option to continue to use the mechanism in the future).

I am not convinced this is a good idea, but as long as there continues to be the option to develop without package managers and versions, I can't think of a reason for you not to do it :)

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Nigel Vickers

unread,
Oct 26, 2016, 5:32:35 AM10/26/16
to golang-nuts


On Wednesday, 26 October 2016 09:45:09 UTC+2, Martin Bertschler wrote:
Hello Gophers!

Yesterday I attended a tech meetup and was introduced to the Elm language. The one thing that really stuck with me was how the Elm package manager handles semantic versioning for the package developers. As soon as things are added to the packages API, the minor version of the package is automatically bumped, and if the existing API of the package is changed, the major version is bumped.

I have extreme reservations about "Semantic Versioning". It's neither Semantic nor Versioning. It's just an additional trigger system for source management. I associate it primarily with node.js and npm and thus "Developer Driven Updating". Working in an area where "Compliance" and "ISO Certification" is paramount such schemes are not usable. We have enough problems with dependency path rewriting in "Vendoring". 
With respect, I personally don't think this is a good idea.

Nigel Vickers

Rob Pike

unread,
Oct 26, 2016, 10:28:28 AM10/26/16
to Nigel Vickers, golang-nuts
Another problem with this approach is bloat. One part of the tree is built with version 1, another with version 2, but neither is truly dependent on the specifics of version 1 or 2: version 0 would work just fine for both. Thus the program links against two versions of the package when only one is required.

Automatically deciding what's important in a program's dependencies is not easy.

-rob


--

Sean Russell

unread,
Nov 1, 2016, 8:41:06 AM11/1/16
to golang-nuts, mbert...@gmail.com
Hi,


On Wednesday, October 26, 2016 at 4:42:13 AM UTC-4, Axel Wagner wrote:
I thought about this too, but came to the conclusion that this would first require a good definition of what "API breakage" actually means.

In it's strictest interpretation as "any go package that imports this will continue to build", there are literally no changes you could make to the API that wouldn't require a major version bump. Which is a correct, but useless implementation of semantic versioning.

While I agree that SemVer leaves API breakage loosely defined, I think you're concentrating on the major number and ignoring the value of the minor and patch numbers.  That said, there are cases SemVer fails to cover.
  1. Compile-time breakages (your strict definition): covered by major
  2. Strictly additions (new functions; no change to existing API calls): covered by minor
  3. Patches (bug fixes, no API changes): covered by patch
However, none of these provide any runtime guarantees.  Indeed, it is well known that fixing bugs can cause run-time breakages, especially in libraries, and these are much more difficult problems to solve than compile-time breakages.  I'd argue that the major number in SemVer is the least useful, since in a compiled language it covers changes that are the most obvious to identify and deal with.

Given that, while I'm generally an advocate of SemVer over the alternative (a chaos of undefined, un-navigable revision history), SemVer leaves a lot to be desired and could arguably be distilled into a single useful version number -- SemVer's "minor" number, declaring that the only thing that changed in an API were strict additions of functions, with no change to existing functions.  How often does that happen?  How much value, therefore, would this be?

There's something to be said for declaring your dependencies as VCS checksums.  SemVer or not, you won't know whether any dependency changes are going to affect your code until you update the dependencies, compile, and run your (hopefully copious) unit tests. 

Said another way: you can't trust SemVer; you can only trust reading the change log and your own unit tests.

--- SER
 

So you need to make exceptions for (at least) dot-imports and embedding. But I don't really think it's reasonable to require people to not embed things. It's a powerful and important mechanism of composition.

Leaving aside my general belief, that semantic versioning is a broken idea, there still is the additional issue that the API isn't mapped completely by the type system. There are things (usually described in comments) that can break, that can't be automatically determined. So at the very least, you'd also need a way to override this mechanism and manually inject breakage-points (while, at the same time preserving the option to continue to use the mechanism in the future).

I am not convinced this is a good idea, but as long as there continues to be the option to develop without package managers and versions, I can't think of a reason for you not to do it :)
On Wed, Oct 26, 2016 at 9:45 AM, Martin Bertschler <mbert...@gmail.com> wrote:
Hello Gophers!

Yesterday I attended a tech meetup and was introduced to the Elm language. The one thing that really stuck with me was how the Elm package manager handles semantic versioning for the package developers. As soon as things are added to the packages API, the minor version of the package is automatically bumped, and if the existing API of the package is changed, the major version is bumped.

I think this could be a great idea for the new package manager, since the whole Go ecosystem values stability and great tooling a lot. Some benefits of this feature that I can imagine:
  • Not having to think about the next version number, especially in small projects where I just want to publish some new code. Let the tool just choose one for you.
  • No accidental changes the public API during development, the tool would point out the API changes to you before publishing. If you didn't intend the change you could fix it.
  • Always correct usage of semantic versioning, that the whole ecosystem can depend on. This could enable automatic updates to always the newest patch version. 
Implementing it should not be hard because we already have things like https://golang.org/cmd/api/.

The full specification on how Elm handles that can be found here: https://github.com/elm-lang/elm-package

What are your thoughts on this matter?

Best,
Martin

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages