cmd/go: modify the Go toolchain to work without GOPATH #17271
Description
Over the years, when helping people approaching existing Go projects (colleagues, friends, etc.) the number one problem is of course that they don't know about GOPATH
, they don't have one configured, and they expect to be able to clone an existing project wherever they want on the disk, and be able to build it. I think the problem statement is clear and the problem is well known.
With the introduction and adoption of the vendoring folder, most Go applications do not even require go get
to run, after the initial clone: all the source code required to compile them is already available in the source tree; it's just that the Go tool doesn't know where to look if GOPATH
is not defined.
Instead of suggesting a default GOPATH
(which does not solve the fact that people will need to find out about it and use it somehow), I suggest that we change the Go toolchain in multiple steps (each one can be independently released as an experiment):
- STEP 1: If
GOPATH
is not set, the Go tool will use any existing./vendor
directory as it was part of theGOPATH
. (I think of this as defaultingGOPATH/src
to./vendor
). At leastgo build
andgo run
are guaranteed to work. Anything else, likego install
andgo get
, would fail with an error pointing to theGOPATH
documentation. - STEP 2: if
GOPATH
is not set, the Go toolchain would be updated to use$HOME/.gopkg
(or similar) aspkg
directory. This would allow other commands to work (e.g.:go build -i
orgo install
). - STEP 3: if
GOPATH
is not set,go get
(or the new package manager, if/when it gets released) would be modified to download packages directly into./vendor
As shown in Step 2, I think this proposal would also interact well with the existing proposal/discussion of dropping pkg
in favour of a hidden cache directory, as that would move things further into the direction of not needing GOPATH
anymore for a whole class of development; in fact, this functionality could be prototyped in this specific scenario of "GOPATH
not defined", where it would make sense to do it without facing the bigger discussion of deprecating pkg
for a normal GOPATH
scenario.
As shown in Step 3, I also think that this might interact well with the new package manager. I saw many people requested that the new package manager ought to be able to download dependencies directly into the vendor folder (like govendor
and glide
can do); if this functionality lands in the new package manager, it would be a perfect default for the "GOPATH
not defined" scenario described here. Alternatively, it might make sense to discuss modifying go get
to have this behaviour.
I think this proposal is incremental, backward-compatible, doesn't affect existing users that successfully use GOPATH
, and allow beginners to approach existing Go codebases without stumbling too soon into GOPATH
.