From c727d8e1f21d8585bdb19dbddabdce37f0f7877c Mon Sep 17 00:00:00 2001 From: kdusek Date: Thu, 13 Nov 2025 20:16:01 +0100 Subject: [PATCH] Add --local option to force installation to user bin directory, preventing automatic fallback when sudo is unavailable --- install-borg-cli.sh | 62 +++++++++++++++----- install-git-credential-manager.sh | 36 +++++++----- install-tea-cli.sh | 94 ++++++++++++++----------------- 3 files changed, 111 insertions(+), 81 deletions(-) diff --git a/install-borg-cli.sh b/install-borg-cli.sh index 1398bf0..c532cf7 100755 --- a/install-borg-cli.sh +++ b/install-borg-cli.sh @@ -278,28 +278,53 @@ check_version_symlink() { # Function to determine installation strategy determine_install_strategy() { + local local_install="$1" local current_info=$(get_current_version) local current_version=$(echo "$current_info" | cut -d: -f1) local install_type=$(echo "$current_info" | cut -d: -f2) - # Strategy: Prefer system installation for all users - if [[ $EUID -eq 0 ]]; then - print_status "Running as root, installing system-wide" - INSTALL_STRATEGY="system_install" - TARGET_DIR="$SYSTEM_INSTALL_DIR" - elif sudo -n true 2>/dev/null; then - print_status "Passwordless sudo available, installing system-wide" - INSTALL_STRATEGY="system_install" - TARGET_DIR="$SYSTEM_INSTALL_DIR" - elif command_exists sudo; then - print_status "Testing sudo access (you may be prompted for password)..." - if sudo -v 2>/dev/null; then - print_success "Sudo access confirmed, installing system-wide" + # Strategy: Check installation type preference + if [[ "$local_install" == "true" ]]; then + print_status "Local installation requested" + if check_user_bin_setup; then + print_status "User bin directory is available and in PATH" + INSTALL_STRATEGY="user_install" + TARGET_DIR="$USER_BIN_DIR" + else + print_error "User bin directory not available for local installation" + exit 1 + fi + else + # Prefer system installation for all users + if [[ $EUID -eq 0 ]]; then + print_status "Running as root, installing system-wide" INSTALL_STRATEGY="system_install" TARGET_DIR="$SYSTEM_INSTALL_DIR" + elif sudo -n true 2>/dev/null; then + print_status "Passwordless sudo available, installing system-wide" + INSTALL_STRATEGY="system_install" + TARGET_DIR="$SYSTEM_INSTALL_DIR" + elif command_exists sudo; then + print_status "Testing sudo access (you may be prompted for password)..." + if sudo -v 2>/dev/null; then + print_success "Sudo access confirmed, installing system-wide" + INSTALL_STRATEGY="system_install" + TARGET_DIR="$SYSTEM_INSTALL_DIR" + else + print_error "Sudo access failed. Use --local to install to user bin directory" + exit 1 + fi else - print_warning "Sudo access failed, falling back to user installation" + print_error "Sudo not available. Use --local to install to user bin directory" + exit 1 fi + + # Warn if user bin has borg (only for system installs) + if [[ "$INSTALL_STRATEGY" == "system_install" ]] && [[ -f "$USER_BIN_DIR/borg" ]]; then + print_warning "Borg CLI found in user bin directory ($USER_BIN_DIR)" + print_status "This might take precedence if $USER_BIN_DIR is in PATH before system paths" + fi + fi else print_warning "Sudo not available, using user installation" fi @@ -463,6 +488,7 @@ show_usage() { echo " -v, --version Install specific version (default: latest)" echo " -f, --force Force reinstall even if up-to-date" echo " -r, --reinstall Reinstall the current installed version" + echo " -l, --local Force installation to user bin directory (~/.bin)" echo " -p, --package Force installation from package manager" echo " -b, --binary Force installation from binary" echo @@ -470,6 +496,7 @@ show_usage() { echo " $0 # Install latest version using best method" echo " $0 -v v1.2.7 # Install specific version" echo " $0 --reinstall # Reinstall current version" + echo " $0 --local # Force installation to user bin" echo " $0 --package # Force installation from package manager" echo " $0 --binary # Force installation from binary" echo @@ -480,6 +507,7 @@ main() { local target_version="" local force_reinstall=false local reinstall_current=false + local local_install=false local install_method="auto" # Parse command line arguments @@ -501,6 +529,10 @@ main() { reinstall_current=true shift ;; + -l|--local) + local_install=true + shift + ;; -p|--package) install_method="package" shift @@ -553,7 +585,7 @@ main() { fi # Determine installation strategy - determine_install_strategy + determine_install_strategy "$local_install" # Check if update is needed if ! check_update_needed "$target_version"; then diff --git a/install-git-credential-manager.sh b/install-git-credential-manager.sh index cad284f..0d7ada7 100755 --- a/install-git-credential-manager.sh +++ b/install-git-credential-manager.sh @@ -511,6 +511,7 @@ show_usage() { echo " -v, --version Install specific version (default: latest)" echo " -f, --force Force reinstall even if already installed" echo " -r, --reinstall Reinstall the current installed version" + echo " -l, --local Force installation to user bin directory (~/.bin)" echo " -p, --package Force installation from package manager" echo " -d, --deb Force installation from DEB package" echo " -t, --tarball Force installation from tarball" @@ -520,6 +521,7 @@ show_usage() { echo " $0 # Install latest version using best method" echo " $0 -v v2.6.0 # Install specific version" echo " $0 --reinstall # Reinstall current version" + echo " $0 --local # Force installation to user bin" echo " $0 --package # Force installation from package manager" echo " $0 --deb # Force installation from DEB package" echo " $0 --checks # Check configuration without installing" @@ -556,6 +558,7 @@ main() { local target_version="" local force_reinstall=false local reinstall_current=false + local local_install=false local install_method="auto" local checks_only=false @@ -578,6 +581,10 @@ main() { reinstall_current=true shift ;; + -l|--local) + local_install=true + shift + ;; -p|--package) install_method="package" shift @@ -643,21 +650,20 @@ main() { # Detect system detect_os ARCH=$(get_arch) - - # Create temporary directory - mkdir -p "$TEMP_DIR" - - # Trap cleanup on exit - trap cleanup EXIT - - # Installation logic based on method - case $install_method in - auto) - # Try package manager first - if install_from_package_manager; then - verify_installation - exit 0 - fi + + # Check for local installation + if [[ "$local_install" == "true" ]]; then + print_error "Git Credential Manager requires system installation for proper integration" + exit 1 + fi + + # Get latest version if not specified + if [[ -z "$target_version" ]]; then + get_latest_release + target_version="$LATEST_VERSION" + else + print_status "Using specified version: $target_version" + fi # Fall back to distribution-specific methods case $OS in diff --git a/install-tea-cli.sh b/install-tea-cli.sh index 66e4307..807ccc9 100755 --- a/install-tea-cli.sh +++ b/install-tea-cli.sh @@ -154,67 +154,52 @@ check_version_symlink() { # Function to determine installation strategy determine_install_strategy() { + local local_install="$1" local current_info=$(get_current_version) local current_version=$(echo "$current_info" | cut -d: -f1) local install_type=$(echo "$current_info" | cut -d: -f2) - # Strategy: Prefer system installation for all users - if [[ $EUID -eq 0 ]]; then - print_status "Running as root, installing system-wide" - INSTALL_STRATEGY="system_install" - TARGET_DIR="$SYSTEM_INSTALL_DIR" - elif sudo -n true 2>/dev/null; then - print_status "Passwordless sudo available, installing system-wide" - INSTALL_STRATEGY="system_install" - TARGET_DIR="$SYSTEM_INSTALL_DIR" - elif command_exists sudo; then - print_status "Testing sudo access (you may be prompted for password)..." - if sudo -v 2>/dev/null; then - print_success "Sudo access confirmed, installing system-wide" - INSTALL_STRATEGY="system_install" - TARGET_DIR="$SYSTEM_INSTALL_DIR" - else - print_warning "Sudo access failed, falling back to user installation" - fi - else - print_warning "Sudo not available, using user installation" - fi - - # Warn if user bin has tea (only for system installs) - if [[ "$INSTALL_STRATEGY" == "system_install" ]] && [[ -f "$USER_BIN_DIR/tea" ]]; then - print_warning "Tea CLI found in user bin directory ($USER_BIN_DIR)" - print_status "This might take precedence if $USER_BIN_DIR is in PATH before system paths" - fi - - # If not system install, check user bin - if [[ "$INSTALL_STRATEGY" != "system_install" ]]; then - print_status "No sudo access, checking user bin directory" + # Strategy: Check installation type preference + if [[ "$local_install" == "true" ]]; then + print_status "Local installation requested" if check_user_bin_setup; then print_status "User bin directory is available and in PATH" - - # Check if tea exists in user bin - if [[ -f "$USER_BIN_DIR/tea" ]]; then - print_status "Tea CLI found in user bin directory" - - # Check for version symlink - if check_version_symlink; then - print_status "Version symlink found: $CURRENT_SYMLINK_VERSION" - INSTALL_STRATEGY="user_update" - TARGET_DIR="$USER_BIN_DIR" - else - print_status "No version symlink found, will create one" - INSTALL_STRATEGY="user_upgrade" - TARGET_DIR="$USER_BIN_DIR" - fi + INSTALL_STRATEGY="user_install" + TARGET_DIR="$USER_BIN_DIR" + else + print_error "User bin directory not available for local installation" + exit 1 + fi + else + # Prefer system installation for all users + if [[ $EUID -eq 0 ]]; then + print_status "Running as root, installing system-wide" + INSTALL_STRATEGY="system_install" + TARGET_DIR="$SYSTEM_INSTALL_DIR" + elif sudo -n true 2>/dev/null; then + print_status "Passwordless sudo available, installing system-wide" + INSTALL_STRATEGY="system_install" + TARGET_DIR="$SYSTEM_INSTALL_DIR" + elif command_exists sudo; then + print_status "Testing sudo access (you may be prompted for password)..." + if sudo -v 2>/dev/null; then + print_success "Sudo access confirmed, installing system-wide" + INSTALL_STRATEGY="system_install" + TARGET_DIR="$SYSTEM_INSTALL_DIR" else - print_status "Tea CLI not found in user bin, will install there" - INSTALL_STRATEGY="user_install" - TARGET_DIR="$USER_BIN_DIR" + print_error "Sudo access failed. Use --local to install to user bin directory" + exit 1 fi else - print_error "Cannot install system-wide (no sudo) and user bin not available" + print_error "Sudo not available. Use --local to install to user bin directory" exit 1 fi + + # Warn if user bin has tea (only for system installs) + if [[ "$INSTALL_STRATEGY" == "system_install" ]] && [[ -f "$USER_BIN_DIR/tea" ]]; then + print_warning "Tea CLI found in user bin directory ($USER_BIN_DIR)" + print_status "This might take precedence if $USER_BIN_DIR is in PATH before system paths" + fi fi print_status "Installation strategy: $INSTALL_STRATEGY" @@ -453,6 +438,7 @@ show_usage() { echo " -v, --version Install specific version (default: latest)" echo " -f, --force Force reinstall even if up-to-date" echo " -r, --reinstall Reinstall the current installed version" + echo " -l, --local Force installation to user bin directory (~/.bin)" echo " -p, --package Force installation from package manager" echo " -b, --binary Force installation from binary" echo @@ -460,6 +446,7 @@ show_usage() { echo " $0 # Install latest version using best method" echo " $0 -v v0.10.0 # Install specific version" echo " $0 --reinstall # Reinstall current version" + echo " $0 --local # Force installation to user bin" echo " $0 --package # Force installation from package manager" echo " $0 --binary # Force installation from binary" echo @@ -470,6 +457,7 @@ main() { local target_version="" local force_reinstall=false local reinstall_current=false + local local_install=false local install_method="auto" # Parse command line arguments @@ -491,6 +479,10 @@ main() { reinstall_current=true shift ;; + -l|--local) + local_install=true + shift + ;; -p|--package) install_method="package" shift @@ -543,7 +535,7 @@ main() { fi # Determine installation strategy - determine_install_strategy + determine_install_strategy "$local_install" # Check if update is needed if ! check_update_needed "$target_version"; then