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: poor error message when resolving an import path that is missing from the main module #38224

Open
firelizzard18 opened this issue Apr 2, 2020 · 5 comments
Labels
modules NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@firelizzard18
Copy link
Contributor

firelizzard18 commented Apr 2, 2020

What version of Go are you using (go version)?

$ go version
go version go1.14 windows/amd64

Does this issue reproduce with the latest release?

Yes, as of 1.14

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
set GO111MODULE=
set GOARCH=amd64
set GOBIN=
set GOCACHE=REDACTED
set GOENV=REDACTED
set GOEXE=.exe
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=REDACTED
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=c:\go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=c:\go\pkg\tool\windows_amd64
set GCCGO=gccgo
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=REDACTED
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=REDACTED=/tmp/go-build -gno-record-gcc-switches

What did you do?

Given a module example.com/repo defined in ./go.mod, if directory ./a does not contain any Go files and a package ./a/b contains import "example.com/repo/a", go build ./a/b will attempt to fetch example.com/repo/a even though ./a is clearly within a module.

Reproduced here: https://github.com/firelizzard18/golang-issue-38224

What did you expect to see?

$ go build ./a/b
./a is not a package (it contains no .go files)

What did you see instead?

$ go build ./a/b
go: finding module for package github.com/firelizzard18/golang-issue/a
a\b\b.go:4:2: no matching versions for query "latest"
go build -c -v ./a/b Output
$ go build -x -v ./a/b
WORK=REDACTED\go-build863876662
go: finding module for package github.com/firelizzard18/golang-issue/a
# get https://proxy.golang.org/github.com/@v/list
# get https://proxy.golang.org/github.com/firelizzard18/@v/list
# get https://proxy.golang.org/github.com/firelizzard18/golang-issue/a/@v/list
# get https://proxy.golang.org/github.com/@v/list: 410 Gone (0.136s)
# get https://proxy.golang.org/github.com/firelizzard18/@v/list: 410 Gone (0.244s)
# get https://proxy.golang.org/github.com/firelizzard18/golang-issue/a/@v/list: 410 Gone (0.250s)
# get https://github.com/?go-get=1
mkdir -p REDACTED_GOPATH\pkg\mod\cache\vcs # git3 https://github.com/firelizzard18/golang-issue
# lock REDACTED_GOPATH\pkg\mod\cache\vcs\e2313c495adbffd1d40784db88daaf99dcbe9402845107a75ca579ef28ad5de6.lock# REDACTED_GOPATH\pkg\mod\cache\vcs\e2313c495adbffd1d40784db88daaf99dcbe9402845107a75ca579ef28ad5de6 for git3 https://github.com/firelizzard18/golang-issue
cd REDACTED_GOPATH\pkg\mod\cache\vcs\e2313c495adbffd1d40784db88daaf99dcbe9402845107a75ca579ef28ad5de6; git ls-remote -q origin
# get https://github.com/?go-get=1: 200 OK (0.249s)
0.541s # cd REDACTED_GOPATH\pkg\mod\cache\vcs\e2313c495adbffd1d40784db88daaf99dcbe9402845107a75ca579ef28ad5de6; git ls-remote -q origin
cd REDACTED_GOPATH\pkg\mod\cache\vcs\e2313c495adbffd1d40784db88daaf99dcbe9402845107a75ca579ef28ad5de6; git -c log.showsignature=false log -n1 '--format=format:%H %ct %D' aae63bbecdc4e4b7f7eb0bde21b827dbb2e3fe49 --
0.038s # cd REDACTED_GOPATH\pkg\mod\cache\vcs\e2313c495adbffd1d40784db88daaf99dcbe9402845107a75ca579ef28ad5de6; git -c log.showsignature=false log -n1 '--format=format:%H %ct %D' aae63bbecdc4e4b7f7eb0bde21b827dbb2e3fe49 --
cd REDACTED_GOPATH\pkg\mod\cache\vcs\e2313c495adbffd1d40784db88daaf99dcbe9402845107a75ca579ef28ad5de6; git for-each-ref --format %(refname) refs/tags --merged aae63bbecdc4e4b7f7eb0bde21b827dbb2e3fe49
0.038s # cd REDACTED_GOPATH\pkg\mod\cache\vcs\e2313c495adbffd1d40784db88daaf99dcbe9402845107a75ca579ef28ad5de6; git for-each-ref --format %(refname) refs/tags --merged aae63bbecdc4e4b7f7eb0bde21b827dbb2e3fe49
cd REDACTED_GOPATH\pkg\mod\cache\vcs\e2313c495adbffd1d40784db88daaf99dcbe9402845107a75ca579ef28ad5de6; git for-each-ref --format %(refname) refs/tags --merged aae63bbecdc4e4b7f7eb0bde21b827dbb2e3fe49
0.037s # cd REDACTED_GOPATH\pkg\mod\cache\vcs\e2313c495adbffd1d40784db88daaf99dcbe9402845107a75ca579ef28ad5de6; git for-each-ref --format %(refname) refs/tags --merged aae63bbecdc4e4b7f7eb0bde21b827dbb2e3fe49
cd REDACTED_GOPATH\pkg\mod\cache\vcs\e2313c495adbffd1d40784db88daaf99dcbe9402845107a75ca579ef28ad5de6; git -c log.showsignature=false log -n1 '--format=format:%H %ct %D' aae63bbecdc4 --
0.038s # cd REDACTED_GOPATH\pkg\mod\cache\vcs\e2313c495adbffd1d40784db88daaf99dcbe9402845107a75ca579ef28ad5de6; git -c log.showsignature=false log -n1 '--format=format:%H %ct %D' aae63bbecdc4 --
cd REDACTED_GOPATH\pkg\mod\cache\vcs\e2313c495adbffd1d40784db88daaf99dcbe9402845107a75ca579ef28ad5de6; git cat-file blob aae63bbecdc4e4b7f7eb0bde21b827dbb2e3fe49:a/go.mod
0.037s # cd REDACTED_GOPATH\pkg\mod\cache\vcs\e2313c495adbffd1d40784db88daaf99dcbe9402845107a75ca579ef28ad5de6; git cat-file blob aae63bbecdc4e4b7f7eb0bde21b827dbb2e3fe49:a/go.mod
a\b\b.go:4:2: no matching versions for query "latest"
@firelizzard18
Copy link
Contributor Author

