Working with Go modules whose major version is 2 or greater is different than working version 0 or 1 and is different than doing so with the tools that came before it like dep and glide. There are changes that need to be made to both the module and the way it’s consumed. Having had to work through this with semver, here are some practical things I’ve learned along the way.

go.mod Module Name

Once you hit v2 of a module, which is often the code in a repository, the go.mod file needs some changes. For example, the first line of the semver package for v1 would have been:

module github.com/Masterminds/semver

When it moved beyond v1 it had to change. For example, here is the change for v3:

module github.com/Masterminds/semver/v3

The version is in the module path.

Changes Using go get

Using go get to retrieve a version changes as well. With version 1 the command could look like:

But, if you tried to change the version to v3.0.1, the latest v3 release at the time of this writing, you’d get an error. The major version needs to be part of the path. You would need to use:

Requiring modules

Requiring modules follows this same paradigm. This is for both the require statements within the .go files and the go.mod require statement.

For example, to require v3 the go.mod file pulling in semver would need to have a line like:

and the require statements in the code would need to import github.com/Masterminds/semver/v3 . The calls to functions in the package don’t need to change unless you’re working with multiple versions of the same package. For example, when importing v3 a call to semver.NewVersion would still work as expected.

If the changes to the import statements aren’t made Go will try get the latest v1 release, update the go.mod file to include the v1 release, and use that. This happens when running commands like go build . If you didn’t know, go build can modify your go.mod file.

This is just a quick primer. There are more details in the Go wiki and docs if you need more details.