diff --git a/README.md b/README.md index 67292d1..63969c8 100644 --- a/README.md +++ b/README.md @@ -57,8 +57,5 @@ Tool fragments from this repo: ```bash # always-on (sourced from ~/.zshenv) -curl -fsSL https://git.miomio.moe/mio/easyzsh/raw/branch/master/patch.sh | bash -s -- zsh/fnm - -# interactive-only (sourced from ~/.zshrc) -curl -fsSL https://git.miomio.moe/mio/easyzsh/raw/branch/master/patch.sh | bash -s -- pyenv +curl -fsSL https://git.miomio.moe/mio/easyzsh/raw/branch/master/patch.sh | bash -s -- zsh/fnm zsh/pyenv ``` diff --git a/install_pyenv.sh b/install_pyenv.sh index 92c5241..a469686 100755 --- a/install_pyenv.sh +++ b/install_pyenv.sh @@ -21,5 +21,7 @@ fi # Uncomment the following line if you would like to automatically install it # pyenv install 3.12.0 && pyenv global 3.12.0 -# Apply the pyenv zsh configuration patch (downloads zshrc/pyenv.zsh to ~/.config/zshrc/pyenv.zsh) -curl -fsSL https://git.miomio.moe/mio/easyzsh/raw/branch/master/patch.sh | bash -s -- pyenv +# Always-on fragment: ~/.config/zsh/pyenv.zsh (sourced from ~/.zshenv) +curl -fsSL https://git.miomio.moe/mio/easyzsh/raw/branch/master/patch.sh | bash -s -- zsh/pyenv +# Drop legacy interactive-only copy if present +rm -f "$HOME/.config/zshrc/pyenv.zsh" diff --git a/patch.sh b/patch.sh index a4854bb..32a8292 100755 --- a/patch.sh +++ b/patch.sh @@ -23,7 +23,7 @@ for arg in "$@"; do exit 1 fi rel="${arg}.zsh" - destination="$HOME/.config/${arg}.zsh" + destination="${XDG_CONFIG_HOME:-$HOME/.config}/${arg}.zsh" else if [[ -z "$arg" || "$arg" == *[![:alnum:]_-]* ]]; then echo "Invalid config name: $arg" >&2 @@ -34,7 +34,7 @@ for arg in "$@"; do fi mkdir -p "$(dirname "$destination")" - temporary=$(mktemp "$HOME/.config/.easyzsh-XXXXXX") + temporary=$(mktemp "$(dirname "$destination")/.easyzsh-XXXXXX") trap 'rm -f "$temporary"' EXIT if ! curl -fsSL "${BASE_URL}/${rel}" -o "$temporary"; then diff --git a/tests/installers.sh b/tests/installers.sh index 21557fc..dec1139 100755 --- a/tests/installers.sh +++ b/tests/installers.sh @@ -88,13 +88,15 @@ done [[ ! -e "$ROOT/.zprofile" ]] || fail "easyzsh should not ship a managed .zprofile" [[ -f "$ROOT/zsh/fnm.zsh" ]] || fail "always-on fnm fragment is missing" [[ ! -e "$ROOT/zshrc/fnm.zsh" ]] || fail "legacy interactive fnm fragment still exists" +[[ -f "$ROOT/zsh/pyenv.zsh" ]] || fail "always-on pyenv fragment is missing" +[[ ! -e "$ROOT/zshrc/pyenv.zsh" ]] || fail "legacy interactive pyenv fragment still exists" grep -q 'NVM_VERSION="v0.40.4"' "$ROOT/install_nvm.sh" || fail "nvm version is stale" grep -q 'apt-get install -y unzip' "$ROOT/install_fnm.sh" || fail "Ubuntu unzip installation is missing" grep -q 'tail -1 || true' "$ROOT/install_merlin_worker.sh" || fail "a missing PYTHONPATH remains fatal" grep -Fq 'mktemp "$HOME/.zshrc.download.' "$ROOT/install.sh" || fail ".zshrc is not downloaded on its target filesystem" grep -Fq 'mktemp "$HOME/.zshenv.download.' "$ROOT/install.sh" || fail ".zshenv is not downloaded on its target filesystem" -grep -Fq 'mktemp "$HOME/.config/.easyzsh-' "$ROOT/patch.sh" || fail "patch downloads can be sourced while incomplete" +grep -Fq 'mktemp "$(dirname "$destination")/.easyzsh-' "$ROOT/patch.sh" || fail "patch downloads can be sourced while incomplete" grep -Fq '"$ZSH_CONFIGS_DIR"/*(DN)' "$ROOT/.zshrc" || fail "existing extensionless Zsh configs are ignored" grep -Fq '_resolve_trash_cmd' "$ROOT/.zshrc" || fail "trash-backed rm helper is missing" grep -Fq 'libglib2.0-bin' "$ROOT/install.sh" || fail "Ubuntu Trash support is not installed" @@ -114,6 +116,7 @@ grep -Fq '$HOME/.local/bin' "$ROOT/.zshenv" || fail "~/.local/bin is not added i grep -Fq 'local.zsh' "$ROOT/.zshenv" || fail "local.zsh is not sourced from .zshenv" grep -Fq 'ZSH_ALWAYS_ON_DIR' "$ROOT/.zshenv" || fail "always-on ~/.config/zsh/*.zsh glob is missing from .zshenv" grep -Fq 'zsh/fnm' "$ROOT/install_fnm.sh" || fail "install_fnm.sh does not patch always-on zsh/fnm" +grep -Fq 'zsh/pyenv' "$ROOT/install_pyenv.sh" || fail "install_pyenv.sh does not patch always-on zsh/pyenv" if grep -Fq 'brew shellenv' "$ROOT/.zshrc"; then fail "Homebrew still initializes from interactive-only .zshrc" fi @@ -160,6 +163,16 @@ HOME="$fnm_env_home" PATH=/usr/bin:/bin \ zsh -c 'command -v fnm >/dev/null' || fail "always-on fnm is not available to non-interactive zsh via .zshenv" +# Non-interactive zsh must resolve pyenv's global Python via .zshenv. +pyenv_env_home="$TEMP_DIR/pyenv-env-home" +mkdir -p "$pyenv_env_home/.pyenv/shims" "$pyenv_env_home/.config/zsh" +ln -s /usr/bin/true "$pyenv_env_home/.pyenv/shims/python3" +cp "$ROOT/zsh/pyenv.zsh" "$pyenv_env_home/.config/zsh/pyenv.zsh" +HOME="$pyenv_env_home" bash "$ROOT/deploy.sh" --home "$pyenv_env_home" >/dev/null +HOME="$pyenv_env_home" PYENV_ROOT="$pyenv_env_home/.pyenv" PATH=/usr/bin:/bin \ + zsh -c '[[ "$(command -v python3)" == "$HOME/.pyenv/shims/python3" ]]' || + fail "pyenv Python is not available to non-interactive zsh via .zshenv" + # patch.sh path form installs into ~/.config/zsh/ path_patch_home="$TEMP_DIR/path-patch-home" path_bin="$TEMP_DIR/path-bin" @@ -180,8 +193,9 @@ printf '%s\n' '# patched-fnm' >"$out" CURL chmod +x "$path_bin/curl" # Prefer real coreutils for mktemp/mkdir used by patch.sh -HOME="$path_patch_home" PATH="$path_bin:/usr/bin:/bin" bash "$ROOT/patch.sh" zsh/fnm >/dev/null -grep -Fxq '# patched-fnm' "$path_patch_home/.config/zsh/fnm.zsh" || +HOME="$path_patch_home" XDG_CONFIG_HOME="$path_patch_home/xdg" PATH="$path_bin:/usr/bin:/bin" \ + bash "$ROOT/patch.sh" zsh/fnm >/dev/null +grep -Fxq '# patched-fnm' "$path_patch_home/xdg/zsh/fnm.zsh" || fail "patch.sh zsh/fnm did not install ~/.config/zsh/fnm.zsh" echo "installer checks passed" diff --git a/zsh/pyenv.zsh b/zsh/pyenv.zsh new file mode 100644 index 0000000..0f46ed2 --- /dev/null +++ b/zsh/pyenv.zsh @@ -0,0 +1,7 @@ +# pyenv (Python Version Manager), always-on via ~/.zshenv +export PYENV_ROOT="${PYENV_ROOT:-$HOME/.pyenv}" +[[ -d "$PYENV_ROOT/bin" ]] && export PATH="$PYENV_ROOT/bin:$PATH" +[[ -d "$PYENV_ROOT/shims" ]] && export PATH="$PYENV_ROOT/shims:$PATH" +if [[ -o interactive ]] && command -v pyenv &> /dev/null; then + eval "$(pyenv init - zsh)" +fi diff --git a/zshrc/pyenv.zsh b/zshrc/pyenv.zsh deleted file mode 100644 index 90f6842..0000000 --- a/zshrc/pyenv.zsh +++ /dev/null @@ -1,4 +0,0 @@ -# Initialize pyenv (Python Version Manager) -export PYENV_ROOT="$HOME/.pyenv" -[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH" # Add pyenv to PATH -command -v pyenv &> /dev/null && eval "$(pyenv init - zsh)"