When I try this in GOPATH mode, I get:

a\b\b.go:3:8: cannot find package "github.com/firelizzard18/golang-issue/a" in any of:
        c:\go\src\github.com\firelizzard18\golang-issue\a (from $GOROOT)
        REDACTED\src\github.com\firelizzard18\golang-issue\a (from $GOPATH)

@jayconrod
Copy link
Contributor

The mechanism here is working as intended, but the diagnostic message should be better.

If you have modules example.com/a and example.com/a/b (the first is a prefix of the second), either module could provide the package example.com/a/b/c. If you import example.com/a/b/c, and that package is not in example.com/a/b, the go command needs to check if example.com/a exists and provides this package.

It's best to avoid interleaving modules like this, but the situation can come up when splitting a large module into smaller pieces, so it's important that the mechanism keeps working.

That said, when the go command doesn't find a package in another module, it should just print that the package is missing without mentioning other modules, since that's what's most likely wrong.

@jayconrod jayconrod added the NeedsFix The path to resolution is known, but the work has not been done. label Apr 3, 2020
@jayconrod jayconrod added this to the Backlog milestone Apr 3, 2020
@firelizzard18
Copy link
Contributor Author

In my particular case, the module I'm working on is not currently accessible, so the fetch fails. Because my IDE (VSCode) uses gopls to update imports on save, this considerably delays saves.

When I build, I get:

go: finding module for package example.com/my/project/pkg1
pkg1\pkg2\file.go:23:2: module example.com/my/project/pkg1: git ls-remote -q origin in GOPATH\pkg\mod\cache\vcs\HASH: exit status 128:
        fatal: could not read Username for 'https://example.com': terminal prompts disabled
Confirm the import path was entered correctly.
If this is a private repository, see https://golang.org/doc/faq#git_https for additional information.

@bcmills
Copy link
Contributor

bcmills commented Apr 3, 2020

Here's the behavior I see, with a current 1.15 development version of cmd/go:

$ go version
go version devel +a9a78b70 Fri Apr 3 05:33:35 2020 +0000 linux/amd64

$ git clone https://github.com/firelizzard18/golang-issue-38224
Cloning into 'golang-issue-38224'...
remote: Enumerating objects: 15, done.
remote: Counting objects: 100% (15/15), done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 15 (delta 1), reused 15 (delta 1), pack-reused 0
Receiving objects: 100% (15/15), done.
Resolving deltas: 100% (1/1), done.

$ cd golang-issue-38224/

golang-issue-38224$ go build ./a/b
go: finding module for package github.com/firelizzard18/golang-issue/a
a/b/b.go:3:8: no matching versions for query "latest"

golang-issue-38224$ go mod tidy
go: finding module for package github.com/firelizzard18/golang-issue/a
github.com/firelizzard18/golang-issue/a/b imports
        github.com/firelizzard18/golang-issue/a: no matching versions for query "latest"

@bcmills
Copy link
Contributor

bcmills commented Apr 3, 2020

That second error message is closer, but still not right: we should probably be returning a PackageNotInModuleError here instead . It has special logic for the main module:

if e.Mod == Target {
if strings.Contains(e.Pattern, "...") {
return fmt.Sprintf("main module (%s) does not contain packages matching %s", Target.Path, e.Pattern)
}
return fmt.Sprintf("main module (%s) does not contain package %s", Target.Path, e.Pattern)
}

But for some reason we're explicitly overriding that error message with what seems to be a much worse one:

// Return "cannot find module providing package […]" instead of whatever
// low-level error QueryPackage produced.

@bcmills bcmills changed the title cmd/go: go build fetches inappropriately in module mode when a path within the module is not a package cmd/go: poor error message when resolving an import path that is missing from the main module Apr 8, 2020
@bcmills bcmills added the modules label Apr 8, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
modules NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

3 participants