Hacker News new | ask | show | jobs
by puddums 2690 days ago
Hi Steve, I've looked at this relatively carefully, and I believe that Go does 100% follow the semver spec (modulo any bugs in the implementation).

However, while that happens to be my personal belief, I am not any type of world-class semver expert, nor am a semver maintainer, and hence always happy to learn more (especially from, say, an actual semver maintainer such as yourself ;-)

I think you are saying "-ish" in your comment above at least partly based the two chunks of linked code above, including this comment there:

  // This package follows Semantic Versioning 2.0.0 (see semver.org)
  // with two exceptions. First, it requires the "v" prefix. Second, it recognizes
  // vMAJOR and vMAJOR.MINOR (with no prerelease or build suffixes)
  // as shorthands for vMAJOR.0.0 and vMAJOR.MINOR.0.
It is true that Go treats the leading "v" as a requirement for VCS tags to be recognized as encoding a semantic version. That said, as far as I am aware, requiring the "v" prefix for VCS tags is allowed by the semver spec, and it might be possible to draw a distinction between a semver version (which does not include a "v") vs. how a given semver version is encoded into a VCS tag (where an encoding is allowed to include a "v", as far as I am aware). For example, there is an FAQ that was added a few years ago to 'master' at github.com/semver/semver that seemed to address this:

prefixing a semantic version with a "v" is a common way (in English) to indicate it is a version number. Abbreviating "version" as "v" is often seen with version control. Example: git tag v1.2.3 -m "Release version 1.2.3", in which case "v1.2.3" is a tag name and the semantic version is "1.2.3".[1]

I am also aware that a leading "v" vs. no leading "v" for VCS tags can trigger some impassioned debate, so I might regret posting this comment. ;-)

Regarding the second piece from that comment above -- that particular Go package does have the ability to parse something like "v1" or "v1.2" (without the three integers required by semver). However, the result is not interpreted as a valid semver version by the overall 'go' tool. For example, a VCS tag such as "v1.2" that the 'go' tool finds on a git repository will _not_ be interpreted as a semantic version (because it does not have the required three integers). However, being able to parse something like "v1" or "v1.2" is used for example as part of a version query mechanism. For example, you can do something like "go get foo@v1.2" as a way of asking "please give me the highest available release version in >= v1.2.0 and < v2.0.0". In other words, it is a short-hand for a particular type of version query, which I would guess would not be in violation of the current semver 2.0 spec? If interested, there is some more information about that query mechanism (which is called a "module query") in the Go doc[2].

Finally, here is a snippet from the Go doc[3] stating semver is used (and there is a link to https://semver.org in that section as well):

The go command requires that modules use semantic versions and expects that the versions accurately describe compatibility

I wouldn't be shocked if you have a different take on some or all of what I said above, but wanted to at least share my personal understanding...

[1] https://github.com/semver/semver/blob/master/semver.md

[2] https://golang.org/cmd/go/#hdr-Module_queries

[3] https://golang.org/cmd/go/#hdr-Module_compatibility_and_sema...

1 comments

Hey hey!

So, primarily I am saying "ish" for two reasons: one, as I said below, I mis-understood how versions were actually used within Go. There's a lot of stuff out there, and keeping the three or four implementations I do know well is tough enough. Second, I don't want to say, definitively, that any particular implementation "does not implement Semver", because I think the spec is deficient enough that it's really hard to say in general.

On to your specific points:

> That said, as far as I am aware, requiring the "v" prefix for VCS tags is allowed by the semver spec

This is true, SemVer says nothing about VCSes.

> However, being able to parse parse something like "v1" or "v1.2" is used for example as part of a version query mechanism.

Right, so that's what I thought this was getting at, and the general "range" concept isn't in the spec, so all of that is fine, spec speaking.

However, that doc comment describes it a bit differently than you are. It describes them as version numbers. So it's possible that the doc comment is a bit mis-leading, maybe. That's very reasonable! This is why we need to clean up the spec text.

Makes sense. I guess the way I would summarize it is I believe the end-to-end Go system is 100% compliant with semver 2.0 spec. (And that is true to my knowledge even though there happens to be an internal-only 'semver' package that also contains Go-specific functionality related to semver, and that internal 'semver' package both must be used properly and is used properly to keep the overall end-to-end system semver spec compliant, including proper use of functions like isSemverPrefix(version) and similar to differentiate between what is allowed in a semver VCS tag vs. what is allowed for what is effectively a range-based query, etc.).

Again, happy to learn otherwise...