goenv
goenv copied to clipboard
DOCS: Confusing config for managing $GOROOT
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.
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.
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 -)"
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:
- check if the version detected by go.mod/.go-version is installed
- if not, install it
- re-evaluate and export the new correct GOPATH/GOROOT env vars.
Thoughts?
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!
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?
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.
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.