#!/bin/bash # Smart dependency installer for Turmli Bar Calendar # Automatically handles compilation failures and falls back to compatible versions set -e # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Print functions print_error() { echo -e "${RED}❌ $1${NC}" } print_success() { echo -e "${GREEN}✅ $1${NC}" } print_info() { echo -e "${BLUE}ℹ️ $1${NC}" } print_warning() { echo -e "${YELLOW}⚠️ $1${NC}" } # Detect system architecture ARCH=$(uname -m) OS=$(uname -s) print_info "System detected: ${OS} ${ARCH}" # Check if we have compilation tools check_compiler() { if command -v gcc &> /dev/null; then return 0 else return 1 fi } # Create requirements file based on capabilities create_requirements() { local req_file=$1 local use_minimal=$2 if [ "$use_minimal" = "true" ]; then print_info "Creating minimal requirements (no compilation needed)..." cat > "$req_file" << 'EOF' # Minimal requirements - no compilation needed # Uses older but stable versions with pre-built wheels fastapi==0.95.2 uvicorn==0.22.0 httpx==0.24.1 icalendar==5.0.7 jinja2==3.1.2 apscheduler==3.10.1 pytz==2023.3 python-multipart==0.0.6 pydantic==1.10.9 EOF else print_info "Creating standard requirements..." cat > "$req_file" << 'EOF' # Standard requirements fastapi>=0.104.0 uvicorn[standard]>=0.24.0 httpx>=0.25.0 icalendar>=5.0.0 jinja2>=3.1.0 python-multipart>=0.0.6 apscheduler>=3.10.0 pytz>=2023.3 EOF fi } # Try to install with pre-built wheels only try_wheels_only() { print_info "Attempting to install from pre-built wheels only..." pip install --no-cache-dir --only-binary :all: -r requirements.txt 2>/dev/null return $? } # Try standard installation try_standard_install() { print_info "Attempting standard installation..." pip install --no-cache-dir -r requirements.txt return $? } # Main installation logic main() { # Check Python version PYTHON_VERSION=$(python3 --version 2>&1 | grep -Po '(?<=Python )\d+\.\d+') print_info "Python version: ${PYTHON_VERSION}" # Upgrade pip first print_info "Upgrading pip..." pip install --upgrade pip # Check if we're on ARM without build tools if [[ "$ARCH" == "arm"* ]] || [[ "$ARCH" == "aarch64" ]]; then print_warning "ARM architecture detected" if ! check_compiler; then print_warning "No compiler found, using minimal dependencies" create_requirements "requirements.txt" "true" if try_standard_install; then print_success "Successfully installed minimal dependencies!" exit 0 else print_error "Installation failed even with minimal dependencies" exit 1 fi fi fi # Try wheels-only first (fastest, no compilation) print_info "Trying to install from pre-built wheels..." if pip install --no-cache-dir --only-binary :all: \ fastapi==0.95.2 \ uvicorn==0.22.0 \ httpx==0.24.1 \ icalendar==5.0.7 \ jinja2==3.1.2 \ apscheduler==3.10.1 \ pytz==2023.3 \ python-multipart==0.0.6 \ pydantic==1.10.9 2>/dev/null; then print_success "Successfully installed from pre-built wheels!" exit 0 fi print_warning "Wheels-only installation failed, trying with compilation..." # Create standard requirements create_requirements "requirements.txt" "false" # Try standard installation if try_standard_install; then print_success "Successfully installed standard dependencies!" exit 0 fi print_warning "Standard installation failed, falling back to minimal..." # Fall back to minimal requirements create_requirements "requirements.txt" "true" if try_standard_install; then print_success "Successfully installed minimal dependencies!" exit 0 fi print_error "All installation attempts failed!" print_info "Manual intervention required. Try:" echo " 1. Install build tools: apt-get install gcc python3-dev" echo " 2. Or use Docker/Podman with pre-built image" exit 1 } # Run main function main