#!/bin/bash # Configuration Variables SERVER_URL=${SERVER_URL:-"https://cli.ghaymah.systems"} CLI_NAME="gy" GHAYMAH_DIR="ghaymah" BIN_DIR="bin" # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[0;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Utility functions log_info() { echo -e "${BLUE}$1${NC}" } log_success() { echo -e "${GREEN}$1${NC}" } log_warning() { echo -e "${YELLOW}$1${NC}" } log_error() { echo -e "${RED}$1${NC}" >&2 } # Detect OS and architecture detect_platform() { local os=$(uname -s | tr '[:upper:]' '[:lower:]') local arch=$(uname -m) case "$os" in linux*) PLATFORM="linux" ;; darwin*) PLATFORM="darwin" ;; *) log_error "Unsupported operating system: $os" return 1 ;; esac case "$arch" in x86_64|amd64) ARCH="amd64" ;; arm64|aarch64) ARCH="arm64" ;; i386|i686) ARCH="386" ;; *) log_error "Unsupported architecture: $arch" return 1 ;; esac BINARY_NAME="${CLI_NAME}-${PLATFORM}-${ARCH}" log_info "Detected platform: ${PLATFORM}-${ARCH}" return 0 } # Check prerequisites check_prerequisites() { log_info "Checking prerequisites..." local missing_deps=() for cmd in curl chmod mkdir; do if ! command -v "$cmd" &> /dev/null; then missing_deps+=("$cmd") fi done if [ ${#missing_deps[@]} -ne 0 ]; then log_error "Missing required dependencies: ${missing_deps[*]}" log_error "Please install the missing dependencies and try again" return 1 fi return 0 } # Create installation directory create_install_dir() { local home_dir=$(get_home_dir) local install_dir="$home_dir/$GHAYMAH_DIR/$BIN_DIR" log_info "Creating installation directory: $install_dir" if ! mkdir -p "$install_dir"; then log_error "Failed to create installation directory" return 1 fi INSTALL_DIR="$install_dir" return 0 } # Get home directory get_home_dir() { if [ -n "$HOME" ]; then echo "$HOME" else # Fallback to ~ expansion echo ~ fi } # Download binary download_binary() { local binary_url="$SERVER_URL/$BINARY_NAME" local output_path="$INSTALL_DIR/$CLI_NAME" log_info "Downloading $CLI_NAME from $binary_url" # Create temp file for download local temp_file=$(mktemp) if ! curl -sSL --fail --connect-timeout 30 --max-time 300 "$binary_url" -o "$temp_file"; then log_error "Failed to download binary from $binary_url" rm -f "$temp_file" return 1 fi # Make executable chmod +x "$temp_file" # Move to final location if ! mv "$temp_file" "$output_path"; then log_error "Failed to move binary to installation directory" rm -f "$temp_file" return 1 fi log_success "Binary downloaded successfully to $output_path" return 0 } # Setup PATH in shell config files setup_path() { local install_dir="$INSTALL_DIR" # Check if already in PATH if echo "$PATH" | grep -q "$install_dir"; then log_info "PATH already contains $install_dir" return 0 fi local home_dir=$(get_home_dir) # Add to common shell config files local shell_configs=( "$home_dir/.zshrc" "$home_dir/.bashrc" "$home_dir/.bash_profile" ) local path_line="export PATH=\"$install_dir:\$PATH\"" for config in "${shell_configs[@]}"; do add_path_to_file "$config" "$path_line" "$install_dir" done # Handle fish shell local fish_config="$home_dir/.config/fish/config.fish" if [ -d "$(dirname "$fish_config")" ]; then local fish_line="fish_add_path $install_dir" add_path_to_file "$fish_config" "$fish_line" "$install_dir" fi log_success "Added $install_dir to PATH in shell configuration files" log_info "Please restart your shell or run 'source ~/.bashrc' (or equivalent) to update your PATH" return 0 } # Add PATH to shell config file add_path_to_file() { local config_file="$1" local path_line="$2" local install_dir="$3" # Create file if it doesn't exist if [ ! -f "$config_file" ]; then touch "$config_file" 2>/dev/null || return 0 fi # Check if file exists and is writable if [ ! -w "$config_file" ]; then return 0 fi # Check if already contains our path if grep -q "$install_dir" "$config_file" 2>/dev/null; then return 0 # Already added fi # Append to file echo "" >> "$config_file" echo "$path_line" >> "$config_file" echo "" >> "$config_file" } # Update existing installation update_installation() { local home_dir=$(get_home_dir) local binary_path="$home_dir/$GHAYMAH_DIR/$BIN_DIR/$CLI_NAME" # Check if binary exists if [ ! -f "$binary_path" ]; then log_info "No existing installation found, performing fresh install" return 1 fi log_info "Updating existing installation at $binary_path" # Get original file permissions local original_perms=$(stat -c "%a" "$binary_path" 2>/dev/null || stat -f "%OLp" "$binary_path" 2>/dev/null || echo "755") # Create backup local backup_path="${binary_path}.backup" if ! cp "$binary_path" "$backup_path"; then log_error "Failed to create backup" return 1 fi # Download new binary to temp file local temp_file=$(mktemp) local binary_url="$SERVER_URL/$BINARY_NAME" if ! curl -sSL --fail --connect-timeout 30 --max-time 300 "$binary_url" -o "$temp_file"; then log_error "Failed to download update from $binary_url" rm -f "$temp_file" "$backup_path" return 1 fi # Make executable with original permissions chmod "$original_perms" "$temp_file" # Replace current binary if ! mv "$temp_file" "$binary_path"; then log_error "Failed to replace binary, restoring backup" mv "$backup_path" "$binary_path" rm -f "$temp_file" return 1 fi # Clean up backup rm -f "$backup_path" log_success "Successfully updated $CLI_NAME" return 0 } # Main installation process main() { # Parse arguments local update_mode=false while [[ $# -gt 0 ]]; do case $1 in --update|-u) update_mode=true shift ;; --help|-h) echo "Usage: $0 [OPTIONS]" echo "Options:" echo " -u, --update Update existing installation" echo " -h, --help Show this help message" exit 0 ;; *) log_error "Unknown option: $1" log_error "Use -h or --help for usage information" exit 1 ;; esac done # Detect platform if ! detect_platform; then exit 1 fi # Verify prerequisites if ! check_prerequisites; then exit 1 fi # Handle update mode if [ "$update_mode" = true ]; then if update_installation; then exit 0 fi # If update fails (no existing install), fall through to fresh install fi # Create installation directory if ! create_install_dir; then exit 1 fi # Download binary if ! download_binary; then exit 1 fi # Setup PATH if ! setup_path; then log_warning "Failed to setup PATH automatically" log_info "Please manually add $INSTALL_DIR to your PATH" fi log_success "Installation completed successfully!" log_info "Binary installed to: $INSTALL_DIR/$CLI_NAME" log_info "Please restart your shell or run 'source ~/.bashrc' (or equivalent) to update your PATH" } # Run main function main "$@"