Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
445 changes: 443 additions & 2 deletions README.md

Large diffs are not rendered by default.

1,173 changes: 1,173 additions & 0 deletions gitssh

Large diffs are not rendered by default.

1,514 changes: 1,514 additions & 0 deletions install

Large diffs are not rendered by default.

313 changes: 313 additions & 0 deletions install-gitssh
Original file line number Diff line number Diff line change
@@ -0,0 +1,313 @@
#!/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 << 'EOF'
╔═══════════════════════════════════════════════════════════════╗
║ ║
║ ██████╗ ███████╗███████╗██╗ ██╗ ║
║ ██╔════╝ ██╗ ██╗ ██╔════╝██╔════╝██║ ██║ ║
║ ██║ ███╗══╝████║███████╗███████╗███████║ ║
║ ██║ ██║██║ ██║ ╚════██║╚════██║██╔══██║ ║
║ ██████╔╝██║ ██║ ███████║███████║██║ ██║ ║
║ ╚═════╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝╚═╝ ╚═╝v0.1.0-Oz ║
║ <-POSIX Compliant-> ║
║ ║
╚═══════════════════════════════════════════════════════════════╝
Manage Multiple SSH Git and GitHub Account Sessions With Ease!

EOF
}

show_progress() {
current="$1"
total="$2"
message="$3"
width=50

# POSIX arithmetic
percentage=$((current * 100 / total))
filled=$((current * width / total))
empty=$((width - filled))

printf "\r\033[0;34m[\033[0m"

# Print filled portion
i=0
while [ $i -lt $filled ]; do
printf "█"
i=$((i + 1))
done

# Print empty portion
i=0
while [ $i -lt $empty ]; do
printf " "
i=$((i + 1))
done

printf "\033[0;34m] %d%% - %s\033[0m" "$percentage" "$message"

if [ "$current" -eq "$total" ]; then
printf "\n"
fi
}

log_info() {
printf "\033[0;34m[INFO]\033[0m %s\n" "$1"
}

log_success() {
printf "\033[0;32m[SUCCESS]\033[0m %s\n" "$1"
}

log_error() {
printf "\033[0;31m[ERROR]\033[0m %s\n" "$1" >&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 "$@"
Loading