golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
123.22k stars 17.57k forks source link

cmd/go: assume GOPATH=$HOME/go if not set #17262

Closed davecheney closed 7 years ago

davecheney commented 8 years ago

This proposal is a simplification of #12488.

In short, if the user has not set $GOPATH in their environment the go tool will default to a value of GOPATH=$HOME/gocode.


Rationale At the moment all the documentation we have says "you have to set a GOPATH", then people get distracted and upset because they don't understand why they have to do this.

By choosing a default GOPATH, we can make our documentation easier because we can say things like

$ go get github.com/foo/bar

will check out the github.com/foo/bar repo into $HOME/gocode/src/github.com/foo/bar.

We don't need to distract newcomers with having to set an env var, all we need to do is put a little parenthetical note at the bottom of the page

$HOME/gocode is the default path to your go workspace. If you want to change this path, set the GOPATH variable to something of your choosing.

Compatibility This proposal only changes the experience for newcomers who have not chosen to set a $GOPATH variable. For anyone using Go 1.1-1.7 today, your experience will be unchanged as you are currently required to set $GOPATH.

bradfitz commented 8 years ago

/cc @adg @broady @campoy @ianlancetaylor @griesemer @robpike @rsc

campoy commented 8 years ago

I like it, but do we have any specific preference for "gocode" and not something like "gopath"?

rsc commented 8 years ago

How many people already use GOPATH=$HOME/gocode? It seems to me not many. That suggests it is the wrong default.

cespare commented 8 years ago

"gocode" will have search engine and other confusion with the popular tool github.com/nsf/gocode.

ianlancetaylor commented 8 years ago

Do we have any information about what most people do?

I use GOPATH=$HOME/gopath myself.

bradfitz commented 8 years ago

Thumbs up here if you currently use GOPATH=$HOME

bradfitz commented 8 years ago

Thumbs up here if you currently use GOPATH=$HOME/gopath

bradfitz commented 8 years ago

Thumbs up here if you currently use GOPATH=$HOME/gocode

campoy commented 8 years ago

Should I do a twitter poll on @golang?

bradfitz commented 8 years ago

@campoy, sounds good. Probably better than inviting everybody to this bug.

freeformz commented 8 years ago

How about $HOME/go (which is what I use).

freeformz commented 8 years ago

See also : http://go-talks.appspot.com/github.com/freeformz/talks/20160712_gophercon/talk.slide#7

$HOME: 8.9% $HOME/go: 50.6% Other : 40.5%

I really wish I had split out more options for this one.

campoy commented 8 years ago

Voting started: https://twitter.com/golang/status/781189567437164544

On Wed, Sep 28, 2016, 10:51 AM Edward Muller notifications@github.com wrote:

How about $HOME/go (which is what I use).

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/golang/go/issues/17262#issuecomment-250244110, or mute the thread https://github.com/notifications/unsubscribe-auth/ACIkDJ83L5fXByqw-NEQ11JxKPGv_iQkks5quqkXgaJpZM4KI0I2 .

freeformz commented 8 years ago

See also Column I here : https://docs.google.com/spreadsheets/d/1peTY_lq8rRW2zsKjwhd8iwiFZP5AZSrCvbCc07mPOWA/edit#gid=1525640201

rakyll commented 8 years ago

@freeformz,

$HOME/go is conflicting with the path go source code (go.googlesource.com/go) is often checked out. It is bad that the community blessed this location as a default for GOPATH :( I worry if someone forgets to set their GOPATH and runs the go tool, it will mess their current development directory.

freeformz commented 8 years ago

@rakyll to each their own, just wanted to indicate what I and many others use. go.googlesource.com/go is checked out in /usr/local/go.git on my system.

davecheney commented 8 years ago

How many people already use GOPATH=$HOME/gocode? It seems to me not many. That suggests it is the wrong default.

For the record I use GOPATH=$HOME, but I felt that this would be too contentious and detract from the goal of this proposal which is to improve the experience for the new user.

rakyll commented 8 years ago

@freeformz, I guess we don't have to care about the existing canonical paths that are outside of $HOME. The default for GOPATH is going to be in $HOME somewhere and the minimal requirement should be that it doesn't conflict with any critical existing path.

$HOME/gocode sounds alien to me but it could be a very good choice.

davecheney commented 8 years ago

The point being, it matters less what the default is, just that there is one.

rsc commented 8 years ago

It does matter what the default is, because setting this default will essentially make it how everyone new to Go is working a few years from now.

The go command goes out of its way not to get confused when GOPATH=$GOROOT explicitly; I'm sure the same logic can be made to apply to am implicit setting as well. So I'm not too worried about smashing $HOME/go accidentally.

I still wonder if instead of a fixed default we should be auto-sniffing the current directory's parents to figure out where GOPATH is. This is what many source tools do these days (for example, every version control system), so it's a concept people would understand. And it doesn't force them to use one directory name or to have only one GOPATH workspace. But we might as well have that discussion on the original issue.

davecheney commented 8 years ago

@rsc I'd love that default to be GOPATH=$HOME because that means $GOPATH/bin will be in their path (on most linux distributions at least, not sure about darwin).

$GOPATH=$HOME/go is also a good choice and those who have the source of the compiler checked out there will have already set GOPATH=something else so there is no chance of conflict.

To be clear, I wasn't trying to be flippant when I said

The point being, it matters less what the default is, just that there is one.

Rather trying to emphasise the goal of this proposal is to have the go tool use a default value for $GOPATH when one is not provided as this is a continual source of confusion and frustration for so many newcomers to the language.

I'm 👎 on auto sniffing because it fails a major use case, which is:

  1. I've installed Go, I didn't actually read the Go installation docs, just followed what it said on the repo's README that said brew install go
  2. I've run go get github.com/thething/theproject
  3. Now I get an error about not setting $GOPATH. What is that? I just wanted to run this program that someone tweeted about!
adg commented 8 years ago

A default value ofGOPATH=$HOME/go SGTM, assuming we decide on a default and not an auto-sniffing approach.

rakyll commented 8 years ago

The go command goes out of its way not to get confused when GOPATH=$GOROOT explicitly; I'm sure the same logic can be made to apply to am implicit setting as well.

Sounds great.

not sure about darwin

Not on darwin.

mvdan commented 8 years ago

If this is for newcomers, I would advise against GOPATH=$HOME as that would create three directories in their home directory versus just one. I'm not keen on software that pollutes my home dir beyond necessary.

davecheney commented 8 years ago

@mvdan I understand and your reaction was why I did not propose GOPATH=$HOME.

If I personally want to set my GOPATH to $HOME, then that option would remain available to me, and I would have to make no changes should this proposal be accepted for Go 1.8.

alexbrainman commented 8 years ago

@davecheney

default to a value of GOPATH=$HOME/gocode

There is no default HOME variable on Windows. What do you propose to do on Windows?

I'd love that default to be GOPATH=$HOME because that means $GOPATH/bin will be in their path

I am always worried about having $GOPATH/bin in my PATH. go get installs other people's programs there. Do we really want new Go user installing random programs from the Internet somewhere in their PATH?

Alex

davecheney commented 8 years ago

I'm not an experienced windows user, but I assume there is some notion of a base path where documents and settings are stored. For the purpose of this discussion assume that I'm talking about that path in the context of windows users.

If no such path exists, assume C:/gocode.

Wrt to my comment on GOPATH=$HOME, while this is and will continue to be my personal preference, I recognise that this is a contentious option for a default value and as such did not suggest it as the proposed value.

broady commented 8 years ago

Auto-detection is fraught with danger. I started prototyping this a while back, but it added significant complexity both to the go tool and the user experience.

I'm not in the loop of what's been happening with the package management working group, but I can imagine a not-too-distant future where GOPATH is eliminated entirely.

That said, even if GOPATH does disappear some time in the near future, there may still be value in setting a default. If we do think GOPATH is likely to disappear, it doesn't matter too much what we set it to.

From what I read above, there is some consensus that:

  1. As a default, GOPATH=$HOME is too invasive.
  2. The default should include the string go somewhere (likely as a prefix).

I'm not worried about GOPATH being a clone of the main go repo (i.e., GOPATH == GOROOT). People checking out the go repo are likely to have a GOPATH set. The go tool would detect the conflict anyway, as it does today.

With that in mind, the most succinct default would be $HOME/go, which I think is quite reasonable.

alexbrainman commented 8 years ago

I assume there is some notion of a base path where documents and settings are stored.

I don't know of such thing. Perhaps other Windows users will comment here.

If no such path exists, assume C:/gocode.

You want C:\gocode instead. Putting things in the root of C:\ does not sounds right to me. Would you recommend GOPATH to be set to /gocode on Linux? But, given that Windows installer already installs Go into C:\go, C:\gocode for GOPATH is at least consistent.

Alex

mattn commented 8 years ago

But, given that Windows installer already installs Go into C:\go, C:\gocode for GOPATH is at least consistent.

GOPATH should not be provided for each users? To be the same as UNIX, %USERPROFILE%\gocode, I guess.

cznic commented 8 years ago

Go+ poll at https://goo.gl/xAsgEj

geosoft1 commented 8 years ago

after i used for a long time something like $HOME/go-programs i switched GOPATH to $HOME. so,now i have the following structure:

$HOME/bin $HOME/pkg $HOME/src/ $HOME/src/github.com/user/some_github_project $HOME/src/some_project

this structure is more generic and also can be used for using with other languages or projects and with github. for example i have $HOME/src/talks (read it home/sources/talks for markdown files) or other projects in some languages (like $HOME/src/github.com/user/html) but also sources and i have one place for many projects sources with or without github correspondence.

bin or pkg can be considered messy but i think is not so annoying. is more messy to have many source folder for people who use multiple languages.

so, from my point of view the best GOPATH place is $HOME.

hnakamur commented 8 years ago

I'm using $HOME/gocode as my GOPATH. I'm against $HOME/go since sometimes you don't have the root privilege and you need to install Go under your home directory. In such case, I think $HOME/go would be the best for GOROOT. So we should use something different from $HOME/go as GOPATH.

tbroyer commented 8 years ago

@hnakamur Back when I installed Go manually (now using Ubuntu Make), I put it in $HOME/bin/go-${go_version} (with a symlink from $HOME/bin/go to $HOME/bin/go-${version}/bin/go, so I didn't have to edit my $PATH)

mattn commented 8 years ago

@tbroyer It's niche. I guess most of users doen't want extra configuration or settings. In my opinion, ~/bin is used to put own script or binaries already (like me). And I think ~/bin (~/src, ~/pkg) make bit's difficult to remove go binaries.

dvrkps commented 8 years ago

I use $HOME for my GOPATH. Why auto set GOPATH, why not raise warning with good info how to set it if GOPATH not exists ?

SamWhited commented 8 years ago

Why auto set GOPATH, why not raise warning with good info how to set it if GOPATH not exists ?

The problem isn't that people don't know how to set an environment variable (for the most part), it's that even if you do it feels poor to have to jump through hoops to get started using Go. Being able to use Go out of the box with sane defaults as soon as it's installed makes the experience as seamless as possible, and means more people are likely to actually try Go after downloading it, instead of hitting a roadblock, losing their momentum, and deciding it's not worth messing with.

rsc commented 8 years ago

I tend to agree with Chris and Andrew: if there's going to be a default GOPATH, it should be just $HOME/go, not gopath or gocode. Most users do not have a Go distribution checked out there (and everyone who does today already sets GOPATH, so this won't bother them). The default needs to make sense for new users, not advanced ones, and for most users $HOME/go makes a lot of sense.

Jaana raised a concern about the go command getting confused if $HOME/go happens to be a Go distribution, but the go command already checks for accidental GOPATH=$GOROOT. It's easy to check if that's true when GOPATH is set implicitly as well. In fact it would also be easy to augment the check to look for, say, $HOME/go/src/cmd/go/alldocs.go, to avoid confusion even when GOROOT!=$HOME/go but $HOME/go does contain a Go distribution.

geosoft1 commented 8 years ago

$HOME/go is not a good option for GOPATH. let's make a simple exercise of behaviour... new users can easy consider the default like a best practice. let say i'm a new user, why should i consider the defaults a bad thing? more than that the easiest (and the best?) method to install golang is by unpack in $HOME because with this method the compiler is always at the last version and need not root rights so you can easy suppose that many users will have go compiler in $HOME/go. why should i move the compiler in /usr/local when i can simply didn't? more than that they can make projects and can clone projects in this folder. so, they will have a messy folder and with a little careless they can easy delete their project folder with a new golang reinstallation. also, windows users have c:\go by default.

randall77 commented 8 years ago

I like $HOME/gopath. It says what it is. The first result on Google for "gopath" is the right page.

btracey commented 8 years ago

If a default is adopted, could a func GOPATH() string function be added to runtime? Right now one can use os.Getenv(), but with a default it won't be so simple.

bradfitz commented 8 years ago

@btracey, GOPATH is a list, not a single value. Use filepath.SplitList. Also, GOPATH isn't a function of the runtime. It only concerns cmd/go.

adg commented 8 years ago

For backward compatibility we'd probably need to set GOPATH in the process' environment if none is set.

On 30 September 2016 at 08:10, Brendan Tracey notifications@github.com wrote:

If a default is adopted, could a func GOPATH() string function be added to runtime? Right now one can use os.Getenv(), but with a default it won't be so simple.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/golang/go/issues/17262#issuecomment-250605418, or mute the thread https://github.com/notifications/unsubscribe-auth/AIDilc6cjWl0r3-V-6FWruHIiYA_X4nJks5qvDc5gaJpZM4KI0I2 .

btracey commented 8 years ago

You're right @bradfitz. The solution proposed by @adg would meet all of my uses.

davecheney commented 8 years ago

This is an interesting wrinkle. I can see this failing currently when no GOPATH is set, but also when GOPATH contains multiple values, and then there is case where the application is built on one machine and deployed on another.

I don't want to dismiss this usage of GOPATH, I understand the pain of being able to locate support files for your application, but I would like to understand how widespread this usage is, and how the current implementations deal with the issues I highlighted above.

On Fri, 30 Sep 2016, 08:35 Brendan Tracey notifications@github.com wrote:

You're right @bradfitz https://github.com/bradfitz. The solution proposed by @adg https://github.com/adg would meet all of my uses.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/golang/go/issues/17262#issuecomment-250611813, or mute the thread https://github.com/notifications/unsubscribe-auth/AAAcA_e53SwZ7Zf_rWCcbZTyPEmXXhUTks5qvD1JgaJpZM4KI0I2 .

btracey commented 8 years ago

My usage is not the normal one. I do scientific research, and I have found it very effective to not just have gopath/src and gopath/bin, but also gopath/data and gopath/results. This makes it easy to copy the source files over to a new system without also having to copy the (gigabytes of) result files. The new system (say a cluster) generates new results files, and I can copy those results to a central location. It's really easy to then say gopath = os.Getenv("GOPATH"), and save a file to something like filepath.Join(gopath, "results", "projectname", result.json).

davecheney commented 8 years ago

Thank you. To be clear I did not mean to imply your usage was incorrect or wrong, I just wanted to understand this usage of GOPATH wrt to the constraints I highlighted.

On Fri, 30 Sep 2016, 09:09 Brendan Tracey notifications@github.com wrote:

My usage is not the normal one. I do scientific research, and I have found it very effective to not just have gopath/src and gopath/bin, but also gopath/data and gopath/results. This makes it easy to copy the source files over to a new system without also having to copy the (gigabytes of) result files. The new system (say a cluster) generates new results files, and I can copy those results to a central location. It's really easy to then say gopath = os.Getenv("GOPATH"), and save a file to something like filepath.Join(gopath, "results", "projectname", result.json).

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/golang/go/issues/17262#issuecomment-250617618, or mute the thread https://github.com/notifications/unsubscribe-auth/AAAcA_CKox90AQMMAxOs9wEL2ffY0S0zks5qvEUPgaJpZM4KI0I2 .

douglarek commented 8 years ago

Thumbs up here if you currently use GOPATH=$HOME/.go

btracey commented 8 years ago

@davecheney no offense taken, just wanted to provide enough context to be useful.

rsc commented 8 years ago

Let's please leave the use of GOPATH to find support files out of this discussion.

(GOPATH is meant to be a compile-time setting, not a run-time one. I know that people blur these sometimes and use GOPATH to find associated files at run-time, but I don't think we should encourage that or make it easier to do. We need a better story for support files in general, but that should be a separate issue.)