go-nv / goenv

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

Q: Do we want shims to automatically execute older binaries after finding them? #249

Open stevegt opened 1 year ago

stevegt commented 1 year ago

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?

  1. Instead of displaying the above message, run the most recent semver of the binary that is less than or equal to the currently set version of Go.
  2. Do (1), but only if GOENV_RUNOLD is set. (I'm open to a better env var name.)
  3. Keep things the way they are.

I'm leaning toward submitting a PR for (2) -- any strong opinions, and is there anything I'm missing?

ChronosMasterOfAllTime commented 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?

stevegt commented 1 year ago

@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.

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.

huyz commented 1 year ago

In the case of pyenv, there are two solutions for retaining access to packages/executables for an older version of pyenv-managed Python:

  1. https://github.com/pyenv/pyenv-pip-migrate
  2. 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.