Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert to go modules #287

Closed
wants to merge 2 commits into from

Conversation

gurudesu
Copy link

@gurudesu gurudesu commented Nov 9, 2020

This partially resolves - particularly the concerns around requiring retool #169

The tooling will still need to be updated but this enables that and easier management of dependencies.

Description of Changes

Initializes the go.mod configuration and removes the dep and vendor folders.

We still are using the +incompatible versions but that will be addressed in another PR.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@marioizquierdo
Copy link
Contributor

marioizquierdo commented Nov 19, 2020

Using +incompatible may be the best tradeoff moving forward. I'm not sure we can find a satisfactory solution creating a new import path. This means, we should fix tools and documentation to work with go modules, and then release this as a major version (v8.0.0), but keep the import path defined in the go.mod as module github.com/twitchtv/twirp (without a v8 prefix).

The main issue with Twirp is that the generated code has some dependencies on the twirp package, and projects may import different generated clients. For example, imagine service Haberdasher is using the twirp/v8 package, and also importing a client that was auto-generated for service HatMaterial. That client constructor expects twirp.ClientOptions (does not accept v8.ClientOptions). Maybe it is easy to use both versions, but a 3rd library wrapping clients with some pre-defined configuration would need to handle both types. Such 3rd library could be updated too, but now we have a dependency lock. We could try to use aliases for types on different versions (as commented in #169 (comment)), but the types twirp.ServerHooks and twirp.ClientHooks can not be properly aliased, because they are structs with functions as properties, and some of those functions also depend on twirp types. Specifically the
twirp. ServerHooks.Error that has type func(context.Context, twirp.Error) context.Context. And precisely, most 3rd party tools and common libraries use Hooks as a point of integration with Twirp. Those would have to be updated to support both old and new versions simultaneously. Maybe they would have to accept interface{} parameters and use type checks on them. I'm not sure there's a better solution here.

Maybe think using +incompatible is not too bad, and overweights the benefits of using go modules as default tool. Maybe in the future there are better options to properly handle versions between generated code from different sources and its shared dependencies on the twirp package.

@marwan-at-work
Copy link
Contributor

@marioizquierdo @gurudesu

and then release this as a major version (v8.0.0), but keep the import path defined in the go.mod as module github.com/twitchtv/twirp (without a v8 prefix).

I'm afraid even that is impossible. +incompatible will not work either in this case.

+incompatible only works when you don't have a go.mod file. The moment you have a go.mod file, then you must follow Semantic Import Versioning.

If you merge this PR then two things will happen:

When a user go gets Twirp, then it will only return v1.x.x which will probably super old since we're already at v7.

If a user explicitly go gets a v8 that will have that go.mod file without SIV, then "go get" will fail.

So if this PR is merged and a tag is created, it will just end up breaking everything if I'm looking at things correctly.

@3ventic
Copy link
Contributor

3ventic commented Nov 21, 2020

The semantic versioning restriction in go get only applies to tags in the vX.X.X format, where the leading v is significant. That is, go get github.com/twitchtv/twirp@v8.0.0 will fail saying the major version must be v0 or v1 for that import path, but go get github.com/twitchtv/twirp@8.0.0 will work; it gets treated as a revision instead of a version and ends up in go.mod as v0.0.0-20201121-ff8409c or similar. It just comes down to the tag name.

@marwan-at-work
Copy link
Contributor

but go get github.com/twitchtv/twirp@8.0.0 will work; it gets treated as a revision instead of a version and ends up in go.mod as v0.0.0-20201121-ff8409c or similar

You really don't want to do that either as this will not be proper semver according to Go's definition of semver. And people who might try to go get github.com/twitchtv/twirp without @8.x.x will end up getting a completely older version which you also really don't want. It's very common for people to issue a go get without the @<version> or they might do @latest which will end up not getting 8.x.x.

I think the only path forward here is to adapt Go Modules the right way or to not adapt it at all.

@gurudesu
Copy link
Author

gurudesu commented Dec 2, 2020

Thanks for the input @marwan-at-work. Definitely sound likes we'll have to attempt a full migration if we would like to get this working and that's much hairier.

I'll close this PR.

@gurudesu gurudesu closed this Dec 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants