Use shim approach instead of modifying `PATH`
meatballhat opened this issue ยท 8 comments
A pattern that's been adopted by other language version managers like rbenv
and pyenv
is to generate "shim" executables so that the value of PATH
can remain stable. I think this would be a reasonable enhancement for gimme
, too ๐
We could also accomplish something similar with a current
(or similar) symlink such that there's only one PATH
modification instead of one per usage (or a combination of both approaches with a current
directory symlink and then per-tool symlinks into that current
folder).
I don't know how common it is for users of gimme
to use multiple versions concurrently (where the localized PATH
modifications are not only useful but desirable), but at least in CI that's probably really uncommon.
@tianon I can contribute an anecdata point in that I use gimme
via direnv
in multiple projects with different go version needs. In that usage, a stable current
wouldn't work, IIUC ๐ค
That sounds like an argument for the shims being optional and possibly even non-default. sweat_smile
@tianon oh! I was thinking that the shims would help with this situation ๐ค The shim would take into account the cwd and env and use the correct version, maybe bail with an error if the version isn't already installed? Although bailing early would be more like the behavior of {thing}env
tools, it would be different than current gimme
expectations which attempts to install whatever you ask for.
So you're thinking gimme
would keep track of which version corresponds to each directory or some kind of sentinel file? (perhaps abusing go.mod
's go X.YY
?)
So you're thinking
gimme
would keep track of which version corresponds to each directory or some kind of sentinel file? (perhapsabusinggo.mod
'sgo X.YY
?)
Right (I think) ๐ค There's precedent in other tooling to use a .{thing}-version
file, which maybe gimme
should learn how to respect, and there's the current support for abusing go.mod
, and the long-time support for respecting GIMME_GO_VERSION
which could be set via whatever env var management tool one prefers (I usually use direnv). I think the biggest behavioral difference here would be to bail early if the requested version isn't already available locally, so a generated/managed shim file would set something like GIMME_BAIL_ON_UNAVAILABLE=1
and then gimme
would echo something helpful for human consumption to stderr
. WDYT?
Seems pretty reasonable! Because I think better in code (especially Bash), here's a really rough example of my interpretation of your thoughts into a /usr/local/bin/go
type wrapper:
#!/usr/bin/env bash
set -Eeuo pipefail
e="$(GIMME_BAIL_ON_UNAVAILABLE=1 gimme "${GIMME_GO_VERSION:-module}")"
eval "$e"
exec go "$@"
# perhaps even instead something like:
tool="$(basename "$0")"
exec "$tool" "$@"
# (so this same script can be symlinked to all the possible "go" tools we might want to invoke? are there more than just "go" that are interesting? I suppose "gofmt" is probably the only one, since it's the only other entry in Go's "bin/" directory)
@tianon Yes! and thank you!