Use XDG (i.e. `~/.local/bin`) instead of the Cargo home directory in the installer
Reviving https://github.com/astral-sh/uv/pull/2236
Basically implements https://github.com/axodotdev/cargo-dist/issues/287
I don't really know how to test this.
Okay so... testing this out
cargo dist build
npx http-server -o ./target/distrib
then edit the installer to use ARTIFACT_DOWNLOAD_URL="http://127.0.0.1:8080/target/distrib/"
give a happy installation at the new location
❯ ./target/distrib/uv-installer.sh
downloading uv 0.4.25 aarch64-apple-darwin
installing to /Users/zb/.local/bin
uv
uvx
everything's installed!
unfortunately uv is not at the front of the path
❯ which uv
/Users/zb/.cargo/bin/uv
after restarting my shell it is though
# Restart shell
❯ which uv
/Users/zb/.local/bin/uv
using XDG_BIN_HOME works
❯ XDG_BIN_HOME=/tmp/test ./target/distrib/uv-installer.sh
downloading uv 0.4.25 aarch64-apple-darwin
installing to /tmp/test
uv
uvx
everything's installed!
To add /tmp/test to your PATH, either restart your shell or run:
source /tmp/test/env (sh, bash, zsh)
source /tmp/test/env.fish (fish)
❯ ls /tmp/test
env env.fish uv uvx
using XDG_DATA_HOME works
❯ XDG_DATA_HOME=/tmp/test ./target/distrib/uv-installer.sh
downloading uv 0.4.25 aarch64-apple-darwin
installing to /tmp/test/../bin
uv
uvx
everything's installed!
To add /tmp/test/../bin to your PATH, either restart your shell or run:
source /tmp/test/../bin/env (sh, bash, zsh)
source /tmp/test/../bin/env.fish (fish)
❯ ls /tmp/test
❯ ls /tmp/bin
env env.fish uv uvx
Some pain points:
-
There's no warning if the newly installed
uvis not first on the path, i.e., another uv binary will be used instead of the one I just installed. -
The installer adds
envfiles to the bin — is that what we want? They're not overridden, which is nice, but I presume that could also lead to confusing behavior?❯ touch /tmp/test/env ❯ XDG_BIN_HOME=/tmp/test ./target/distrib/uv-installer.sh downloading uv 0.4.25 aarch64-apple-darwin installing to /tmp/test uv uvx everything's installed! ❯ cat /tmp/test/env -
Relative paths don't display as absolute, i.e., for
XDG_DATA_HOMEthe installer displays/tmp/test/../bin/env
Requires some docs changes still
Agree, per Discord, that (3) seems fixable in cargo-dist. I could PR it if needed.
For my own understanding, where does $XDG_DATA_HOME/../bin come from? (I know we check this already.)
It's interesting that the env files are added within the install directory? For Cargo it looks like it's /Users/crmarsh/.cargo/bin/uv and then /Users/crmarsh/.cargo/env (one level up).
The env file thing seems like the most unfortunate to me... Should we ask for a way to disable that?
It seems kind of problematic because now env will be a binary on PATH?
For my own understanding, where does
$XDG_DATA_HOME/../bincome from? (I know we check this already.)
XDG_BIN_HOME isn't officially a part of the standard. So it's sort of a "next best" approximation of where we should put binaries.
Regarding env — yeah it's not great, but it doesn't shadow the env executable because it's not executable
❯ PATH="/tmp/bin:$PATH" which env
/usr/bin/env
❯ /tmp/bin/env
zsh: permission denied: /tmp/bin/env
I think it's ~okay.
Is it worth trying to get it removed?
In favor of what? It still needs to go somewhere for activation purposes right? My main concern is that it could collide with another env file in that directory, but at least it doesn't overwrite it. I think that probably won't be common anyway.
Sorry, why is it necessary?
Is it sourced from .zshrc or similar?
It's what they use for adding the install directory to the PATH in shells without duplicating the entry, e.g., in my .zshrc:
. "$HOME/.cargo/env"
So if you run XDG_BIN_HOME=/tmp/test ./target/distrib/uv-installer.sh, does it add . /tmp/test/env to your .zshrc? (Just making sure I understand.)
Does it always do that, or only if it's not on PATH already?
As far as I understand, it's the same as the existing behavior (just in a flat directory, which honestly makes more sense to me anyway).
❯ export XDG_BIN_HOME=/tmp/example-bin-home
❯ ./target/distrib/uv-installer.sh
downloading uv 0.4.25 aarch64-apple-darwin
installing to /tmp/example-bin-home
uv
uvx
everything's installed!
To add /tmp/example-bin-home to your PATH, either restart your shell or run:
source /tmp/example-bin-home/env (sh, bash, zsh)
source /tmp/example-bin-home/env.fish (fish)
❯ cat /tmp/example-bin-home/env
#!/bin/sh
# add binaries to PATH if they aren't added yet
# affix colons on either side of $PATH to simplify matching
case ":${PATH}:" in
*:"/tmp/example-bin-home":*)
;;
*)
# Prepending path in case a system-installed binary needs to be overridden
export PATH="/tmp/example-bin-home:$PATH"
;;
esac
❯ cat ~/.zshrc | grep "example-bin-home"
. "/tmp/example-bin-home/env"
Sorry to repeat, but does it add to .zshrc if the directory is already on PATH?
Ah I thought you meant did the env script duplicate the entry. No, it looks skips creating the env files and modifying the shell config at all:
❯ export XDG_BIN_HOME="/tmp/example-3"
❯ export PATH="/tmp/example-3:$PATH"
❯ ./target/distrib/uv-installer.sh
downloading uv 0.4.25 aarch64-apple-darwin
installing to /tmp/example-3
uv
uvx
everything's installed!
❯ cat ~/.zshrc | grep "example-3"
❯ ls /tmp/example-3
uv uvx
Thanks!