[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/gitssh-cli/gitssh/main/install-gitssh [Back]  [Original]

#!/bin/sh

#================================================================#
# GitSSH Auto-Installer
# Automatically clones and installs GitSSH from GitHub
# POSIX Compliant - Fixed for curl | sh usage
#================================================================#

set -e  # Exit on any error

# Configuration
REPO_URL="https://github.com/gitssh-cli/gitssh"
TEMP_DIR="/tmp/gitssh-install-$$"
INSTALL_DIR="$TEMP_DIR/gitssh"

#================================================================#
# UTILITY FUNCTIONS
#================================================================#

show_banner() {
    cat &2
}

log_warning() {
    printf "\033[1;33m[WARNING]\033[0m %s\n" "$1"
}

cleanup_on_error() {
    if [ -d "$TEMP_DIR" ]; then
        log_info "Cleaning up temporary files due to error..."
        rm -rf "$TEMP_DIR"
    fi
}

cleanup_final() {
    if [ -d "$TEMP_DIR" ]; then
        log_info "Cleaning up temporary files..."
        rm -rf "$TEMP_DIR"
    fi
}

check_dependencies() {
    missing_deps=""
    
    # Check for git
    if ! command -v git >/dev/null 2>&1; then
        missing_deps="$missing_deps git"
    fi
    
    # Check for chmod
    if ! command -v chmod >/dev/null 2>&1; then
        missing_deps="$missing_deps chmod"
    fi
    
    if [ -n "$missing_deps" ]; then
        log_error "Missing required dependencies:$missing_deps"
        log_error "Please install them and try again."
        exit 1
    fi
}

# POSIX Compliant sleep alternative using read with timeout where available
posix_sleep() {
    duration="$1"
    # Try different sleep methods
    if command -v sleep >/dev/null 2>&1; then
        sleep "$duration"
    elif command -v ping >/dev/null 2>&1; then
        # Use ping as timer (works on most systems)
        ping -c 1 -W "${duration}000" 127.0.0.1 >/dev/null 2>&1 || true
    else
        # Fallback: busy wait (not ideal but POSIX Compliant)
        start_time=$(date +%s)
        while [ $(($(date +%s) - start_time)) -lt "$duration" ]; do
            continue
        done
    fi
}

# Function to detect if we're running via pipe (curl | sh)
is_piped_execution() {
    # Check if stdin is a pipe
    [ ! -t 0 ]
}

# Function to read user input that works with both direct execution and piped execution
read_user_input() {
    printf "\033[1;33mContinue anyway? (y/N): \033[0m"
    
    if is_piped_execution; then
        # When piped, read from terminal directly via /dev/tty
        if [ -r /dev/tty ]; then
            read response < /dev/tty
        else
            # If /dev/tty is not available, try other methods
            if command -v tty >/dev/null 2>&1; then
                tty_device=$(tty)
                if [ "$tty_device" != "not a tty" ] && [ -r "$tty_device" ]; then
                    read response < "$tty_device"
                else
                    # Fallback: assume 'y' for automated environments
                    log_warning "No terminal available, proceeding automatically..."
                    response="y"
                fi
            else
                # Final fallback
                log_warning "No terminal available, proceeding automatically..."
                response="y"
            fi
        fi
    else
        # Normal execution - read from stdin
        read response
    fi
    
    echo "$response"
}

# Function to wait for user confirmation that works with piped execution
wait_for_confirmation() {
    if is_piped_execution; then
        # When piped, read from terminal directly
        printf "\033[1;33mPress Enter to continue with installation...\033[0m"
        if [ -r /dev/tty ]; then
            # Read a single line from the terminal
            head -n 1 < /dev/tty > /dev/null
        else
            # If no terminal available, add a short delay and continue
            log_warning "No terminal available for confirmation, continuing automatically..."
            posix_sleep 2
        fi
    else
        # Normal execution
        printf "\033[1;33mPress Enter to continue with installation...\033[0m"
        read dummy
    fi
}

#================================================================#
# MAIN INSTALLATION PROCESS
#================================================================#

main() {
    # Set up cleanup trap ONLY for errors and interrupts (not normal exit)
    trap cleanup_on_error INT TERM
    
    # Show banner
    show_banner
    
    # Check dependencies
    log_info "Checking system dependencies..."
    check_dependencies
    show_progress 1 6 "Dependencies checked"
    posix_sleep 1
    
    # Create temporary directory
    log_info "Creating temporary directory..."
    mkdir -p "$TEMP_DIR"
    show_progress 2 6 "Temporary directory created"
    posix_sleep 1
    
    # Clone repository
    log_info "Cloning GitSSH repository..."
    if git clone "$REPO_URL" "$INSTALL_DIR" >/dev/null 2>&1; then
        show_progress 3 6 "Repository cloned successfully"
    else
        show_progress 3 6 "Repository clone failed"
        log_error "Failed to clone repository from $REPO_URL"
        log_error "Please check your internet connection and try again."
        cleanup_on_error
        exit 1
    fi
    posix_sleep 1
    
    # Change to install directory
    log_info "Entering installation directory..."
    cd "$INSTALL_DIR"
    show_progress 4 6 "Changed to install directory"
    posix_sleep 1
    
    # Make install script executable
    log_info "Making install script executable..."
    if [ -f "install" ]; then
        chmod +x install
        show_progress 5 6 "Install script made executable"
    else
        show_progress 5 6 "Install script not found"
        log_error "Install script not found in repository"
        log_error "Expected file: $INSTALL_DIR/install"
        cleanup_on_error
        exit 1
    fi
    posix_sleep 1
    
    # Complete preparation
    show_progress 6 6 "Installation preparation complete"
    printf "\n"
    
    # Run installer
    log_success "Repository downloaded and prepared successfully!"
    printf "\n"
    log_info "Starting GitSSH installation..."
    
    # Use the new confirmation function that handles piped execution
    wait_for_confirmation
    
    # Clear the trap before running installer (so installer can manage its own cleanup)
    trap - INT TERM
    
    # Execute the install script with proper stdin handling
    if is_piped_execution; then
        # When script was piped, we need to ensure the install script can also access terminal
        if [ -r /dev/tty ]; then
            # Redirect the install script's stdin to the terminal
            ./install < /dev/tty
        else
            # If no terminal, run without interactive input
            log_warning "Running installation in non-interactive mode..."
            ./install
        fi
    else
        # Normal execution
        ./install
    fi
    
    # Always cleanup after install script finishes, regardless of outcome
    cleanup_final
}

#================================================================#
# ENTRY POINT
#================================================================#

# Check if running as root (optional warning)
if [ "$(id -u)" -eq 0 ]; then
    log_warning "Running as root. GitSSH is typically installed for individual users."
    
    # Use the new input function that handles piped execution
    response=$(read_user_input)
    
    case "$response" in
        [yY]|[yY][eE][sS]) 
            log_info "Proceeding with root installation..."
            ;;
        *)
            log_info "Installation cancelled."
            exit 0
            ;;
    esac
fi

# Run main installation
main "$@"

Web Proxy Viewer  |  New URL  |  Original Page