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

cmd/go: go mod tidy does not fail when ambiguous import path found #28685

Closed
jeanbza opened this issue Nov 9, 2018 · 4 comments
Closed

cmd/go: go mod tidy does not fail when ambiguous import path found #28685

jeanbza opened this issue Nov 9, 2018 · 4 comments
Labels
FrozenDueToAge modules NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@jeanbza
Copy link
Member

jeanbza commented Nov 9, 2018

I perform the following steps:

- add /go.mod
- add /pkg_a/foo.go
- add /pkg_b/bar.go
- commit
- tag v0.0.1 # should be unrelated, AFAICT
- push commit + tag

- add /pkg_b/go.mod
- commit
- tag pkg_b/v0.0.1
- push commit + tag

- make pkg_a/foo.go depend on pkg_b/bar.go
- cd pkg_a && go mod tidy
== nothing

- add "require pkg_b v0.0.1" to /pkg_a/go.mod
- cd pkg_a && go mod tidy
== removes require statement in /pkg_a/go.mod

Why does go mod think that pkg_a does not need a require statement for pkg_b?

@odeke-em
Copy link
Member

odeke-em commented Nov 9, 2018

Thank you for reporting this issue and great to catch you here @jadekler!
Let me tag some experts for help, @myitcv @rsc

@odeke-em odeke-em added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Nov 9, 2018
@myitcv
Copy link
Member

myitcv commented Nov 9, 2018

@jadekler I don't see anything wrong with the above, indeed a quick repro works just fine (results):

$ cd $(mktemp -d)
$ git init -q
$ git remote add origin https://github.com/go-modules-by-example-staging/20181109100134_jadekler
$ go mod init
go: creating new go.mod: module github.com/go-modules-by-example-staging/20181109100134_jadekler
$ mkdir pkg_a pkg_b
$ cat <<EOD >pkg_a/foo.go
package pkg_a

const Name = "pkg_a"
EOD
$ cat <<EOD >pkg_b/bar.go
package pkg_b

const Name = "pkg_b"
EOD
$ git add -A
$ git commit -q -am 'Initial commit of a and b'
$ git push -q
remote:
remote: Create a pull request for 'master' on GitHub by visiting:
remote:      https://github.com/go-modules-by-example-staging/20181109100134_jadekler/pull/new/master
remote:
$ git tag v0.0.1
$ git push origin v0.0.1
To https://github.com/go-modules-by-example-staging/20181109100134_jadekler
 * [new tag]         v0.0.1 -> v0.0.1

# Make pkg_b a submodule

$ cd pkg_b
$ go mod init github.com/go-modules-by-example-staging/20181109100134_jadekler/pkg_b
go: creating new go.mod: module github.com/go-modules-by-example-staging/20181109100134_jadekler/pkg_b
$ cd ..
$ git add -A
$ git commit -q -am 'Make b a submodule'
$ git push
To https://github.com/go-modules-by-example-staging/20181109100134_jadekler
   70c6b1f..995050c  master -> master
$ git tag pkg_b/v0.0.1
$ git push origin pkg_b/v0.0.1
To https://github.com/go-modules-by-example-staging/20181109100134_jadekler
 * [new tag]         pkg_b/v0.0.1 -> pkg_b/v0.0.1

# Make pkg_a depend on pkg_b

$ cat <<EOD >pkg_a/foo.go
package pkg_a

import "github.com/go-modules-by-example-staging/20181109100134_jadekler/pkg_b"

const Name = "pkg_a"
const OtherName = pkg_b.Name
EOD
$ go mod tidy
go: finding github.com/go-modules-by-example-staging/20181109100134_jadekler/pkg_b v0.0.1
go: downloading github.com/go-modules-by-example-staging/20181109100134_jadekler/pkg_b v0.0.1
$ cat go.mod
module github.com/go-modules-by-example-staging/20181109100134_jadekler

require github.com/go-modules-by-example-staging/20181109100134_jadekler/pkg_b v0.0.1
$ go test github.com/go-modules-by-example-staging/20181109100134_jadekler/pkg_a
?       github.com/go-modules-by-example-staging/20181109100134_jadekler/pkg_a  [no test files]

I wonder however, if instead of:

- make pkg_a/foo.go depend on pkg_b/bar.go

you actually meant to add the reverse dependency, i.e.:

- make pkg_b/bar.go depend on pkg_a/foo.go

Because if so, that will have caused a problem. Reason being, when the go tool tries to resolve pkg_a from within the submodule pkg_b, it only finds v0.0.1 or the parent module. And that version contains pkg_b as a package in the main module, and not as a submodule (which happened afterwards). go mod tidy should I think fail in this situation, just as go test does (results):

