SemVer v3 Released

I’m happy to share that a new major release of github.com/Masterminds/semver, a semantic version package for Go, is here. This is version 3.0.0. This release was the result of following up on feedback, requests, and watching how semver was used in many real world situations. The v1 series is still in wide use and will be supported for some time. The work for that major version now happens on the release-1 branch.

Let’s take a look at what’s new in v3.

What Happened To v2?

You might be wondering, what happened to v2? Why jump from v1 to v3? When work on what would become dep started there was a desire to make changes to the way semver worked. On a 2.x branch, Sam Boyer began work on a major overhaul and we’d hoped this would be the future of semver. But, a couple things happened that changed course.

First, dep is now being replaced by Go modules. The semver package isn’t needed by it long term as dep is going to be archived, according to the Go team. The primary driver for it is gone and development stalled.

Second, many tools still use go get in their installation instructions and many people aren’t using Go modules. That means changing the API can cause breakages in tools that depend on semver. This happens even when those tools use a dependency manager to set versions because some people are routing around that. This problem even came up in the development of v3 where a breaking change caused people to come to issue queues, file issues, and create PRs to route around the problem. This is extra support work.

Until the Go community is generally using tools that support versions as a group it is a bit of extra support work to break public APIs.

v2 is not ready for any tagged releases even though it has some use. For example, the documentation needs some large updates.

So, we skipped a version to avoid confusion. It’s kind of like PHP 6 that way.

Upgrade Path From v1

Since the Go API didn’t change the upgrade path is fairly simple. In your dependency management tool request v3. If you want to opt into the one change you can opt into see below. Before using the new version see the changes in the v3 announcement.

Changes

If the API didn’t have breaking changes then what did? Let’s take a look.

A Change To ^

One of the biggest changes is to the ^ operator in comparisons. The way it evaluates ranges is different when the major version is 0. In that case it treats the minor version as the compatibility point unless the patch is specified. The docs share examples:

  • ^1.2.3 is equivalent to >= 1.2.3, < 2.0.0
  • ^1.2.x is equivalent to >= 1.2.0, < 2.0.0
  • ^2.3 is equivalent to >= 2.3, < 3
  • ^2.x is equivalent to >= 2.0.0, < 3
  • ^0.2.3 is equivalent to >=0.2.3 <0.3.0
  • ^0.2 is equivalent to >=0.2.0 <0.3.0
  • ^0.0.3 is equivalent to >=0.0.3 <0.0.4
  • ^0.0 is equivalent to >=0.0.0 <0.1.0
  • ^0 is equivalent to >=0.0.0 <1.0.0

This change is similar to the pattern in npm/js and Rust/Cargo. The difference from npm/js is the way prereleases are handled which you can read about in the semver documentation.

Spaces and Commas

And comparisons used to require a command between them (e.g., >=1.2.3, <2). The comma is now optional. It is still supported but not required. Like other tools >=1.2.3 <2 is now supported for ANDing conditions.

StrictNewVersion

One feature that can be opted into for creating Version instances is the StrictNewVersion function. While parsing it will validate the version passed in was strictly speaking a semantic version. The NewVersion function in v1 and v3 has performed coercion to try and turn a version into a semantic version. For example, v1.2 is not a valid semantic version. StrictNewVersion will return an error while NewVersion will return an object whose version is 1.2.0.

Take It For A Spin and Provide Feedback

The release is out the door. There are more tests, including fuzzing. Please try it out and let us know how this works for you.