Finally. This is going to make it easier for newcomers to the Go ecosystem, since commands such as "go get" will now work out of the box.
Finally. This is going to make it easier for newcomers to the Go ecosystem, since commands such as "go get" will now work out of the box.
Go has a list of locations to look for projects (packages) in ($GOPATH) and by default does not include the working directory. Unlike Python's sys.path, $GOPATH normally only contains a single value.
Python's behavior is similar to $PATH on Windows while Go's behavior is similar to $PATH on Unix.
There are pros and cons to each default value but either language can be overridden to have the other's behavior if you desire.
I personally quite like having a single unified $GOPATH for all of my source.
How? With Python I can release a package with code like `import foo from .` in it. This will not work in Go, a GOPATH package must import things from subdirectories via GOPATH. At least, this was the case the last time I checked.
https://github.com/golang/go/issues/14566
There are many problems with running outside GOPATH. Among others, there's no
caching of built object files, so everything is much slower than it should be
(go build, go test, and so on). Vendoring is pretty low on the list of problems.
It may be that GOPATH should be reconsidered but if so it should be done as a
whole change, not just one piece at a time, like @bradfitz said above.
The solution for now is to use GOPATH.
> rsc closed this on 6 Dec 2016
Once the new dependency tool is done, it seems like GOPATH will be increasingly irrelevant with vendored dependencies and proper tooling.(You may also be interested in this extended and active discussion on getting rid of GOPATH; https://github.com/golang/go/issues/17271)
I appreciate the correction!
This used to work okay-ish until Go 1.5. Then Go 1.6 introduced vendoring support (i.e. you put the code for the libraries you need into your own repo) which is very nice if it works, so I wanted to have it. But `go build` stubbornly refuses to look at vendored code when you are not in the exact correct location inside the GOPATH.
To preserve the familiar build semantics, I set up the GOPATH inside the repo. Roughly like this:
$ git clone https://github.com/foo/bar && cd bar
$ mkdir -p .gopath/src/github.com/foo
$ ln -sTf ../../../.. .gopath/src/github.com/foo/bar
$ GOPATH=$PWD/.gopath go build github.com/foo/bar
Of course, all that bullshit can be nicely tugged away in the Makefile. For example: https://github.com/sapcc/swift-drive-autopilot/blob/a3d5d02b...You can find this either hilarious or sad. I like the irony in using make(1) to patch up the deficiencies of a tool that was created decades after it.
You are trying to build Go in a way it wasn't designed for.
Go encourages absolute import paths (relative to $GOPATH) and solves a myriad of other language faults in this way. A good benefit is go-gettable projects, where all dependencies can be reached without a setup/configuration file (like setup.py, requirements.txt, and so on).
If you do not try to use Go like other language, your build should be something like:
$ GOPATH=$PWD/some/path go get github.com/foo/barYeah, I think his issue is with Go's choice to not search the current directory.
The go tools should let you use the current directory, and the "best practice" would have been vendoring to start, relative to the current directory. Then suddenly you see no GOPATH would be necessary at all! For example:
% mkdir $proj
% go get github.com/$dep1
% go get github.com/$dep2
% vim main.go
% find .
./main.go
./github.com
./github.com/$dep1
./github.com/$dep1/somepkg
./github.com/$dep2
...
See, then main can import github.com/$dep1/somepkg, and it would be properly versioned and vendored! It falls out in a bunch of other ways of being nicer too IMO.The currently GOPATH design encourages untracked and complected dependencies, where we're at 1.8 of the toolchain and we're still changing packaging behavior of dependencies.
(I have no affiliation with gb)
I hope to abandon it for an official solution, though, given that it appears and is good.
In some ways this is similar to cargo which depends on existence of ~/.cargo
btw. you can manually invoke Go compiler and linker. A very simple example from some time ago can be found here: https://github.com/tumdum/go_build
This doesn't restrict you to using a special path or a particular mode of organizing. Rather, it leaves much of that problem to the user, for better or for worse. It's perfectly fine to write programs with GOPATH unset.
Now if they could figure out a way to get go get to work nicely with private repos out of the box without SSH config hacks that'd be great..
I worked on the YCM support for godef, we eventually had to fork the library and rewrite paths since there was no way of pinning to a version within YCM. Libraries written with github paths for `go get` do not play nice with living outside of gopath, and libraries written with relative paths don't work with go get (even though this is something that go could support)
It's fine for a Go project, but this is not a Go project. It should not be forced to change how it works because it wants to contain some Go code.
Go is not like Python, the end result is a binary, not interpreted source code. You can simply write a build script that sets a custom GOPATH inside a temporary folder, pulls all dependencies, builds and pops out a binary ready for use; and you can either discard or save your custom GOPATH anywhere for caching purposes.
Note that this wasn't the only reason we had to fork. Go doesn't (or didn't) provide a way to pin to a dependency, so we would have had to fork anyway, and then rewrite all the paths anyway, so I went the way of using local paths in the fork.
With non-opinionated languages nothing is stopping you from structuring your code the same way.
Some people stated how hard go makes it when you try to have project that utilizes different languages. Another issue is when you try to use a fork of one of library.
Yet another is that it is much more complex to generate a package (e.g. rpm) of projects that has many dependencies.
With Go, I can do `go build $project` from anywhere and get a releasable binary in the working directory. I can do `import "$oldproject/$package"` in my new project and start using it immediately. I can use `godef` to jump around all of the Go code installed on my system and quickly drill down all the way to the Go builtins if I need to. I can use `guru` to see all references to a definition across all of the Go packages installed on my system. The list goes on. And I can do all of that from a favorite text editor (and not a huge slow IDE). I never felt so liberated in any other programming environment, and I've used quite a few.
> Yet another is that it is much more complex to generate a package (e.g. rpm) of projects that has many dependencies.
Go binaries have only the standard system libraries for dependencies - for all practical purposes they can be considered static. Or you mean something else?
> Some people stated how hard go makes it when you try to have project that utilizes different languages.
I've used links successfully, but maybe my scenarios were not complex enough?
> Another issue is when you try to use a fork of one of library.
Vendor support since 1.6 made this a nonissue; it's now trivial to use forked versions of libraries.
A fork of a library is either identical to the original, or a new library. And you could argue (or rather: I do), that it is a good thing that you need to explicitly specify which one you intend to use.
As I said, being opinionated is great if the opinion matches yours otherwise you might end up fighting it on every step.
ln -s PROJECT_SOURCE_FOLDER $GOPATH/src/
Re the other question: If you don't run a go command with a path name, it doesn't matter what the directory structure is. I have tons of non-go projects in my GOPATH and build them with the usual tools. No issues.
GOPATH=$HOME go get github.com/foo/bar
would download the package to: $HOME/src/github.com/foo/bar
So $HOME will not have .git.That is, is the root of each go project effected?
I also set GOPATH=$HOME, and all my source code (not only Go) lives in $HOME/src, and I do use git for both Go and non-Go projects (so they have a .git directory in $HOME/src/what/ever/.git), and there's no problem. Why would there be one?
Wellllllllll... until you actually start to write code against JNI, of course. But the project LAYOUT is simple!
JNA[1] makes things much simpler.
https://plus.google.com/u/0/+RobPikeTheHuman/posts/R58WgWwN9...
Oh, that's rich. This from the guy who designed a language where the case of a symbol's name determines the symbol's visibility.
> First, a bad precedent was set. A lot of other lazy programmers introduced bugs by making the same simplification. Actual files beginning with periods are often skipped when they should be counted.
> Second, and much worse, the idea of a "hidden" or "dot" file was created. As a consequence, more lazy programmers started dropping files into everyone's home directory.
> I don't have all that much stuff installed on the machine I'm using to type this, but my home directory has about a hundred dot files and I don't even know what most of them are or whether they're still needed. Every file name evaluation that goes through my home directory is slowed down by this accumulated sludge.
At least, I can't think of any similar problems that semantically significant casing in Go creates.