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: improve error when a package exists in the filesystem but is in a different module #30590

Open
firelizzard18 opened this Issue Mar 5, 2019 · 7 comments

Comments

Projects
None yet
5 participants
@firelizzard18
Copy link

firelizzard18 commented Mar 5, 2019

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

$ go version
go version go1.12 darwin/amd64

Does this issue reproduce with the latest release?

Yes (1.12)

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

go env Output
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/me/Library/Caches/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/me/Source/Go"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/Cellar/go/1.12/libexec"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.12/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/private/tmp/test/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/vy/7b8vfhcx2v7036h99kzs188h0000gn/T/go-build129924831=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

$ tree
.
├── a
│   ├── go.mod
│   └── somefile.go
├── somefile.go
└── go.mod
$ cat go.mod
module path/should/not/matter
$ cat a/go.mod
module path/should/not/matter/a
go build ./a
(cd ./a && go build)

What did you expect to see?

I expect go build ./a from the project root and go build from the submodule a to behave the same.

What did you see instead?

Adding a/go.mod causes go build ./a and cd ./a; go build to behave differently.

$ go build ./a && echo success
can't load package: package path/should/not/matter/a: unknown import path "path/should/not/matter/a": cannot find module providing package path/should/not/matter/a
$ (cd ./a && go build && echo success)
success
@firelizzard18

This comment has been minimized.

Copy link
Author

firelizzard18 commented Mar 5, 2019

It appears that go build ./sub/path does not build what's on disk, if ./sub/path/go.mod exists, but instead determines what the import path of ./sub/path is and downloads and builds that. This is extremely counterintuitive and problematic.

@nim-nim

This comment has been minimized.

Copy link

nim-nim commented Mar 5, 2019

Each module starts at the directory containing its go.mod file, and contains all packages from that directory and its subdirectories recursively, excluding any subtree that contains another go.mod file.

FAQ

So by creating nested modules, you exclude the resulting files from the main module scope.

@mvdan

This comment has been minimized.

Copy link
Member

mvdan commented Mar 5, 2019

Basically what @nim-nim said. Perhaps the docs should be clearer about "nested modules" not being a supported feature. I seem to remember earlier threads about this, but can't find them now. /cc @bcmills @myitcv @thepudds

@bcmills

This comment has been minimized.

Copy link
Member

bcmills commented Mar 5, 2019

We should fix the error message, at least. Pretty sure this is a duplicate.

@bcmills

This comment has been minimized.

Copy link
Member

bcmills commented Mar 5, 2019

#27957 is related, but doesn't mention fixing the error message explicitly.

@bcmills bcmills changed the title cmd/go: unexpected behavior when building nested modules cmd/go: improve error when a package exists in the filesystem but is in a different module Mar 5, 2019

@bcmills bcmills added the NeedsFix label Mar 5, 2019

@bcmills bcmills added this to the Go1.13 milestone Mar 5, 2019

@bcmills

This comment has been minimized.

Copy link
Member

bcmills commented Mar 5, 2019

@bcmills bcmills added the modules label Mar 5, 2019

@jayconrod jayconrod self-assigned this Mar 5, 2019

@firelizzard18

This comment has been minimized.

Copy link
Author

firelizzard18 commented Mar 7, 2019

I fully understand that "nested modules" are excluded from the "parent module". I have no issue with that. The issues I do have are:

  • Running go build on a relative path, when that path is its own module, does not build the code at that path but instead downloads the module and builds that.
  • Running go build on a relative path and running go build after changing directory to that path have different results.

So by creating nested modules, you exclude the resulting files from the main module scope.

Sure, fine, that's reasonable and makes sense. But go build ./a seems to be doing this:

  1. Look for go.mod at the specified path
  2. Read the module name/id from go.mod
  3. Instead of building the module at the specified path, download the module to some location (the cache?) and build that.

I don't understand the logic behind that last step. When I run go build <path> on a path that is prefixed with ./, I expect it to build from my local workspace. go is interpreting go build ./a as go build path/should/not/matter/a, which is entirely unexpected and unwelcome.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.