Open stevegt opened 1 year ago
Unsure I understand the ask here.
Are you saying you want to stay on an older patch version of a particular release?
For example, if go 1.15.2 was used, dont use 1.15.15?
@ChronosMasterOfAllTime When we execute goenv local
, goenv global
, or goenv shell
, that changes the version of Go compiler that will be used to compile binaries in the future. That's all goenv
should change, but right now it also changes PATH access to binaries that have already been compiled -- it inherited this behavior from pyenv
for reasons that are not valid for compiled binaries.
~/go/*/bin
, it ordinarily doesn't need to be compiled again, even when we later use goenv
to switch to a newer compiler. That's the entire point of compiled languages -- an already compiled binary does not need an installed compiler, and doesn't care about the version of any compiler that is in the PATH. goenv
inherited an assumption from pyenv
that says we do care about the version of interpreter that is in the PATH. In the case of pyenv
this is important, because older python executables will not necessarily work with newer versions of the python interpreter, might need libraries that are only installed alongside older interpreters, etc. In the case of goenv
this is an invalid assumption, because Go executables do not use or need an interpreter.goenv
to switch to a new compiler version, we lose access to all of the binaries we already compiled and placed in ~/go/*/bin
. When that happens, a goenv
user has approximately three choices:
~/go/*/bin
directory so the shims will execute them.Do we want to modify the shim code such that, instead of acting like pyenv
and displaying the message listing all of the versions of Go a binary was compiled with, we instead simply execute the most recent version of the binary?
This new behavior might be enabled by a feature flag -- I'm suggesting GOENV_RUNOLD above, but am open to other env variable names.
In the case of pyenv
, there are two solutions for retaining access to packages/executables for an older version of pyenv-managed Python:
pyenv global 3.11.1 3.10.9 3.9.15
. This is how you specify the fallbacks.Perhaps some of these schemes are relevant to goenv
.
I hope this question hasn't come up before: The closest I can find is the discussion in #30.
Right now, goenv follows the pyenv precedent of saying this:
https://github.com/syndbg/goenv/blob/ece1aba5651a73c891d2beb75d37ea35d1c5fb2a/libexec/goenv-which#L94
That behavior -- not running executables associated with older versions -- makes sense for an interpreted language in which libraries need to match executables at runtime. But one of the whole points of migrating from e.g. Python to Go is to get away from that constraint. By carrying forward that behavior from pyenv we are causing ourselves more work than we need to. Each time we use goenv to upgrade to a new Go version, we either manually update PATH to include older versions of GO binaries, or we run
go install
for everything we already had installed.We should be able to simply let the shims run the old binaries instead.
In my own case, I finally wrote a little bash script that walks through all of the older go/*/bin directories in semver order and creates symlinks in a go/basket/bin, which I then put in PATH. That works great except when I want to use goenv to set my local or shell Go version to an earlier version of binaries, in which case I manually edit PATH anyway to remove go/bin/basket. But that means I lose not only the newer binaries but the older binaries as well -- it's not a great solution.
Which of the following options makes more sense?
I'm leaning toward submitting a PR for (2) -- any strong opinions, and is there anything I'm missing?