#!/bin/bash # ════════════════════════════════════════════════ # ARIA Cockpit — Android Dev Setup # Installiert alle Abhängigkeiten für den Build # und generiert das native Android-Projekt. # Verwendung: ./setup.sh # ════════════════════════════════════════════════ set -e SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" cd "$SCRIPT_DIR" # ── Farben ──────────────────────────────────── RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' CYAN='\033[0;36m' NC='\033[0m' echo -e "${CYAN}╔═══════════════════════════════════════╗${NC}" echo -e "${CYAN}║ ARIA Cockpit — Dev Setup ║${NC}" echo -e "${CYAN}╚═══════════════════════════════════════╝${NC}" echo "" # ── Betriebssystem erkennen ─────────────────── OS="unknown" PKG_INSTALL="" if [ -f /etc/debian_version ]; then OS="debian" PKG_INSTALL="sudo apt install -y" elif [ -f /etc/fedora-release ]; then OS="fedora" PKG_INSTALL="sudo dnf install -y" elif [ -f /etc/arch-release ]; then OS="arch" PKG_INSTALL="sudo pacman -S --noconfirm" elif [[ "$OSTYPE" == "darwin"* ]]; then OS="macos" PKG_INSTALL="brew install" fi echo -e "${CYAN}System: ${OS}${NC}" echo "" # ── Hilfsfunktionen ────────────────────────── installed() { command -v "$1" &> /dev/null } step() { echo "" echo -e "${GREEN}══════════════════════════════════════${NC}" echo -e "${GREEN} $1${NC}" echo -e "${GREEN}══════════════════════════════════════${NC}" } skip() { echo -e " ${GREEN}✓${NC} $1 bereits vorhanden" } install_pkg() { if [ -z "$PKG_INSTALL" ]; then echo -e "${RED} Kann $1 nicht automatisch installieren (unbekanntes OS).${NC}" echo -e "${RED} Bitte manuell installieren: $1${NC}" return 1 fi $PKG_INSTALL "$@" } # ══════════════════════════════════════════════ # 1. Basis-Tools (curl, unzip, git) # ══════════════════════════════════════════════ step "1/7 — Basis-Tools prüfen" NEED_TOOLS=() for TOOL in curl unzip git; do if ! installed "$TOOL"; then NEED_TOOLS+=("$TOOL") else skip "$TOOL" fi done if [ ${#NEED_TOOLS[@]} -gt 0 ]; then echo " Installiere: ${NEED_TOOLS[*]}" install_pkg "${NEED_TOOLS[@]}" fi # ══════════════════════════════════════════════ # 2. Node.js # ══════════════════════════════════════════════ step "2/7 — Node.js prüfen" if installed node; then NODE_VERSION=$(node -v) NODE_MAJOR=$(echo "$NODE_VERSION" | sed 's/v//' | cut -d. -f1) if [ "$NODE_MAJOR" -ge 18 ]; then skip "Node.js $NODE_VERSION" else echo -e "${YELLOW} Node.js $NODE_VERSION ist zu alt (mindestens v18 nötig)${NC}" echo -e "${YELLOW} Bitte Node.js updaten: https://nodejs.org/${NC}" exit 1 fi else echo " Node.js nicht gefunden — installiere..." case "$OS" in debian) curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - sudo apt install -y nodejs ;; fedora) curl -fsSL https://rpm.nodesource.com/setup_22.x | sudo bash - sudo dnf install -y nodejs ;; arch) install_pkg nodejs npm ;; macos) install_pkg node ;; *) echo -e "${RED} Bitte Node.js manuell installieren: https://nodejs.org/${NC}" exit 1 ;; esac echo -e " ${GREEN}✓${NC} Node.js $(node -v) installiert" fi # ══════════════════════════════════════════════ # 3. JDK 17 # ══════════════════════════════════════════════ step "3/7 — Java JDK 17 prüfen" # JDK 17 wird EXAKT benötigt — nicht 21, nicht 22. # Android Gradle Plugin 8.1 + Gradle 8.3 haben Probleme mit JDK 21+ (jlink-Bug). NEED_JDK=false JDK17_HOME="" # Prüfe ob JDK 17 bereits installiert ist (auch wenn JDK 21 der Default ist) for JDK_PATH in \ /usr/lib/jvm/java-17-openjdk-amd64 \ /usr/lib/jvm/temurin-17-jdk-amd64 \ /usr/lib/jvm/java-17-openjdk \ /usr/lib/jvm/jdk-17 \ /usr/lib/jvm/zulu-17 \ /Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home \ /Library/Java/JavaVirtualMachines/openjdk-17.jdk/Contents/Home; do if [ -x "$JDK_PATH/bin/java" ]; then JDK17_HOME="$JDK_PATH" break fi done # Prüfe ob es wirklich der volle JDK ist (nicht nur JRE) — jlink muss existieren if [ -n "$JDK17_HOME" ] && [ ! -x "$JDK17_HOME/bin/jlink" ]; then echo -e " ${YELLOW}JDK 17 gefunden in $JDK17_HOME, aber nur JRE (jlink fehlt)${NC}" echo -e " ${YELLOW}Installiere vollen JDK 17...${NC}" JDK17_HOME="" fi if [ -n "$JDK17_HOME" ]; then skip "JDK 17 (vollständig) in $JDK17_HOME" else echo " JDK 17 nicht gefunden — installiere..." NEED_JDK=true case "$OS" in debian) install_pkg openjdk-17-jdk ;; fedora) install_pkg java-17-openjdk-devel ;; arch) install_pkg jdk17-openjdk ;; macos) install_pkg openjdk@17 ;; *) echo -e "${RED} Bitte JDK 17 manuell installieren${NC}" exit 1 ;; esac # Nochmal suchen nach Installation for JDK_PATH in \ /usr/lib/jvm/java-17-openjdk-amd64 \ /usr/lib/jvm/temurin-17-jdk-amd64 \ /usr/lib/jvm/java-17-openjdk; do if [ -x "$JDK_PATH/bin/java" ]; then JDK17_HOME="$JDK_PATH" break fi done echo -e " ${GREEN}✓${NC} JDK 17 installiert" fi # Hinweis falls JDK 21+ der Default ist if installed java; then CURRENT_JAVA=$(java -version 2>&1 | head -1 | cut -d'"' -f2 | cut -d'.' -f1) if [ "$CURRENT_JAVA" -gt 17 ] 2>/dev/null && [ -n "$JDK17_HOME" ]; then echo -e " ${YELLOW}Hinweis: Standard-Java ist JDK $CURRENT_JAVA, aber Build nutzt JDK 17${NC}" echo -e " ${YELLOW}build.sh setzt JAVA_HOME automatisch auf $JDK17_HOME${NC}" fi fi # ══════════════════════════════════════════════ # 4. Android SDK (Command Line Tools) # ══════════════════════════════════════════════ step "4/7 — Android SDK prüfen" ANDROID_SDK_DIR="${ANDROID_HOME:-${ANDROID_SDK_ROOT:-$HOME/Android/Sdk}}" if [ -d "$ANDROID_SDK_DIR/platforms" ] && [ -d "$ANDROID_SDK_DIR/build-tools" ]; then skip "Android SDK in $ANDROID_SDK_DIR" else echo " Android SDK nicht gefunden — installiere..." echo "" mkdir -p "$ANDROID_SDK_DIR" # Command Line Tools herunterladen CMDLINE_TOOLS_URL="https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip" if [[ "$OSTYPE" == "darwin"* ]]; then CMDLINE_TOOLS_URL="https://dl.google.com/android/repository/commandlinetools-mac-11076708_latest.zip" fi echo " Lade Command Line Tools herunter..." TEMP_ZIP="/tmp/android-cmdline-tools.zip" curl -L -o "$TEMP_ZIP" "$CMDLINE_TOOLS_URL" echo " Entpacke..." mkdir -p "$ANDROID_SDK_DIR/cmdline-tools" unzip -q -o "$TEMP_ZIP" -d "$ANDROID_SDK_DIR/cmdline-tools" mv "$ANDROID_SDK_DIR/cmdline-tools/cmdline-tools" "$ANDROID_SDK_DIR/cmdline-tools/latest" 2>/dev/null || true rm -f "$TEMP_ZIP" SDKMANAGER="$ANDROID_SDK_DIR/cmdline-tools/latest/bin/sdkmanager" echo " Akzeptiere Lizenzen..." yes | "$SDKMANAGER" --licenses > /dev/null 2>&1 || true echo " Installiere SDK Komponenten (dauert ein paar Minuten)..." "$SDKMANAGER" \ "platforms;android-34" \ "build-tools;34.0.0" \ "platform-tools" echo -e " ${GREEN}✓${NC} Android SDK installiert in $ANDROID_SDK_DIR" fi # ── ANDROID_HOME in Shell-Profil setzen ────── export ANDROID_HOME="$ANDROID_SDK_DIR" export ANDROID_SDK_ROOT="$ANDROID_SDK_DIR" export PATH="$ANDROID_HOME/platform-tools:$ANDROID_HOME/cmdline-tools/latest/bin:$PATH" SHELL_PROFILE="" if [ -f "$HOME/.bashrc" ]; then SHELL_PROFILE="$HOME/.bashrc" elif [ -f "$HOME/.zshrc" ]; then SHELL_PROFILE="$HOME/.zshrc" fi if [ -n "$SHELL_PROFILE" ]; then if ! grep -q "ANDROID_HOME" "$SHELL_PROFILE" 2>/dev/null; then echo "" >> "$SHELL_PROFILE" echo "# Android SDK (ARIA Setup)" >> "$SHELL_PROFILE" echo "export ANDROID_HOME=\"$ANDROID_SDK_DIR\"" >> "$SHELL_PROFILE" echo "export ANDROID_SDK_ROOT=\"\$ANDROID_HOME\"" >> "$SHELL_PROFILE" echo 'export PATH="$ANDROID_HOME/platform-tools:$ANDROID_HOME/cmdline-tools/latest/bin:$PATH"' >> "$SHELL_PROFILE" echo -e " ${CYAN}→ ANDROID_HOME in $SHELL_PROFILE eingetragen${NC}" fi fi # ══════════════════════════════════════════════ # 5. Node Dependencies # ══════════════════════════════════════════════ step "5/7 — Node Dependencies & Metro-Config" # Metro-Config-Dateien prüfen/erstellen (nötig für JS-Bundle im Release-Build) if [ ! -f "metro.config.js" ]; then echo " Erstelle metro.config.js..." cat > metro.config.js << 'METROEOF' const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config'); /** * Metro configuration * https://reactnative.dev/docs/metro */ const config = {}; module.exports = mergeConfig(getDefaultConfig(__dirname), config); METROEOF echo -e " ${GREEN}✓${NC} metro.config.js erstellt" else skip "metro.config.js" fi if [ ! -f "babel.config.js" ]; then echo " Erstelle babel.config.js..." cat > babel.config.js << 'BABELEOF' module.exports = { presets: ['module:metro-react-native-babel-preset'], }; BABELEOF echo -e " ${GREEN}✓${NC} babel.config.js erstellt" else skip "babel.config.js" fi if [ ! -f ".watchmanconfig" ]; then echo " Erstelle .watchmanconfig..." echo '{}' > .watchmanconfig echo -e " ${GREEN}✓${NC} .watchmanconfig erstellt" else skip ".watchmanconfig" fi # Alte node_modules aufräumen falls vorhanden (verhindert veraltete/korrupte Pakete) if [ -d "node_modules" ]; then echo " Räume alte node_modules auf..." rm -rf node_modules fi npm install # ══════════════════════════════════════════════ # 6. React Native — natives Android-Projekt # ══════════════════════════════════════════════ step "6/7 — React Native Android-Projekt generieren" if [ -f "android/gradlew" ]; then skip "Natives Android-Projekt (android/gradlew)" else echo " Generiere natives Android-Projekt..." echo " (React Native init in Temp-Verzeichnis → kopiere android/ Ordner)" echo "" TEMP_DIR="/tmp/aria-rn-init-$$" rm -rf "$TEMP_DIR" # React Native Projekt in Temp-Verzeichnis erstellen npx --yes @react-native-community/cli@latest init AriaCockpit \ --directory "$TEMP_DIR" \ --skip-git-init \ --install-pods false \ --version 0.73.4 \ 2>&1 | while IFS= read -r line; do echo " $line"; done if [ -d "$TEMP_DIR/android" ]; then # Natives Android-Verzeichnis kopieren cp -r "$TEMP_DIR/android" ./android/ # App-Name in strings.xml anpassen if [ -f "android/app/src/main/res/values/strings.xml" ]; then sed -i 's/AriaCockpit/ARIA/g' "android/app/src/main/res/values/strings.xml" fi # Gradle Wrapper ausführbar machen chmod +x android/gradlew 2>/dev/null || true echo -e " ${GREEN}✓${NC} Natives Android-Projekt erstellt in android/android/" else echo -e "${RED} Fehler: React Native Init hat kein android/ Verzeichnis erzeugt.${NC}" echo -e "${RED} Temp-Verzeichnis zur Inspektion: $TEMP_DIR${NC}" echo "" echo -e "${YELLOW} Manueller Fallback:${NC}" echo -e "${YELLOW} cd /tmp${NC}" echo -e "${YELLOW} npx @react-native-community/cli@latest init AriaCockpit${NC}" echo -e "${YELLOW} cp -r /tmp/AriaCockpit/android $SCRIPT_DIR/android/${NC}" exit 1 fi # Temp aufräumen rm -rf "$TEMP_DIR" fi # ══════════════════════════════════════════════ # 7. Gradle konfigurieren & Cache aufräumen # ══════════════════════════════════════════════ step "7/7 — Gradle konfigurieren & Cache aufräumen" # gradle.properties: compileSdk-Warnung unterdrücken if [ -f "android/gradle.properties" ]; then if ! grep -q "android.suppressUnsupportedCompileSdk" "android/gradle.properties" 2>/dev/null; then echo "" >> "android/gradle.properties" echo "# ARIA: compileSdk-Warnung unterdrücken (AGP 8.1 vs SDK 35)" >> "android/gradle.properties" echo "android.suppressUnsupportedCompileSdk=35" >> "android/gradle.properties" echo -e " ${GREEN}✓${NC} gradle.properties: suppressUnsupportedCompileSdk=35" else skip "gradle.properties bereits konfiguriert" fi fi # Gradle Build-Cache aufräumen (verhindert Probleme nach Dependency-Wechsel) if [ -d "android/.gradle" ]; then echo " Räume Gradle Build-Cache auf..." rm -rf android/.gradle echo -e " ${GREEN}✓${NC} Gradle-Cache gelöscht" fi if [ -d "android/app/build" ]; then echo " Räume alten Build auf..." rm -rf android/app/build echo -e " ${GREEN}✓${NC} Alter Build gelöscht" fi # ══════════════════════════════════════════════ # Zusammenfassung # ══════════════════════════════════════════════ echo "" echo -e "${GREEN}╔═══════════════════════════════════════════════════╗${NC}" echo -e "${GREEN}║ Setup abgeschlossen! ║${NC}" echo -e "${GREEN}╠═══════════════════════════════════════════════════╣${NC}" NODE_V=$(node -v 2>/dev/null || echo "?") JAVA_V=$(java -version 2>&1 | head -1 | cut -d'"' -f2 || echo "?") echo -e "${GREEN}║ ║${NC}" echo -e "${GREEN}║ Node.js: ${NC}${NODE_V}" echo -e "${GREEN}║ Java: ${NC}${JAVA_V}" echo -e "${GREEN}║ Android SDK: ${NC}${ANDROID_SDK_DIR}" echo -e "${GREEN}║ Gradle: ${NC}$([ -f android/gradlew ] && echo '✓ vorhanden' || echo '✗ fehlt')" echo -e "${GREEN}║ ║${NC}" echo -e "${GREEN}║ Nächster Schritt: ║${NC}" echo -e "${GREEN}║ ${NC}./build.sh ${GREEN}(Release-APK bauen)${NC}" echo -e "${GREEN}║ ${NC}./build.sh debug ${GREEN}(Debug-APK bauen)${NC}" echo -e "${GREEN}║ ║${NC}" echo -e "${GREEN}╚═══════════════════════════════════════════════════╝${NC}" echo "" if [ -n "$SHELL_PROFILE" ] && grep -q "ANDROID_HOME" "$SHELL_PROFILE" 2>/dev/null; then echo -e "${YELLOW}Hinweis: Shell neu starten oder ausführen:${NC}" echo -e "${YELLOW} source $SHELL_PROFILE${NC}" echo "" fi