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: behavior when using relative dirs for package names is underspecified #14609

Closed
cespare opened this issue Mar 3, 2016 · 4 comments
Closed

Comments

@cespare
Copy link
Contributor

cespare commented Mar 3, 2016

This is using Go 1.6, but I don't think the behavior has changed recently.

go build (and probably other go commands) normally take Go package names (that is, relative to some GOPATH component) but, as special cases, also take relative and absolute directories.

go help packages says this:

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.

However, this does not fully describe the go tool's behavior when given relative paths such as . or ./hello. I haven't looked into the code, but it seems like the tool tries to resolve such paths relative to GOPATH and does different things depending on what it finds.

Here are two examples.

First, there is a very different error given depending on whether the given path is inside a GOPATH or not:

$ pwd
/tmp/build
$ ls
$ mkdir -p a/src b/src
$ cd a/src/
$ GOPATH=/asdf go build ./hello
can't load package: package ./hello: open /tmp/build/a/src/hello: no such file or directory
$ GOPATH=/tmp/build/a go build ./hello                                                                                                                                                                                              
can't load package: package hello: cannot find package "hello" in any of:
        /home/caleb/apps/go/src/hello (from $GOROOT)
        /tmp/build/a/src/hello (from $GOPATH)

There are actual behavior differences as well, though. For instance, you can build a package given a non-existent relative path if the resolved package name does exist in some other GOPATH component (or GOROOT, for that matter):

$ # continuing from above...
$ cd /tmp/build/b/src/
$ mkdir hello
$ cat > hello/hello.go
package main
func main() { println("hello") }
$ cd /tmp/build/a/src/
$ ls
$ GOPATH=/asdf go build ./hello
can't load package: package ./hello: open /tmp/build/a/src/hello: no such file or directory
$ GOPATH=/tmp/build/a:/tmp/build/b go build ./hello
$ ./hello
hello

That seems to directly contradict "interpreted as a file system path" in the go help packages output.

@minux
Copy link
Member

minux commented Mar 3, 2016 via email

@cespare
Copy link
Contributor Author

cespare commented Mar 3, 2016

The relative import is really only for testing purposes

I'm only talking about arguments to e.g. go build, not relative imports in my Go source code.

Personally, I use this feature all the time. If my cwd is $GOPATH/src/github.com/cespare/foo, I am much more likely to type

go build ./bar
go test ./bar

than

go build github.com/cespare/foo/bar
go test github.com/cespare/foo/bar

and only works as intended (relative to cwd) when used out of GOPATH.

What does this mean, and where is it documented?

@rsc
Copy link
Contributor

rsc commented May 17, 2016

I think the docs are fairly clear. The second example in the original report is a bug (#12385).

@cespare
Copy link
Contributor Author

cespare commented May 17, 2016

Thanks Russ. I'm happy to close this as a duplicate of #12385.

@cespare cespare closed this as completed May 17, 2016
@golang golang locked and limited conversation to collaborators May 17, 2017
@rsc rsc removed their assignment Jun 23, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants