How can I force go mod to accept a module that declares its path being different from its go.mod?
Asked Answered
P

3

9

When I run go mod tidy, it breaks because a package imported by my project imports another package using path github.com/coreos/bbolt, but when it fetches the package from this path its go.mod says its path is go.etcd.io/bbolt.

The problem is that both the importing package and the imported package are 3rd party packages. I know I could edit the go module cache to fix it, but it would be a real hell fixing it when new versions of these packages become available.

Partial echoed messages are shown below:

    github.com/coreos/etcd/client tested by
    github.com/coreos/etcd/client.test imports
    github.com/coreos/etcd/integration imports
    github.com/coreos/etcd/etcdserver imports
    github.com/coreos/etcd/mvcc/backend imports
    github.com/coreos/bbolt: github.com/coreos/[email protected]: parsing go.mod:
    module declares its path as: go.etcd.io/bbolt
            but was required as: github.com/coreos/bbolt

So, how can I fix or work around this situation?

Phonic answered 25/3, 2021 at 5:23 Comment(0)
D
8

You can fix this solution by using the replace directive

Simply add:

replace github.com/coreos/bbolt v1.3.5 => go.etcd.io/bbolt v1.3.5

at the end of your go.mod file

Doriedorin answered 25/3, 2021 at 5:33 Comment(2)
If that works, it's arguably a bug in the go command — and one that I'm likely to fix as part of golang.org/issue/26904, which will address this sort of “renamed module” use-case more directly. 😅Burlington
a) You're right. The problem was that I was suspicious whether this was a temporary change of bbolt or not, and didn't want to change the codebase for that. For a solid fix, changing the import paths is a better solution b) I too am a long time follower of #26904, since you are the maintainer: good luck and thanksDoriedorin
B
3

The mismatched path implies that your dependency (github.com/coreos/etcd/mvcc/backend) is written against an old version of the bbolt repository — one that predates commit e65d4d.


I notice that the current go.mod file in the github.com/etcd-io/etcd repo specifies its module path as go.etcd.io/etcd/v3.

So the most robust fix for you is probably to update to that path, which you can do by changing your import statements to refer to the new canonical import path and running go mod tidy to update your dependencies accordingly:

sed -i s,github.com/coreos/etcd,go.etcd.io/etcd/v3,g $(find . -name '*.go')
go mod tidy

Barring that, you could explicitly choose a version of github.com/coreos/bbolt that matches the older import path. I notice that the highest version for that module listed at https://beta.pkg.go.dev/github.com/etcd-io/bbolt?tab=versions is v1.3.3, and v1.3.4 does seem to add a go.mod file with the updated path. So as a fallback, you could try:

go get -d github.com/coreos/[email protected]

The downside to that approach is that v1.3.3 is the end of the line: you wouldn't be able to pull in bug-fixes after that point, because those fixes are all at the go.etcd.io path.

Burlington answered 29/6, 2021 at 3:49 Comment(1)
An aside: bbolt adding a go.mod file in a patch release is not a great choice as far as semantic versioning goes — adding a go.mod file is arguably “add[ing] functionality”, not a “backwards compatible bug [fix]”. But that's not a problem you or they can feasibly address at this point. 😅Burlington
F
0

You could also use the replace directive with the command line, as example:

go mod edit -replace github.com/pselle/bar=/Users/pselle/Projects/bar

More info in this article

Funambulist answered 25/3, 2021 at 8:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.