# ...

# Make pkg_b depend on pkg_a

$ cd pkg_b
$ cat <<EOD >bar.go
package pkg_b

import "github.com/go-modules-by-example-staging/20181109100151_jadekler_reverse/pkg_a"

const Name = "pkg_b"
const OtherName = pkg_a.Name
EOD
$ go mod tidy
go: finding github.com/go-modules-by-example-staging/20181109100151_jadekler_reverse/pkg_a latest
go: finding github.com/go-modules-by-example-staging/20181109100151_jadekler_reverse v0.0.1
go: downloading github.com/go-modules-by-example-staging/20181109100151_jadekler_reverse v0.0.1
$ cat go.mod
module github.com/go-modules-by-example-staging/20181109100151_jadekler_reverse/pkg_b
$ go test github.com/go-modules-by-example-staging/20181109100151_jadekler_reverse/pkg_b
go: finding github.com/go-modules-by-example-staging/20181109100151_jadekler_reverse/pkg_a latest
can't load package: package github.com/go-modules-by-example-staging/20181109100151_jadekler_reverse/pkg_b: unknown import path "github.com/go-modules-by-example-staging/20181109100151_jadekler_reverse/pkg_b": ambiguous import: found github.com/go-modules-by-example-staging/20181109100151_jadekler_reverse/pkg_b in multiple modules:
        github.com/go-modules-by-example-staging/20181109100151_jadekler_reverse/pkg_b (/tmp/tmp.ii4Gp8vqRa/pkg_b)
        github.com/go-modules-by-example-staging/20181109100151_jadekler_reverse v0.0.1 (/home/gopher/pkg/mod/github.com/go-modules-by-example-staging/20181109100151_jadekler_reverse@v0.0.1/pkg_b)

The way to fix this is to either tag a new version of the main module at the same commit where the pkg_b submodule is created, or to add a replace statement in pkg_b's go.mod to the parent directory. Here is the replace option (results):

# ...

# Make pkg_b depend on pkg_a

$ cd pkg_b
$ cat <<EOD >bar.go
package pkg_b

import "github.com/go-modules-by-example-staging/20181109100214_jadekler_replace/pkg_a"

const Name = "pkg_b"
const OtherName = pkg_a.Name
EOD

# Use a replace statement

$ go mod edit -replace=github.com/go-modules-by-example-staging/20181109100214_jadekler_replace=../
$ cat go.mod
module github.com/go-modules-by-example-staging/20181109100214_jadekler_replace/pkg_b

replace github.com/go-modules-by-example-staging/20181109100214_jadekler_replace => ../
$ go mod tidy
go: finding github.com/go-modules-by-example-staging/20181109100214_jadekler_replace/pkg_a latest
go: finding github.com/go-modules-by-example-staging/20181109100214_jadekler_replace v0.0.1
$ cat go.mod
module github.com/go-modules-by-example-staging/20181109100214_jadekler_replace/pkg_b

replace github.com/go-modules-by-example-staging/20181109100214_jadekler_replace => ../

require github.com/go-modules-by-example-staging/20181109100214_jadekler_replace v0.0.1
$ go test github.com/go-modules-by-example-staging/20181109100214_jadekler_replace/pkg_b
?       github.com/go-modules-by-example-staging/20181109100214_jadekler_replace/pkg_b  [no test files]

cc @rsc @bcmills for any opinions on whether go mod tidy should be failing in this situation.

@myitcv myitcv changed the title cmd/go: go mod tidy removes necessary inter-repository dependencies cmd/go: go mod tidy does not fail when ambiguous import path found Nov 9, 2018
@myitcv myitcv added the modules label Nov 9, 2018
@ianlancetaylor ianlancetaylor added this to the Go1.12 milestone Nov 9, 2018
@jeanbza
Copy link
Member Author

jeanbza commented Nov 9, 2018

AH. Sorry, this is my mistake. I'm using intellij, and it seems my auto-import pulled in some other, similarly-named-but-not-correct-path variable. Sorry again, user error.

Although my question is solved (thanks again @myitcv), I'll leave this open for y'all to close at your discretion if you want to discuss the question posed at the end of @myitcv post.

@bcmills
Copy link
Contributor

bcmills commented Nov 9, 2018

If I understand correctly, this is a duplicate of #27063.

@bcmills bcmills closed this as completed Nov 9, 2018
@golang golang locked and limited conversation to collaborators Nov 9, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge modules NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

6 participants