A little while ago we were hitting yet another issue with dependencies related to version pinning at work. I tried to divine what the disparate versions mean, and came up with this flow chart from a legalistic reading of stack overflow issues [1] and the go modules doc [2]:
has the package opted into go modules (i.e. is there a go.mod?)
yes
does the repository use semver?
yes
is the major version <= 1?
yes
=> normal versioning, e.g. github.com/stretchr/testify v1.3.0
no
=> when importing, we need add /vN at the end, e.g., import "github.com/my/mod/v4", and in go.mod it will behave like github.com/my/mod/v4 v4.1.0
no
=> pseudo-versioning will be used, e.g. github.com/kolo/xmlrpc v0.0.0-20190717152603-07c4ee3fd181
no
does the repository use semver?
yes
is the major version <= 1?
yes
=> pseudo-versioning will be used, e.g. github.com/kolo/xmlrpc v0.0.0-20190717152603-07c4ee3fd181
no
=> version will be marked as incompatible, e.g. github.com/zeromq/goczmq v4.1.0+incompatible
no
=> ???
I still don't know if this is right. But that's not really the point. I think the go authors painted themselves into a corner with such an anemic initial release. Now that they're trying to address shortcomings, the complexity is blowing up to handle the very large/diverse ecosystem. It reminds me a lot of java around 1.4 when they added in generics. In the long-run it was the right move, but man was it painful.1: https://stackoverflow.com/a/57372286 2: https://github.com/golang/go/wiki/Modules