From 6e26d15428ef5f31eb32c5da08cba3db0c067cab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E7=94=B5=E8=8A=BD=E8=A1=A3?= Date: Sat, 18 Jul 2026 12:07:57 -0400 Subject: [PATCH] Installers persist PATH themselves instead of printing instructions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit install.sh: append the export line to the login shell's rc file (zsh: $ZDOTDIR/.zshrc; bash: ~/.bash_profile on macOS, ~/.bashrc on Linux; fish: fish_add_path in config.fish; otherwise ~/.profile). Idempotent — a second run detects the existing entry and skips. On an unwritable rc it fails loudly with the manual command. install.ps1: prepend the bin dir to the per-user PATH via [Environment]::SetEnvironmentVariable(..., 'User') — registry-backed, picked up by every new terminal. Strict-mode-safe for a null user Path. Verified end-to-end on macOS with a fake HOME: install → rc appended → fresh zsh sources it → kigi resolves and runs. All shell branches, ZDOTDIR/XDG overrides, idempotency, and the write-failure path covered by a harness driving the real script tail; install.ps1 parse-checked and its path-construction logic exercised under pwsh strict mode. --- install.ps1 | 11 ++++++----- install.sh | 36 +++++++++++++++++++++++++++++------- 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/install.ps1 b/install.ps1 index d6b4be3..319cda1 100644 --- a/install.ps1 +++ b/install.ps1 @@ -138,12 +138,13 @@ try { $OnPath = (($UserPath -split ";") -contains $BinDir) -or (($env:Path -split ";") -contains $BinDir) if (-not $OnPath) { + # Persist the bin dir on the per-user PATH so the user doesn't have + # to. Registry-backed; every new terminal picks it up automatically. + $NewUserPath = if ($UserPath) { "$BinDir;$UserPath" } else { $BinDir } + [Environment]::SetEnvironmentVariable("Path", $NewUserPath, "User") Write-Host "" - Write-Host "$BinDir is not on your PATH. Add it for the current user with:" - Write-Host "" - Write-Host " [Environment]::SetEnvironmentVariable('Path', `"$BinDir;`" + [Environment]::GetEnvironmentVariable('Path', 'User'), 'User')" - Write-Host "" - Write-Host "Then open a new terminal and run 'kigi' to get started." + Write-Host "Added $BinDir to your user PATH." + Write-Host "Open a new terminal, then run 'kigi' to get started." } else { Write-Host "Run 'kigi' to get started." } diff --git a/install.sh b/install.sh index 33e1ede..8f9c43d 100644 --- a/install.sh +++ b/install.sh @@ -191,23 +191,45 @@ case ":$PATH:" in printf 'Run `kigi` to get started.\n' ;; *) - printf '\n%s is not on your PATH. Add it permanently:\n\n' "$BIN_DIR" + # Persist BIN_DIR on PATH in the login shell's rc file, so the user + # doesn't have to. Idempotent: skipped when the rc already mentions + # the bin dir. On write failure the manual command is printed and the + # script fails loudly (the binary itself is already installed). + persist_line() { + rc="$1" + line="$2" + if [ -f "$rc" ] && grep -qF "$BIN_DIR" "$rc"; then + printf '\n%s is already configured in %s.\n' "$BIN_DIR" "$rc" + return 0 + fi + printf '\n# Added by the kigi installer\n%s\n' "$line" >> "$rc" \ + || err "could not write $rc — add kigi to your PATH manually: $line" + printf '\nAdded %s to your PATH in %s.\n' "$BIN_DIR" "$rc" + } + EXPORT_LINE="export PATH=\"$BIN_DIR:\$PATH\"" case "${SHELL:-}" in */zsh) - printf " echo 'export PATH=\"%s:\$PATH\"' >> ~/.zshrc\n" "$BIN_DIR" + persist_line "${ZDOTDIR:-$HOME}/.zshrc" "$EXPORT_LINE" ;; */bash) # macOS login shells read ~/.bash_profile; Linux reads ~/.bashrc. - if [ "$PLATFORM_OS" = "macos" ]; then BASH_RC="~/.bash_profile"; else BASH_RC="~/.bashrc"; fi - printf " echo 'export PATH=\"%s:\$PATH\"' >> %s\n" "$BIN_DIR" "$BASH_RC" + if [ "$PLATFORM_OS" = "macos" ]; then + persist_line "$HOME/.bash_profile" "$EXPORT_LINE" + else + persist_line "$HOME/.bashrc" "$EXPORT_LINE" + fi ;; */fish) - printf ' fish_add_path %s\n' "$BIN_DIR" + # fish_add_path in config.fish is fish's own idempotent way + # to persist a PATH entry. + FISH_CONF_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/fish" + mkdir -p "$FISH_CONF_DIR" + persist_line "$FISH_CONF_DIR/config.fish" "fish_add_path $BIN_DIR" ;; *) - printf " echo 'export PATH=\"%s:\$PATH\"' >> ~/.profile\n" "$BIN_DIR" + persist_line "$HOME/.profile" "$EXPORT_LINE" ;; esac - printf '\nThen open a new terminal (or source the file) and run `kigi` to get started.\n' + printf 'Open a new terminal, then run `kigi` to get started.\n' ;; esac