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: module go install cmd with relative import path resolved against $GOPATH #35918

Closed
ghost opened this issue Dec 1, 2019 · 6 comments
Closed
Labels
FrozenDueToAge modules NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.

Comments

@ghost
Copy link

ghost commented Dec 1, 2019

go1.13.4

Does this issue reproduce with the latest release?

yes

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

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/user2/Library/Caches/go-build"
GOENV="/Users/user2/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/user2/A/AL3/code/laboratory"
GOPRIVATE=""
GOPROXY="direct"
GOROOT="/usr/local/go"
GOSUMDB="off"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
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/8v/vpckwgfs4_547sb94qr9f4d40000gq/T/go-build933483445=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

NOTE: This is documented in github.com/Conformable/gotests/experiments/e003, e003b and e003c. The tests have re-runnable bash scripts and store the input and output of go install.
All of the tests are contained in a .zip for reuse.

go install github.com/githubuserid/reponame/pkgname

Am testing go install with all permutations: local-disk/remote vcs, internet on/off, GOPROXY on/off, etc. etc.

The current test is with internet off and just local disk source code within the $GOPATH.

If a package name is specified on the go install command line which is a relative path, relative to $GOPATH, then the install works successfully without accessing github.com -- BUT it is apparently treated as a non-module install. The go.mod file is not updated.

On the other hand, if go install is performed inside the package's directory like so, "go install", then Go does not resolve the imported package's path against $GOPATH -- this behavior matches the "go help gopath" documentation -- and it tries to access github.com using the internet.

What did you expect to see?

I expected the go install which used a relative import path to fail.

What did you see instead?

But it worked, though it did not recognize that the package had a go.mod file (apparently) and did not update it.

@dmitshur dmitshur changed the title module go install cmd with relative import path resolved against $GOPATH cmd/go: module go install cmd with relative import path resolved against $GOPATH Dec 2, 2019
@dmitshur dmitshur added modules NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Dec 2, 2019
@dmitshur
Copy link
Contributor

dmitshur commented Dec 2, 2019

/cc @jayconrod @bcmills

@jayconrod
Copy link
Contributor

I think this is working as intended.

The go command will look for a go.mod file in the current directory or a parent directory (regardless of command line arguments). If one is found, that defines "main module", and it's the only go.mod file that may be updated. If GO111MODULE is auto or is not set, this also determines whether module aware mode is enabled.

Relative paths are described in go help packages. A relative or absolute path is interpreted as a directory, not a package name. The go command may go out to the network to download modules to satisfy imports in that directory or to fill in anything missing from the cache. It won't look $GOPATH/src in module aware mode though.

@ghost
Copy link
Author

ghost commented Dec 3, 2019

Well...that is curious. The package did have a go.mod file, and it was ignored. The entire go install process ignored the go.mod files -- but simply changing the install command to be inside the directory triggered module=on behavior. So two different forms of the "go install" command cause different results: one ignores the go.mod files and does a local disk compile and the other recognizes the modules and goes out to github.com to resolve the imports, etc.

And look at "go help gopath":

"GOPATH and Modules

When using modules, GOPATH is no longer used for resolving imports.
However, it is still used to store downloaded source code (in GOPATH/pkg/mod)
and compiled commands (in GOPATH/bin)."

So if Go had been using modules it would have ignored the gopath/src and gone out to github to get the imports. I have tested this and that is the way it works.

If you think it works as intended, then that is fine with me. It just doesn't seem to match the documentation.

@ghost
Copy link
Author

ghost commented Dec 3, 2019

From "go help packages"

An import path that is a rooted path or that begins with a . or .. element is interpreted as a file system path and denotes the package in that directory.

Otherwise, the import path P denotes the package found in the directory DIR/src/P for some DIR listed in the GOPATH environment variable (For more details see: 'go help gopath').


I think that is pretty clear: it "denotes the package found in that directory". And in my case, that package had a go.mod file. Which was ignored. To take the alternative reading of the documentation would be to say: 'Fire up the command line and enter "go install github.com/userid/repo/pkgname" and if the user's home directory has a go.mod file that is what will be input to go install.' Would that be reasonable behavior?

@jayconrod
Copy link
Contributor

go help modules has more information on this:

Go 1.13 includes support for Go modules. Module-aware mode is active by default whenever a go.mod file is found in, or in a parent of, the current directory.

The quickest way to take advantage of module support is to check out your repository, create a go.mod file (described in the next section) there, and run go commands from within that file tree.

For more fine-grained control, Go 1.13 continues to respect a temporary environment variable, GO111MODULE, which can be set to one of three string values: off, on, or auto (the default). If GO111MODULE=on, then the go command requires the use of modules, never consulting GOPATH. We refer to this as the command being module-aware or running in "module-aware mode". If GO111MODULE=off, then the go command never uses module support. Instead it looks in vendor directories and GOPATH to find dependencies; we now refer to this as "GOPATH mode." If GO111MODULE=auto or is unset, then the go command enables or disables module support based on the current directory. Module support is enabled only when the current directory contains a go.mod file or is below a directory containing a go.mod file.

In module-aware mode, GOPATH no longer defines the meaning of imports during a build, but it still stores downloaded dependencies (in GOPATH/pkg/mod) and installed commands (in GOPATH/bin, unless GOBIN is set).

@ghost
Copy link
Author

ghost commented Dec 3, 2019

OK, thank you for explaining that.

@golang golang locked and limited conversation to collaborators Dec 2, 2020
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

3 participants