Skip to content

Default install to ~/.local/bin to avoid requiring sudo#17

Merged
albertodebortoli merged 2 commits into
mainfrom
feature/no-sudo-default-install
Jul 26, 2026
Merged

Default install to ~/.local/bin to avoid requiring sudo#17
albertodebortoli merged 2 commits into
mainfrom
feature/no-sudo-default-install

Conversation

@albertodebortoli

Copy link
Copy Markdown
Member

Summary

install.sh / uninstall.sh defaulted INSTALL_DIR to /usr/local/bin, which is root-owned on stock macOS. Even though the scripts already had sudo_if_install_dir_not_writeable() to skip sudo when possible, that helper never actually got a chance to skip it because the default target directory itself required elevated privileges — every fresh install prompted for a password.

This PR switches the default to the XDG-style ~/.local/bin (a common no-sudo convention, used by tools like pipx, uv, rustup), while keeping /usr/local/bin fully supported as an opt-in via INSTALL_DIR=/usr/local/bin ./install.sh.

  • install.sh
    • INSTALL_DIR now defaults to $HOME/.local/bin instead of /usr/local/bin.
    • New "PATH setup" step: if $INSTALL_DIR isn't already on PATH for the current session, appends an export PATH=... line to the detected shell RC file (.bashrc/.zshrc), idempotently (skips if the exact line is already present), and exports it into the current process too. If the shell can't be detected, prints a manual instruction instead of failing.
    • Deduplicated shell RC detection: previously the script detected $SHELL → RC file in two separate, identical case blocks (once for the new PATH step, once for the final "how to start using Luca" message). Consolidated into a single SHELL_PROFILE variable computed once and reused by both.
  • uninstall.sh
    • INSTALL_DIR default updated to match.
    • Removes the PATH export line it added, alongside the existing shell-hook cleanup.
  • README.md
    • Updated the mermaid diagrams (install flow, uninstall flow, directory structure, sequence diagram) to reflect ~/.local/bin as the default and the new PATH-bootstrap step.

Notes

  • If PATH already contains $INSTALL_DIR in the running shell (e.g. because another tool like uv/rustup already sources an env file that adds ~/.local/bin), the script correctly no-ops on the RC file — it doesn't need to duplicate PATH setup that's already handled elsewhere.
  • Existing installs at /usr/local/bin (from before this change) are unaffected; they just won't be found unless INSTALL_DIR=/usr/local/bin is set, or the user re-runs uninstall with that override before switching to the new default location.

Test plan

  • bash -n install.sh / bash -n uninstall.sh — syntax check
  • bats tests/*.bats — full suite (60/60) passes unchanged, since tests already override INSTALL_DIR explicitly
  • Manually verified on a real machine: fresh terminal picks up luca from ~/.local/bin without sudo; confirmed the "already on PATH" fast path correctly skips redundant RC edits when another tool (uv's ~/.local/bin/env) already manages PATH

INSTALL_DIR previously defaulted to /usr/local/bin, which is root-owned
on stock macOS, forcing every install through sudo. Default to the
XDG-style ~/.local/bin instead (still overridable via INSTALL_DIR) and
bootstrap PATH in the user's shell RC file when needed, mirroring
existing patterns like rustup/pipx. uninstall.sh cleans up the same
PATH export it adds.
Both the PATH bootstrap step and the final "installation complete"
message independently re-detected the shell RC file with the same
case statement. Compute SHELL_PROFILE once and reuse it in both places.
@albertodebortoli
albertodebortoli merged commit 2b6a189 into main Jul 26, 2026
2 checks passed
@albertodebortoli
albertodebortoli deleted the feature/no-sudo-default-install branch July 26, 2026 09:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant