go-nv / goenv

:blue_car: Like pyenv and rbenv, but for Go.
https://github.com/go-nv/goenv
MIT License
2.07k stars 246 forks source link

DOCS: Confusing config for managing $GOROOT #233

Open jkopczyn opened 2 years ago

jkopczyn commented 2 years ago

In ./INSTALL.md, it says:

If you want goenv to manage GOPATH and GOROOT (recommended), add GOPATH and GOROOT to your shell after eval "$(goenv init -)".

 $ echo 'export PATH="$GOROOT/bin:$PATH"' >> ~/.bash_profile
 $ echo 'export PATH="$PATH:$GOPATH/bin"' >> ~/.bash_profile

For GOPATH, this makes sense. But on my machine, $GOROOT is /Users/jrandom/.goenv/versions/1.18.0. This matches the value of goenv global when the shell was created, but if I change that, $GOROOT doesn't change, nor does $PATH. Also, this doesn't respect goenv local in any case.

What makes this additionally confusing is that goenv works fine despite that. Probably through the inclusion of /Users/jrandom/.goenv/shims in the path, the correct versions of go are found and used. But since that works, what is the GOROOT entry doing? Isn't it completely superfluous?

I'd appreciate the docs being clarified on this point. And/or changed, if it actually is superfluous and the recommendation is no longer correct.

dantman commented 2 years ago

I have the same thoughts.

And for a user with no default Go install these lines result in the PATH containing two extra /bin entries in it. Which ironically may have broken pyenv for me because the first line adds /bin to the very start of PATH resulting in /bin/python overriding pyenv's shims.

bentlema commented 1 year ago

I'm seeing this also I think. I'm using goenv 2.0.2 installed via Homebrew on a Mac with zsh, and the GOPATH and GOROOT env vars are not being updated when switching go versions:

$ cat .goenv/version
1.18.7

$ cat testing-something/.go-version
1.19.2

$ goenv versions
* 1.18.7 (set by /Users/markbentley/.goenv/version)
  1.19.2

$ env | grep GO && go version
GOENV_SHELL=zsh
GOENV_ROOT=/Users/markbentley/.goenv
GOROOT=/Users/markbentley/.goenv/versions/1.18.7
GOPATH=/Users/markbentley/go/1.18.7
go version go1.18.7 darwin/amd64

$ cd testing-something
$ env | grep GO && go version
GOENV_SHELL=zsh
GOENV_ROOT=/Users/markbentley/.goenv
GOROOT=/Users/markbentley/.goenv/versions/1.18.7
GOPATH=/Users/markbentley/go/1.18.7
go version go1.19.2 darwin/amd64

Notice that when I cd into the testing-something directory containing a .go-version file, the shim is updated, and I'm getting the correct version of go, but the GOROOT and GOPATH still have 1.18.7 which is incorrect. If I run goenv rehash they are updated, but I shouldn't have to do that.

I have only this at the tail end of my .zshrc:

eval "$(goenv init -)"
ChronosMasterOfAllTime commented 1 year ago

That eval statement will only execute any time a new zsh instance is executed (as expected with .zshrc/.zprofile/.zshenv). I am unsure how your go version switched by changing dirs. I tried to replicate this locally using Ubuntu 20.04 + zsh. I had to forcibly re-source my profile to re-evaluate my shims and get the correct go version loaded

Now here's what I was thinking at some point as an idea.

If you're familiar with Terraform and tfswitch, it automatically reads your terraform version file and changes your PATH pointers to the correct binary (no additional params, just invoke tfswitch). However, updating the GOROOT and GOPATH might be a bit tricky because we need to export those new values and you would have to source the new out put. This is similar to Python's virtual environments of sourcing the .env/bin/activate script. What might be beneficial is if we export an alias called (part of the eval exports) goenv-switch which will:

Thoughts?

ChronosMasterOfAllTime commented 1 year ago

I have the same thoughts.

And for a user with no default Go install these lines result in the PATH containing two extra /bin entries in it. Which ironically may have broken pyenv for me because the first line adds /bin to the very start of PATH resulting in /bin/python overriding pyenv's shims.

This may have been fixed in the latest release of goenv. We had a PR that was merged to move goenv's shims to the end of the path definition instead of the beginning. Hope that helps!

sarim commented 1 year ago

If you have to type a command manually to properly switch go version, then it kinda invalidates this whole project. It needs to be automatic, maybe a lightweight shell function executed from PROMPT_COMMAND?

ChronosMasterOfAllTime commented 1 year ago

If you have to type a command manually to properly switch go version, then it kinda invalidates this whole project. It needs to be automatic, maybe a lightweight shell function executed from PROMPT_COMMAND?

I get that, you would want something that detects if the go version is different than the local/global and then re-executes the eval, otherwise it can become expensive. You would also need to auto install if the expected version doesn't exist locally. I would put this behind an env var feature flag, (e.g. GOENV_AUTO_SWITCH) because not everyone necessarily wants this behavior.

kvendingoldo commented 6 months ago

btw. you can also use tenv that support Terraform as well as OpenTofu (and Terragrunt :) ) in one tool. It allow you to simplify version management and can do much more, than tfswitch.