THIS IS NO LONGER NESSESARY
go finally supports modules natively
ugo is an extremly simple and obvious solution to all your GOPATH troubles.
If the official way of working with go is somehow troubling you, this is the one workaround you need.
tested with | works |
---|---|
go1.7.4 linux/amd64 | yep |
go1.8.3 linux/amd64 | yep |
Please open a github issue to report if it works on your platform (windows is not supported)
simply add a file ".gopackage" to your package root, containing the full path of your package
$ git clone github.com/foo/bar && cd something
$ go get
error: you have angered the GOPATH god
$ echo 'github.com/foo/bar' > .gopackage
$ ugo go get
$ ugo go build
# just bloody works
- A workaround for the underlying design mistake in go, not a vendoring tool (see background)
- So trivial that many other tools can be implemented on this
- Foward and backward compatible with the official way of working.
- A Trivial single file with zero overhead to the project that all projects can adopt painfree
This repo contains ugo, that creates a workspace in the project root of whatever you're building.
It's quite simplistic and many more tools can be built using the obvious package fix (read below). If you implement something else that uses .gopackage, let me know and i'll link from here
go get -u github.com/aep/ugo
"ugo anything" will create the virtual workspace, add it to your existing gopath and then exec "anything"
This also works with other tools need to know the import path, such as generators or parsers, for example to use ginkgo generate just prefix it with "ugo"
$ ginkgo generate
Couldn't identify package import path.
$ ugo ginkgo generate
#works fine
You can also pass -r to this script to not add but replace the workspace, which works exactly the same way, except that all dependencies are redownloaded for every project. I'd recommend using vendoring instead. -r also serves as a workaround for broken tools that only accept a single path in GOPATH
GOPATH has many issues, such as crippling any workflow with private repos, mixed go and non-go code, git submodules, or global dependencies generally being a terrible idea. Probably a million more. There's workarounds for every issue GOPATH brings, but the puzzling part for me was: why does GOPATH even exist, when no other language has it?
Here's an attempt to explain the situation:
let's assume this is your project:
$ git clone github.com/company/server/
$ tree server
server
├── router
│ └── router.go
└── cmd
└── main.go
your router.go:
package router
and your main.go imports the router sub package
package main
import "github.com/company/server/router"
since package names must be short, and import names must be full urls there is no way go build could figure out these two things are related. Unless we're complying with the law :
$ cd $GOPATH
$ git clone github.com/company/server/ src/github.com/company/server/
$ tree
src
└── github.com
└── company
└── server
├── router
| └── router.go
└── cmd
└── main.go
now the go tools understand what "import github.com/company/server/router" means, because that is a valid path relative to GOPATH
I'm unsure wether this is the reason gopath exists, but it is the only time it's actually needed for any of the go tools.
ugo fakes that layout inside a symlink, so the go tools know where to find stuff, without you having to bother about all the other problems that come with gopath
$ git clone github.com/company/server/
$ cd server && ugo *anything*
$ tree server
server
├── .gopackage
├── router
│ └── router.go
├── cmd
│ └── main.go
└── .workspace
└── src
└── github.com
└── company
└── ...
In theory, go tools could just read .gopackage directly or use full names in the package directive, and do away with GOPATH. Until then, this workaround hopefully enable a saner workflow for everyone.