fix(install): cross-platform binary install + PATH conflict detection

install_binary() now:
1. Automatically picks best location per platform:
   - macOS: ~/.cargo/bin/ (no sudo, in PATH for Rust users)
   - Linux: ~/.cargo/bin/ → /usr/local/bin → ~/.local/bin/
   - Windows: /usr/local/bin (Git Bash/MSYS2)
2. Detects if old binary exists at a different PATH location
   and warns the user: 'There is ANOTHER gyandoot at ...'
3. Verifies 'command -v gyandoot' resolves correctly after install
4. Shows shell profile instructions if PATH needs updating

Previous issue: always installed to /usr/local/bin with sudo,
overwriting the old binary from install.sh but not warning if
another copy existed elsewhere in PATH.
This commit is contained in:
2026-06-13 18:26:39 +05:30
parent febc4b02c7
commit 3b5b995af8
2 changed files with 107 additions and 10 deletions

View File

@@ -408,7 +408,7 @@ async fn trigger_daemon_start(npx: &str, session: &str) -> Result<(), String> {
/// Find the daemon.js entrypoint in the globally installed camoufox-browser package.
/// Tries: npm root -g → find dist/daemon.js
async fn find_daemon_js(npx: &str) -> Result<std::path::PathBuf, String> {
async fn find_daemon_js(_npx: &str) -> Result<std::path::PathBuf, String> {
// Try `npm root -g` to find global node_modules
let root_output = Command::new("npm")
.args(&["root", "-g"])

View File

@@ -260,16 +260,113 @@ install_binary() {
err "Binary not found at $target_dir/$bin_name"
fi
local install_dir="/usr/local/bin"
if [ ! -w "$install_dir" ]; then
info "Need sudo to install to $install_dir"
sudo cp "$target_dir/$bin_name" "$install_dir/$bin_name"
sudo chmod +x "$install_dir/$bin_name"
else
cp "$target_dir/$bin_name" "$install_dir/$bin_name"
chmod +x "$install_dir/$bin_name"
# ── Detect best install location per platform ─────────────────────
# Priority:
# 1. ~/.cargo/bin/ — always in PATH for Rust users, no sudo
# 2. /usr/local/bin/ — standard Unix location, may need sudo
# 3. Windows: use a standard PATH location or just warn
#
local os
os="$(uname -s)"
local install_dir=""
local installed_to=""
# Detect WSL (Windows Subsystem for Linux)
local is_wsl=false
if [ -f /proc/version ] && grep -qiE 'microsoft|wsl' /proc/version 2>/dev/null; then
is_wsl=true
fi
case "$os" in
Darwin|Linux)
# Option A: ~/.cargo/bin/ (no sudo needed, always in PATH for Rust users)
if [ -d "$HOME/.cargo/bin" ] && echo "$PATH" | grep -q "$HOME/.cargo/bin"; then
install_dir="$HOME/.cargo/bin"
cp "$target_dir/$bin_name" "$install_dir/$bin_name"
chmod +x "$install_dir/$bin_name"
installed_to="$install_dir/$bin_name"
# Option B: /usr/local/bin/ (standard, may need sudo)
elif [ -d "/usr/local/bin" ]; then
if [ -w "/usr/local/bin" ]; then
install_dir="/usr/local/bin"
cp "$target_dir/$bin_name" "$install_dir/$bin_name"
chmod +x "$install_dir/$bin_name"
else
info "Need sudo to install to /usr/local/bin"
sudo cp "$target_dir/$bin_name" "/usr/local/bin/$bin_name"
sudo chmod +x "/usr/local/bin/$bin_name"
install_dir="/usr/local/bin"
fi
installed_to="$install_dir/$bin_name"
# Option C: ~/.local/bin/ (XDG, common on modern Linux)
elif [ -d "$HOME/.local/bin" ] && echo "$PATH" | grep -q "$HOME/.local/bin"; then
install_dir="$HOME/.local/bin"
cp "$target_dir/$bin_name" "$install_dir/$bin_name"
chmod +x "$install_dir/$bin_name"
installed_to="$install_dir/$bin_name"
else
# Fallback: just copy to ~/.cargo/bin and create it
mkdir -p "$HOME/.cargo/bin"
cp "$target_dir/$bin_name" "$HOME/.cargo/bin/$bin_name"
chmod +x "$HOME/.cargo/bin/$bin_name"
install_dir="$HOME/.cargo/bin"
installed_to="$install_dir/$bin_name"
if ! echo "$PATH" | grep -q "$HOME/.cargo/bin"; then
warn "$HOME/.cargo/bin is not in your PATH."
warn "Add this to your shell profile (~/.zshrc, ~/.bashrc, etc.):"
echo " export PATH=\"\$HOME/.cargo/bin:\$PATH\""
fi
fi
;;
CYGWIN*|MINGW*|MSYS*)
# Windows / Git Bash / MSYS2
install_dir="/usr/local/bin"
cp "$target_dir/$bin_name" "$install_dir/$bin_name"
chmod +x "$install_dir/$bin_name"
installed_to="$install_dir/$bin_name"
warn "Windows detected. Make sure '$install_dir' is in your PATH."
;;
*)
err "Unsupported OS: $os"
;;
esac
ok "Installed to $installed_to"
# ── Verify it's usable via PATH ──────────────────────────────────
local cmd_path
cmd_path="$(command -v gyandoot 2>/dev/null || true)"
if [ -z "$cmd_path" ]; then
warn "'gyandoot' not found in PATH after install."
warn "The install directory may not be in your PATH."
warn "Try running with: $installed_to"
if [ -n "$install_dir" ]; then
case "$os" in
Darwin)
echo ""
echo " Add to your ~/.zshrc:"
echo " export PATH=\"$install_dir:\$PATH\""
echo " Then: source ~/.zshrc"
;;
Linux)
echo ""
echo " Add to your ~/.bashrc:"
echo " export PATH=\"$install_dir:\$PATH\""
echo " Then: source ~/.bashrc"
;;
esac
fi
elif [ "$cmd_path" != "$installed_to" ]; then
warn "There's ANOTHER 'gyandoot' at '$cmd_path' that takes priority over '$installed_to'."
warn "That binary is from a PREVIOUS installation and may be outdated."
warn ""
warn " ▶ To use the NEW version, run: $installed_to"
warn " ▶ Or remove the old one: sudo rm $cmd_path"
warn " ▶ Then 'gyandoot run' will pick up the new one."
else
ok "PATH resolves to the newly installed binary."
fi
ok "Installed to $install_dir/$bin_name"
}
print_post_install() {