This is specific for: https://github.com/twitchtv/twirp
This library is currently on version v7, and we would like to migrate it into go modules. The library is currently imported from other libraries like this:
// go.mod
require github.com/twitchtv/twirp v7.2.0+incompatible
// .go code
import "github.com/twitchtv/twirp"
If we add a go.mod
file in the library, now every other library is forced to change the import paths like this:
// go.mod
require github.com/twitchtv/twirp v7.2.0
// .go code
import "github.com/twitchtv/twirp/v7"
How can we migrate the Twirp library to use go modules without forcing other libraries to update their import path?
The main issue here is that a single service may import multiple Twirp clients that were generated on different versions, and make use of helper functions that depend on specific types. Forcing the import path update would force all those helper functions to require managing both the old and new types, and we can't make aliases for all types (some types are functions). This would create an upgrade lock. Does this mean that the Twirp library needs to stay in +incompatible
mode forever?
You can't.
If your
go.mod
declares the module asgithub.com/twitchtv/twirp/v7
, then every client library (and your own packages) will have to update the import path. That's just how semantic import paths were intended to work in Go modules.If you use
v1
orv0
module path — which is written without the suffix — you are breaking the semver contract, since your project actually has alreadyv7
tags.Migrating to Go modules explicitly solves this in a clean way, i.e. clients that import multiple versions of your project just declare imports as
github.com/twitchtv/twirp/vX
etc, making it immediately apparent also in.go
files what versions they are using.Actually you have a very easy way to deal with this. Just migrate to Go modules declaring your module as with the next major version suffix
github.com/twitchtv/twirp/v8
, then tag itv8.x.y
. This is correct from a semver perspective, since your change is indeed breaking — your clients must change the import paths.This way, clients that do want to migrate to your Go modules version will know what to expect and deal with the implications of switching to a new major version, including rewriting the import paths. Whereas clients that do not want to migrate can keep importing a
v7.x.y
(or less) as+incompatible
.