21

I forked a go module, and want to use the fork in my project that uses versioned modules via v1.12. My code is not inside my GOPATH.

My project's go.mod:

module github.com/me/myproj

go 1.12

require (   
    go.larrymyers.com/protoc-gen-twirp_typescript v0.0.0-20190605194555-ffbfe407b60f
)

replace go.larrymyers.com/protoc-gen-twirp_typescript => github.com/rynop/protoc-gen-twirp_typescript master

protoc-gen-twirp_typescript is a tool for protoc, so here is my tools.go:

// +build tools

package tools

import (
    // protocol buffer compiler plugins
    _ "github.com/golang/protobuf/protoc-gen-go"
    _ "github.com/mwitkow/go-proto-validators/protoc-gen-govalidators"
    _ "github.com/twitchtv/twirp/protoc-gen-twirp"
    _ "github.com/rynop/protoc-gen-twirp_typescript"
)

When I run go mod tidy to download my dependencies, I get this error:

go: finding github.com/rynop/protoc-gen-twirp_typescript master
go: finding github.com/rynop/protoc-gen-twirp_typescript latest
go: github.com/rynop/protoc-gen-twirp_typescript@v0.0.0-20190618203538-a346b5d9c8fb: parsing go.mod: unexpected module path "go.larrymyers.com/protoc-gen-twirp_typescript"

Why am I getting this error? I thought the replace directive in go.mod allows for the forked modules go.mod to stay untouched.

rynop
  • 50,086
  • 26
  • 101
  • 112

2 Answers2

16

You have the following replace:

replace go.larrymyers.com/protoc-gen-twirp_typescript => github.com/rynop/protoc-gen-twirp_typescript master

which if I've followed, is effectively replace originalname => forkname

I think the issue is that you are importing using the name of the fork, rather than the original name:

import (
    // protocol buffer compiler plugins
    _ "github.com/golang/protobuf/protoc-gen-go"
    _ "github.com/mwitkow/go-proto-validators/protoc-gen-govalidators"
    _ "github.com/twitchtv/twirp/protoc-gen-twirp"
    _ "github.com/rynop/protoc-gen-twirp_typescript"   <<<< PROBLEM, using fork name
)

The error message you see seems to be the go command complaining about that.

I suspect it would work if you used the original name in the import statement:

import (
    ...
    _ "go.larrymyers.com/protoc-gen-twirp_typescript"   <<<< original name
)

You should also run go list -m all to see the final selected versions, including it shows the outcome of any replace and exclude directives.

thepudds
  • 4,787
  • 3
  • 20
  • 37
  • THANK YOU! I was so confused on why the readme seemed to state that the go dev team explicitly planned for this case. What a dumb error on my part. – rynop Aug 02 '19 at 02:15
-10

How to use a forked module [?]

You cannot. A Github fork produces a unrelated package, most likely not even buildable.

Don't fork, clone. Then push to a different remote (which can be a fork).

rynop
  • 50,086
  • 26
  • 101
  • 112
Volker
  • 40,468
  • 7
  • 81
  • 87
  • If I clone and push isn't that same as fork? Are you sure you cannot? https://github.com/golang/go/wiki/Modules#when-should-i-use-the-replace-directive seems to explicitly state my use case: "replace also allows the use of a forked dependency, such as..." – rynop Jun 20 '19 at 15:06
  • All depends on the Details. If you fork a project with single package that does not pin its import path and does not use reflection to get its import path then of course you can fork and use the fork without and Problem. A github fork creates a new Package and is a Bad idea. – Volker Jun 21 '19 at 09:54
  • 1
    I'm a golang noob, but I think your comments are true in the "old" non-versioned go module way (when all code is within `GOPATH`), which is covered in https://stackoverflow.com/questions/14323872/using-forked-package-import-in-go With new go module support (v1.11+) I'm pretty sure this pain-point has been addressed. – rynop Jun 25 '19 at 19:24
  • 1
    You are right. `replace` is only meant for local development, and have no effect outside of your own module (aka external tools like one in Q) . Details @ https://github.com/golang/go/issues/30354 – rynop Jun 25 '19 at 20:39