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:
When it moved beyond v1 it had to change. For example, here is the change for v3:
The version is in the module path.
go get to retrieve a version changes as well. With version 1 the command could look like:
$ go get github.com/Masterminds/[email protected]
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:
$ go get github.com/Masterminds/semver/[email protected]
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:
require github.com/Masterminds/semver/[email protected]
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
This is just a quick primer. There are more details in the Go wiki and docs if you need more details.