How does one do a relative import from a parent directory?
From meme/cmd/meme
:
import "../../../meme"
This gives an ambiguous error:
matt@stanley:~/gopath/src/bitbucket.org/anacrolix/meme/cmd/meme$ go get bitbucket.org/anacrolix/meme/cmd/meme
can't load package: /home/matt/gopath/src/bitbucket.org/anacrolix/meme/cmd/meme/main.go:8:2: local import "../../../meme" in non-local package
matt@stanley:~/gopath/src/bitbucket.org/anacrolix/meme/cmd/meme$ echo $GOPATH
/home/matt/gopath
How do I import locally from a parent directory?
Relarive imports are supported when manually using the compiler, linker, ... directly. The 'go' (build) tool doesn't support the same (somehow comparable to eg Java).
Thanks for adding to your question. First, an answer, then some explanation. I built your code by,
main.go
back to "../../../meme", as you wanted to do.go run main.go
orgo build main.go
worked.I was wrong in my comment earlier when I said go install works; I should have said go build.
The key however is that
go build
alone does not work; you must typego build main.go
. This is because the go command does not allow "local imports in non-local packages." You are right that spec is of little help here. It weasels out saying, "The interpretation of the ImportPath is implementation-dependent." The current implementation behavior was set with CL 5787055, which was subsequently debated at length on Go-nuts."Local" means indicated with a file system relative path. Obviously a relative path starting with .. is local, so the trick is just getting the
go
command to treat main as a local package as well. It apparently doesn't do this when you typego build
, but does when you typego build main.go
.Edit: Relative import paths are not the way to go in Go. Lack of documentation shows something about popularity of relative paths, and I don't see a reason for using them. Go's recommended code organization works pretty well. Every package should have a unique import path and be imported everywhere using that same import path.
See how a package like
github.com/ha/doozerd/peer
imports its neighbors. This is a common practice among Go projects and I've seen it a lot of times. Packagecamlistore.org/pkg/auth
(also on GitHub; written by one of the main authors of Go) importscamlistore.org/pkg/netutil
by full path.Even if you are having both commands and libraries in the same project this approach works. In your original questions you wisely asked for best practices. I did my best in explaining best practices on this matter.
Import paths can't be relative in Go.I recommend reading How to Write Go Code, the essential reading on organizing Go projects. Here's a short overview:Make a directory like
~/go
for your Go development. Then say:$GOPATH/src
holds source code for all your Go packages, even the ones your download withgo get
.bin
andpkg
keep output of compilations. Packages with package namemain
are commands and yield to executable binaries which go to$GOPATH/bin
. Other packages are libraries and their compiled object files are put in$GOPATH/pkg
.Now if you put your code in
$GOPATH/src/matt/meme
, you can import it byimport "matt/meme"
. It's recommended to use a prefix for your package names and leave short package names for standard libraries. That's why I used$GOPATH/src/matt/meme
instead of$GOPATH/src/meme
.Organize your code around this idea.