#!/bin/sh # RF-Swift Enhanced Installer Script # Usage: curl -fsSL "https://get.rfswift.io/" | sh # or: wget -qO- "https://get.rfswift.io/" | sh set -e # Configuration GITHUB_REPO="PentHertz/RF-Swift" # Color codes for better readability RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[0;33m' BLUE='\033[0;34m' MAGENTA='\033[0;35m' CYAN='\033[0;36m' NC='\033[0m' # No Color # Function to output colored text color_echo() { local color=$1 local text=$2 case $color in "red") printf "${RED}%s${NC}\n" "${text}" ;; "green") printf "${GREEN}%s${NC}\n" "${text}" ;; "yellow") printf "${YELLOW}%s${NC}\n" "${text}" ;; "blue") printf "${BLUE}%s${NC}\n" "${text}" ;; "magenta") printf "${MAGENTA}%s${NC}\n" "${text}" ;; "cyan") printf "${CYAN}%s${NC}\n" "${text}" ;; *) printf "%s\n" "${text}" ;; esac } # Enhanced Arch Linux detection function is_arch_linux() { # Primary check: /etc/arch-release file if [ -f /etc/arch-release ]; then return 0 fi # Secondary check: /etc/os-release contains Arch if [ -f /etc/os-release ] && grep -qi "arch" /etc/os-release; then return 0 fi # Tertiary check: pacman command exists and /etc/pacman.conf exists if command_exists pacman && [ -f /etc/pacman.conf ]; then return 0 fi # Quaternary check: uname contains arch if uname -a | grep -qi "arch"; then return 0 fi return 1 } # Enhanced Steam Deck detection is_steam_deck() { # Check for Steam Deck specific indicators if [ -f /etc/steamos-release ]; then return 0 fi # Check for Steam Deck hardware identifiers if [ -f /sys/devices/virtual/dmi/id/product_name ] && grep -q "Steam Deck" /sys/devices/virtual/dmi/id/product_name 2>/dev/null; then return 0 fi # Check for deck user if [ "$(whoami)" = "deck" ] || [ "$USER" = "deck" ]; then return 0 fi # Check for Steam Deck specific mount points if [ -d /home/deck ] && [ -f /usr/bin/steamos-readonly ]; then return 0 fi return 1 } # Enhanced Linux distribution detection detect_distro() { # Enhanced Arch Linux detection first if is_arch_linux; then echo "arch" return 0 fi # Check for other distributions if [ -f /etc/fedora-release ]; then echo "fedora" elif [ -f /etc/redhat-release ]; then if grep -q "CentOS" /etc/redhat-release; then echo "centos" else echo "rhel" fi elif [ -f /etc/debian_version ]; then if grep -q "Ubuntu" /etc/os-release 2>/dev/null; then echo "ubuntu" else echo "debian" fi elif [ -f /etc/gentoo-release ]; then echo "gentoo" elif [ -f /etc/alpine-release ]; then echo "alpine" elif [ -f /etc/opensuse-release ] || [ -f /etc/SUSE-brand ]; then echo "opensuse" else echo "unknown" fi } # Enhanced package manager detection get_package_manager() { # Prioritize Arch Linux package manager if is_arch_linux && command_exists pacman; then echo "pacman" return 0 fi # Check for other package managers if command_exists dnf; then echo "dnf" elif command_exists yum; then echo "yum" elif command_exists apt; then echo "apt" elif command_exists zypper; then echo "zypper" elif command_exists apk; then echo "apk" elif command_exists emerge; then echo "emerge" else echo "unknown" fi } # Check if PipeWire is running is_pipewire_running() { if command_exists pgrep; then pgrep -x pipewire >/dev/null 2>&1 && return 0 fi # Check for PipeWire socket USER_ID=$(id -u 2>/dev/null || echo "1000") if [ -S "/run/user/${USER_ID}/pipewire-0" ]; then return 0 fi return 1 } # Check if PulseAudio is running is_pulseaudio_running() { if command_exists pulseaudio; then pulseaudio --check >/dev/null 2>&1 else return 1 fi } # Detect current audio system detect_audio_system() { if is_pipewire_running; then echo "pipewire" elif is_pulseaudio_running; then echo "pulseaudio" else echo "none" fi } # Check if we should prefer PipeWire for this distribution should_prefer_pipewire() { local distro="$1" case "$distro" in "arch") # Arch Linux: PipeWire is modern and well-supported return 0 ;; "fedora") # PipeWire is default since Fedora 34 return 0 ;; "ubuntu"|"debian") # Available in modern versions return 0 ;; "opensuse") # OpenSUSE has good PipeWire support return 0 ;; "rhel"|"centos") # Check if dnf is available (RHEL 8+) command_exists dnf ;; *) return 1 ;; esac } # Enhanced PipeWire installation with Arch Linux optimization install_pipewire() { local distro="$1" color_echo "blue" "đ Installing PipeWire audio system..." case "$distro" in "arch") if have_sudo_access; then color_echo "blue" "đĻ Using pacman to install PipeWire on Arch Linux..." # Update package database first sudo pacman -Sy --noconfirm # Install PipeWire and related packages sudo pacman -S --noconfirm --needed pipewire pipewire-pulse pipewire-alsa pipewire-jack wireplumber # Optional: install additional tools sudo pacman -S --noconfirm --needed pipewire-audio pipewire-media-session || true else color_echo "red" "sudo access required for package installation" return 1 fi ;; "fedora") if have_sudo_access; then sudo dnf install -y pipewire pipewire-pulseaudio pipewire-alsa pipewire-jack-audio-connection-kit wireplumber else color_echo "red" "sudo access required for package installation" return 1 fi ;; "rhel"|"centos") if command_exists dnf; then if have_sudo_access; then sudo dnf install -y pipewire pipewire-pulseaudio pipewire-alsa wireplumber else color_echo "red" "sudo access required for package installation" return 1 fi else color_echo "yellow" "âšī¸ PipeWire not available on RHEL/CentOS 7, installing PulseAudio instead" return install_pulseaudio "$distro" fi ;; "debian"|"ubuntu") if have_sudo_access; then sudo apt update sudo apt install -y pipewire pipewire-pulse pipewire-alsa wireplumber else color_echo "red" "sudo access required for package installation" return 1 fi ;; "opensuse") if have_sudo_access; then sudo zypper install -y pipewire pipewire-pulseaudio pipewire-alsa wireplumber else color_echo "red" "sudo access required for package installation" return 1 fi ;; *) color_echo "red" "â Unsupported distribution for PipeWire installation" return 1 ;; esac # Enable PipeWire services color_echo "blue" "đ§ Enabling PipeWire services..." if command_exists systemctl; then systemctl --user enable pipewire.service pipewire-pulse.service 2>/dev/null || true systemctl --user enable wireplumber.service 2>/dev/null || true fi return 0 } # Enhanced PulseAudio installation with Arch Linux optimization install_pulseaudio() { local distro="$1" color_echo "blue" "đ Installing PulseAudio audio system..." case "$distro" in "arch") if have_sudo_access; then color_echo "blue" "đĻ Using pacman to install PulseAudio on Arch Linux..." # Update package database first sudo pacman -Sy --noconfirm # Install PulseAudio and related packages sudo pacman -S --noconfirm --needed pulseaudio pulseaudio-alsa alsa-utils # Optional: install additional tools sudo pacman -S --noconfirm --needed pulseaudio-bluetooth pavucontrol || true else color_echo "red" "sudo access required for package installation" return 1 fi ;; "fedora") if have_sudo_access; then sudo dnf install -y pulseaudio pulseaudio-utils alsa-utils else color_echo "red" "sudo access required for package installation" return 1 fi ;; "rhel"|"centos") if have_sudo_access; then if command_exists dnf; then sudo dnf install -y pulseaudio pulseaudio-utils alsa-utils else sudo yum install -y epel-release sudo yum install -y pulseaudio pulseaudio-utils alsa-utils fi else color_echo "red" "sudo access required for package installation" return 1 fi ;; "debian"|"ubuntu") if have_sudo_access; then sudo apt update sudo apt install -y pulseaudio pulseaudio-utils alsa-utils else color_echo "red" "sudo access required for package installation" return 1 fi ;; "opensuse") if have_sudo_access; then sudo zypper install -y pulseaudio pulseaudio-utils alsa-utils else color_echo "red" "sudo access required for package installation" return 1 fi ;; *) color_echo "red" "â Unsupported distribution for PulseAudio installation" return 1 ;; esac return 0 } # Start PipeWire start_pipewire() { color_echo "blue" "đĩ Starting PipeWire..." # Try systemd user services first if command_exists systemctl; then if systemctl --user start pipewire.service pipewire-pulse.service 2>/dev/null; then systemctl --user start wireplumber.service 2>/dev/null || true color_echo "green" "đ§ PipeWire started via systemd services" return 0 fi fi # Fallback to direct execution if command_exists pipewire && command_exists pipewire-pulse; then pipewire >/dev/null 2>&1 & pipewire-pulse >/dev/null 2>&1 & if command_exists wireplumber; then wireplumber >/dev/null 2>&1 & fi sleep 2 color_echo "green" "đ§ PipeWire started directly" return 0 fi color_echo "yellow" "â ī¸ Could not start PipeWire" return 1 } # Start PulseAudio start_pulseaudio() { color_echo "blue" "đĩ Starting PulseAudio..." if command_exists pulseaudio; then if ! pulseaudio --check >/dev/null 2>&1; then pulseaudio --start >/dev/null 2>&1 fi color_echo "green" "đ§ PulseAudio is running" return 0 fi color_echo "yellow" "â ī¸ Could not start PulseAudio" return 1 } # Enhanced audio system check with better Arch Linux support check_audio_system() { color_echo "blue" "đ Checking audio system..." # Skip audio setup on macOS case "$(uname -s)" in Darwin*) color_echo "yellow" "đ macOS detected. Audio system management is handled by the system" return 0 ;; esac # Detect Linux distribution and current audio system local distro=$(detect_distro) local current_audio=$(detect_audio_system) color_echo "blue" "đ§ Detected distribution: $distro" # Special message for Arch Linux if [ "$distro" = "arch" ]; then color_echo "cyan" "đī¸ Arch Linux detected - using optimized package management with pacman" fi # Check current audio system status case "$current_audio" in "pipewire") color_echo "green" "â PipeWire is already running" return 0 ;; "pulseaudio") color_echo "green" "â PulseAudio is already running" return 0 ;; "none") color_echo "yellow" "â ī¸ No audio system detected" ;; esac # Ask user if they want to install audio system if ! prompt_yes_no "Would you like to install an audio system for RF-Swift?" "y"; then color_echo "yellow" "â ī¸ Audio system installation skipped" return 0 fi # Determine which audio system to install if should_prefer_pipewire "$distro"; then color_echo "blue" "đ¯ PipeWire is recommended for $distro" # Check if PipeWire is available if command_exists pipewire || command_exists pw-cli; then color_echo "green" "â PipeWire is already installed" start_pipewire else color_echo "blue" "đĻ Installing PipeWire..." if install_pipewire "$distro"; then color_echo "green" "â PipeWire installed successfully" start_pipewire else color_echo "red" "â Failed to install PipeWire, falling back to PulseAudio" if install_pulseaudio "$distro"; then start_pulseaudio fi fi fi else color_echo "blue" "đ¯ PulseAudio is recommended for $distro" # Check if PulseAudio is available if command_exists pulseaudio; then color_echo "green" "â PulseAudio is already installed" start_pulseaudio else color_echo "blue" "đĻ Installing PulseAudio..." if install_pulseaudio "$distro"; then color_echo "green" "â PulseAudio installed successfully" start_pulseaudio else color_echo "red" "â Failed to install PulseAudio" return 1 fi fi fi return 0 } # Display audio system status show_audio_status() { color_echo "blue" "đĩ Audio System Status" echo "==================================" local current_audio=$(detect_audio_system) case "$current_audio" in "pipewire") color_echo "green" "â PipeWire is running" if command_exists pw-cli; then color_echo "blue" "âšī¸ PipeWire info:" pw-cli info 2>/dev/null | head -5 || echo "Unable to get detailed info" fi ;; "pulseaudio") color_echo "green" "â PulseAudio is running" if command_exists pactl; then color_echo "blue" "âšī¸ PulseAudio info:" pactl info 2>/dev/null | grep -E "(Server|Version)" || echo "Unable to get detailed info" fi ;; "none") color_echo "red" "â No audio system detected" ;; esac echo "==================================" } # Fun welcome message fun_welcome() { color_echo "cyan" "đ WELCOME TO THE RF-Swift Enhanced Installer! đ" color_echo "yellow" "Prepare yourself for an epic journey in the world of radio frequencies! đĄ" # Show system information local distro=$(detect_distro) local pkg_mgr=$(get_package_manager) color_echo "blue" "đĨī¸ System Information:" color_echo "blue" " OS: $(uname -s)" color_echo "blue" " Architecture: $(uname -m)" color_echo "blue" " Distribution: $distro" color_echo "blue" " Package Manager: $pkg_mgr" if is_steam_deck; then color_echo "magenta" "đŽ Steam Deck detected!" fi } # Fun thank you message after installation thank_you_message() { color_echo "green" "đ You did it! RF-Swift is now ready for action! đ" color_echo "magenta" "Thank you for installing. You've just taken the first step towards RF mastery! đ§" } # Function to check if a command exists command_exists() { command -v "$1" >/dev/null 2>&1 } # Function to check if we have sudo privileges have_sudo_access() { if command_exists sudo; then sudo -v >/dev/null 2>&1 return $? fi return 1 } # Function to get the current user even when run with sudo get_real_user() { if [ -n "$SUDO_USER" ]; then echo "$SUDO_USER" else whoami fi } # Function to prompt user for yes/no with terminal redirection solution prompt_yes_no() { local prompt="$1" local default="$2" # Optional default (y/n) local response # Try to use /dev/tty for interactive input even in pipe scenarios if [ -t 0 ]; then tty_device="/dev/stdin" elif [ -e "/dev/tty" ]; then tty_device="/dev/tty" else # No interactive terminal available, use defaults if [ "$default" = "n" ]; then echo "${YELLOW}${prompt} (y/n): Defaulting to no (no terminal available)${NC}" return 1 else echo "${YELLOW}${prompt} (y/n): Defaulting to yes (no terminal available)${NC}" return 0 fi fi # Try to read from the terminal while true; do printf "${YELLOW}%s (y/n): ${NC}" "${prompt}" if read -r response < "$tty_device" 2>/dev/null; then case "$response" in [Yy]* ) return 0 ;; [Nn]* ) return 1 ;; * ) echo "Please answer yes (y) or no (n)." ;; esac else # Failed to read from terminal, use default if [ "$default" = "n" ]; then echo "${YELLOW}${prompt} (y/n): Defaulting to no (couldn't read from terminal)${NC}" return 1 else echo "${YELLOW}${prompt} (y/n): Defaulting to yes (couldn't read from terminal)${NC}" return 0 fi fi done } # Function to create an alias for RF-Swift in the user's shell configuration create_alias() { local bin_path="$1" color_echo "blue" "đ Setting up an alias for RF-Swift..." # Get the real user even when run with sudo REAL_USER=$(get_real_user) USER_HOME=$(eval echo ~${REAL_USER}) # Determine shell from the user's default shell USER_SHELL=$(getent passwd "${REAL_USER}" 2>/dev/null | cut -d: -f7 | xargs basename 2>/dev/null) if [ -z "${USER_SHELL}" ]; then USER_SHELL=$(basename "${SHELL}") fi SHELL_RC="" ALIAS_LINE="alias rfswift='${bin_path}/rfswift'" # Determine the correct shell configuration file case "${USER_SHELL}" in bash) # Check for .bash_profile first (macOS preference), then .bashrc (Linux preference) if [ -f "${USER_HOME}/.bash_profile" ]; then SHELL_RC="${USER_HOME}/.bash_profile" elif [ -f "${USER_HOME}/.bashrc" ]; then SHELL_RC="${USER_HOME}/.bashrc" else # Default to .bashrc if neither exists SHELL_RC="${USER_HOME}/.bashrc" fi ;; zsh) SHELL_RC="${USER_HOME}/.zshrc" ;; fish) SHELL_RC="${USER_HOME}/.config/fish/config.fish" ALIAS_LINE="alias rfswift '${bin_path}/rfswift'" # fish has different syntax ;; *) color_echo "yellow" "â ī¸ Unsupported shell ${USER_SHELL}. Please manually add an alias for rfswift." return 1 ;; esac # Create the configuration file if it doesn't exist if [ ! -f "${SHELL_RC}" ]; then if [ "${USER_SHELL}" = "fish" ]; then # For fish, ensure config directory exists mkdir -p "$(dirname "${SHELL_RC}")" fi touch "${SHELL_RC}" if [ $? -ne 0 ]; then color_echo "yellow" "â ī¸ Unable to create ${SHELL_RC}. Please manually add the alias." return 1 fi fi # Check if alias already exists if grep -q "alias rfswift" "${SHELL_RC}" 2>/dev/null; then color_echo "yellow" "An existing rfswift alias was found in ${SHELL_RC}" if prompt_yes_no "Do you want to replace the existing alias?" "y"; then # Remove the existing alias line(s) if [ "${USER_SHELL}" = "fish" ]; then sed -i.bak '/alias rfswift /d' "${SHELL_RC}" 2>/dev/null || sed -i '' '/alias rfswift /d' "${SHELL_RC}" 2>/dev/null else sed -i.bak '/alias rfswift=/d' "${SHELL_RC}" 2>/dev/null || sed -i '' '/alias rfswift=/d' "${SHELL_RC}" 2>/dev/null fi # Add the new alias if echo "${ALIAS_LINE}" >> "${SHELL_RC}"; then color_echo "green" "â Updated RF-Swift alias in ${SHELL_RC}" color_echo "yellow" "⥠To use the alias immediately, run: source ${SHELL_RC}" return 0 else color_echo "yellow" "â ī¸ Failed to update alias in ${SHELL_RC}. Please manually update the alias." color_echo "blue" "đĄ Run this command to add it manually: echo '${ALIAS_LINE}' >> ${SHELL_RC}" return 1 fi else color_echo "blue" "Keeping existing alias." return 0 fi fi # Add the alias if it doesn't exist if echo "${ALIAS_LINE}" >> "${SHELL_RC}"; then color_echo "green" "â Added RF-Swift alias to ${SHELL_RC}" color_echo "yellow" "⥠To use the alias immediately, run: source ${SHELL_RC}" return 0 else color_echo "yellow" "â ī¸ Failed to add alias to ${SHELL_RC}. Please manually add the alias." color_echo "blue" "đĄ Run this command to add it manually: echo '${ALIAS_LINE}' >> ${SHELL_RC}" return 1 fi } # Enhanced Steam Deck Docker installation with Arch Linux optimization install_docker_steamdeck() { color_echo "yellow" "đŽ Installing Docker on Steam Deck using Arch Linux methods..." if ! have_sudo_access; then color_echo "red" "đ¨ Steam Deck Docker installation requires sudo privileges." return 1 fi # Installation steps for Docker on Steam Deck (Arch Linux based) color_echo "blue" "đŽ Disabling read-only mode on Steam Deck" sudo steamos-readonly disable color_echo "blue" "đ Initializing pacman keyring" sudo pacman-key --init sudo pacman-key --populate archlinux sudo pacman-key --populate holo color_echo "blue" "đŗ Installing Docker using pacman" sudo pacman -Syu --noconfirm docker docker-compose # Install Docker Compose for Steam Deck install_docker_compose_steamdeck # Add user to docker group if command_exists sudo && command_exists groups; then current_user=$(get_real_user) if ! groups "$current_user" | grep -q docker; then color_echo "blue" "đ§ Adding '$current_user' to Docker group..." sudo usermod -aG docker "$current_user" color_echo "yellow" "⥠You may need to log out and log back in for this to take effect." fi fi # Start Docker service if command_exists systemctl; then color_echo "blue" "đ Starting Docker service..." sudo systemctl start docker sudo systemctl enable docker fi color_echo "green" "đ Docker installed successfully on Steam Deck using Arch Linux methods!" return 0 } # Install Docker Compose for Steam Deck install_docker_compose_steamdeck() { color_echo "blue" "đ§Š Installing Docker Compose v2 plugin for Steam Deck" DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker} mkdir -p "$DOCKER_CONFIG/cli-plugins" # Download Docker Compose for x86_64 (Steam Deck architecture) color_echo "blue" "đĨ Downloading Docker Compose..." curl -SL https://github.com/docker/compose/releases/download/v2.36.0/docker-compose-linux-x86_64 -o "$DOCKER_CONFIG/cli-plugins/docker-compose" chmod +x "$DOCKER_CONFIG/cli-plugins/docker-compose" color_echo "green" "â Docker Compose v2 installed successfully for Steam Deck" } # Enhanced Docker check with Arch Linux optimization check_docker() { color_echo "blue" "đ Checking if Docker is installed..." if command_exists docker; then color_echo "green" "â Docker is already installed. You're all set for RF-Swift!" return 0 fi color_echo "yellow" "â ī¸ Docker is not installed on your system." color_echo "blue" "âšī¸ Docker is required for RF-Swift to work properly." # Provide advice on running Docker with reduced privileges color_echo "cyan" "đ Docker Security Advice:" color_echo "cyan" " - Consider using Docker Desktop which provides a user-friendly interface" color_echo "cyan" " - On Linux, add your user to the 'docker' group to avoid using sudo with each Docker command" color_echo "cyan" " - Use rootless Docker mode if you need enhanced security" color_echo "cyan" " - Always pull container images from trusted sources" # Check if this is a Steam Deck and offer Steam Deck specific installation if [ "$(uname -s)" = "Linux" ]; then if is_steam_deck; then color_echo "magenta" "đŽ Steam Deck detected!" if prompt_yes_no "Would you like to install Docker using Steam Deck optimized method?" "y"; then install_docker_steamdeck return $? fi else if prompt_yes_no "Are you installing on a Steam Deck?" "n"; then install_docker_steamdeck return $? fi fi fi # Ask if the user wants to install Docker using standard method if prompt_yes_no "Would you like to install Docker now?" "n"; then install_docker return $? else color_echo "yellow" "â ī¸ Docker installation skipped. You'll need to install Docker manually before using RF-Swift." return 1 fi } # Enhanced Docker installation with Arch Linux support install_docker() { case "$(uname -s)" in Darwin*) if command_exists brew; then color_echo "blue" "đ Installing Docker via Homebrew..." brew install --cask docker color_echo "blue" "đ Launching Docker Desktop now... Hold tight!" open -a Docker color_echo "yellow" "âŗ Give it a moment, Docker is warming up!" i=1 while [ $i -le 30 ]; do if command_exists docker && docker info >/dev/null 2>&1; then color_echo "green" "â Docker is up and running!" return 0 fi sleep 2 i=$((i + 1)) done color_echo "yellow" "Docker is installed but still starting. Please open Docker manually if needed." else color_echo "red" "đ¨ Homebrew is not installed! Please install Homebrew first:" color_echo "yellow" '/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"' color_echo "yellow" "Then, run the script again!" return 1 fi ;; Linux*) color_echo "blue" "đ§ Installing Docker on your Linux machine..." # Enhanced Arch Linux Docker installation if is_arch_linux; then color_echo "cyan" "đī¸ Arch Linux detected - using pacman for Docker installation" if ! have_sudo_access; then color_echo "red" "đ¨ Unable to obtain sudo privileges. Docker installation requires sudo." return 1 fi color_echo "blue" "đĻ Installing Docker using pacman..." sudo pacman -Sy --noconfirm sudo pacman -S --noconfirm --needed docker docker-compose # Enable and start Docker service if command_exists systemctl; then color_echo "blue" "đ Enabling and starting Docker service..." sudo systemctl enable docker sudo systemctl start docker fi # Add user to docker group current_user=$(get_real_user) if ! groups "$current_user" 2>/dev/null | grep -q docker; then color_echo "blue" "đ§ Adding '$current_user' to Docker group..." sudo usermod -aG docker "$current_user" color_echo "yellow" "⥠You may need to log out and log back in for Docker group changes to take effect." fi color_echo "green" "đ Docker installed successfully using pacman!" return 0 else # Standard Docker installation for other distributions color_echo "yellow" "â ī¸ This will require sudo privileges to install Docker." if ! have_sudo_access; then color_echo "red" "đ¨ Unable to obtain sudo privileges. Docker installation requires sudo." return 1 fi color_echo "blue" "Using sudo to install Docker..." if command_exists curl; then curl -fsSL "https://get.docker.com/" | sudo sh elif command_exists wget; then wget -qO- "https://get.docker.com/" | sudo sh else color_echo "red" "đ¨ Missing curl/wget. Please install one of them." return 1 fi if command_exists sudo && command_exists groups; then current_user=$(get_real_user) if ! groups "$current_user" 2>/dev/null | grep -q docker; then color_echo "blue" "đ§ Adding you to the Docker group..." sudo usermod -aG docker "$current_user" color_echo "yellow" "⥠You may need to log out and log back in for this to take effect." fi fi if command_exists systemctl; then color_echo "blue" "đ Starting Docker service..." sudo systemctl start docker sudo systemctl enable docker fi color_echo "green" "đ Docker is now installed and running!" fi ;; *) color_echo "red" "đ¨ Unsupported OS detected: $(uname -s). Docker can't be installed automatically here." return 1 ;; esac } # Function to get the latest release information get_latest_release() { color_echo "blue" "đ Detecting the latest RF-Swift release..." # Default version as fallback DEFAULT_VERSION="0.6.3" VERSION="${DEFAULT_VERSION}" # Initialize with default # First try: Use GitHub API with a proper User-Agent to avoid rate limiting issues if command_exists curl; then # First method: direct API call with proper headers to avoid throttling LATEST_INFO=$(curl -s -H "User-Agent: RF-Swift-Installer" "https://api.github.com/repos/${GITHUB_REPO}/releases/latest") # Check if we got a proper response if echo "${LATEST_INFO}" | grep -q "tag_name"; then # Extract version, handle both with and without "v" prefix DETECTED_VERSION=$(echo "${LATEST_INFO}" | grep -o '"tag_name": *"[^"]*"' | sed 's/.*: *"v\{0,1\}\([^"]*\)".*/\1/') if [ -n "${DETECTED_VERSION}" ]; then VERSION="${DETECTED_VERSION}" color_echo "green" "â Successfully retrieved latest version using GitHub API" fi else color_echo "yellow" "GitHub API query didn't return expected results. Trying alternative method..." fi fi # Second try: Parse the releases page directly if API method failed if [ "${VERSION}" = "${DEFAULT_VERSION}" ] && command_exists curl; then color_echo "blue" "Trying direct HTML parsing method..." RELEASES_PAGE=$(curl -s -L -H "User-Agent: RF-Swift-Installer" "https://github.com/${GITHUB_REPO}/releases/latest") # Look for version in the page title and URL DETECTED_VERSION=$(echo "${RELEASES_PAGE}" | grep -o "${GITHUB_REPO}/releases/tag/v[0-9][0-9.]*" | head -1 | sed 's/.*tag\/v//') if [ -n "${DETECTED_VERSION}" ]; then VERSION="${DETECTED_VERSION}" color_echo "green" "â Retrieved version ${VERSION} by parsing GitHub releases page" else # One last attempt - look for version in the title DETECTED_VERSION=$(echo "${RELEASES_PAGE}" | grep -o '