#!/bin/bash # 🌲 Crumbforest Mission Doktor v2.0 # Metadata-driven, erweiterbar, Bash 3.2+ kompatibel # Inspiriert vom crumbpages-doktor.sh Konzept set -euo pipefail # === FARBEN === GREEN='\033[0;32m' BLUE='\033[0;34m' RED='\033[0;31m' YELLOW='\033[1;33m' CYAN='\033[0;36m' NC='\033[0m' # No Color # === KONFIGURATION === SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" MISSION_DIR="${SCRIPT_DIR}/missions" # ============================================================ # HILFSFUNKTIONEN # ============================================================ function show_header() { clear echo -e "${GREEN}" cat << 'EOF' 🌲 Crumbforest Mission Doktor 🌲 Willkommen im Waldlern-System! Wähle deine Kategorie: EOF echo -e "${NC}" } function load_missions_from_category() { local category="$1" local search_dir="${MISSION_DIR}/${category}" if [[ ! -d "$search_dir" ]]; then echo -e "${RED}Kategorie '$category' nicht gefunden.${NC}" return 1 fi # Arrays für Missionen (Bash 3.2+ kompatibel) MISSION_OPTIONS=() MISSION_SCRIPTS=() # Alle .sh Dateien finden while IFS= read -r file; do [[ -n "$file" ]] && MISSION_SCRIPTS+=("$file") done < <(find "$search_dir" -maxdepth 1 -type f -name "*.sh" | sort) if [[ ${#MISSION_SCRIPTS[@]} -eq 0 ]]; then echo -e "${YELLOW}Keine Missionen in dieser Kategorie gefunden.${NC}" return 1 fi # Metadaten laden for mission_file in "${MISSION_SCRIPTS[@]}"; do local mission_name mission_name="$(basename "$mission_file" .sh)" local meta_file="${search_dir}/${mission_name}.meta.json" if [[ -f "$meta_file" ]]; then local icon title enabled icon=$(jq -r '.icon // "🛸"' "$meta_file" 2>/dev/null) title=$(jq -r '.title // "Unknown"' "$meta_file" 2>/dev/null) enabled=$(jq -r '.enabled // true' "$meta_file" 2>/dev/null) # Ignoriere deaktivierte Missionen [[ "$enabled" == "false" ]] && continue MISSION_OPTIONS+=("${icon} ${title}") else # Fallback ohne Metadaten MISSION_OPTIONS+=("🛸 ${mission_name}") fi done return 0 } # ============================================================ # MISSION RUNNER # ============================================================ function run_mission_menu() { local category="$1" local category_name="$2" if ! load_missions_from_category "$category"; then read -p "Drücke Enter..." -r return fi while true; do clear echo -e "${BLUE}=== ${category_name} ===${NC}" echo "" # Beenden-Option hinzufügen MISSION_OPTIONS+=("🚪 Zurück zum Hauptmenü") PS3="Gib die Zahl deiner Wahl ein: " select opt in "${MISSION_OPTIONS[@]}"; do local choice=$((REPLY - 1)) # Beenden gewählt if [[ "$opt" == "🚪 Zurück zum Hauptmenü" ]]; then return fi # Mission starten if (( choice >= 0 && choice < ${#MISSION_OPTIONS[@]} - 1 )); then local selected_script="${MISSION_SCRIPTS[$choice]}" echo "" echo -e "${YELLOW}▶️ Starte Mission: $(basename "$selected_script")${NC}" echo "" # Mission ausführen bash "$selected_script" # Nach Mission: Zurück zum Menü echo "" echo -e "${GREEN}✅ Mission abgeschlossen!${NC}" read -p "Drücke Enter für das Menü..." -r break else echo -e "${RED}❗ Ungültige Eingabe.${NC}" fi done # Reload für nächste Iteration if ! load_missions_from_category "$category"; then return fi done } # ============================================================ # DOKTOR SYSTEM-CHECK # ============================================================ function system_doktor() { clear echo -e "${BLUE}=== 🖥️ System Doktor ===${NC}" echo "" if [[ "$OSTYPE" == "linux-gnu"* ]]; then echo -e "${CYAN}🐧 Linux System${NC}" hostnamectl 2>/dev/null || hostname echo "" uname -r echo "" free -h 2>/dev/null || echo "free: nicht verfügbar" echo "" df -h / 2>/dev/null elif [[ "$OSTYPE" == "darwin"* ]]; then echo -e "${CYAN}🍏 macOS System${NC}" hostname echo "" sw_vers 2>/dev/null echo "" echo "Memory:" vm_stat | head -n 5 echo "" echo "Disk:" df -h / else echo -e "${YELLOW}Unbekanntes System: $OSTYPE${NC}" fi echo "" echo -e "${GREEN}Bash Version: $BASH_VERSION${NC}" echo "" read -p "Drücke Enter..." -r } # ============================================================ # TOOLS CHECK (Interactive Shell) # ============================================================ function tools_doktor() { echo -e "${BLUE}--- 🛠️ Crumbforest Werkzeugkasten ---${NC}" # Temporäres RC File für die Shell TOOL_RC="/tmp/crumb_tools_$$.rc" cat > "${TOOL_RC}" << 'EOF' if [ -f /etc/bashrc ]; then source /etc/bashrc; fi if [ -f ~/.bashrc ]; then source ~/.bashrc; fi # Farben GREEN='\033[0;32m' RED='\033[0;31m' YELLOW='\033[1;33m' NC='\033[0m' # Prompt im Crumbforest-Style export PS1="\[\033[0;33m\](🛠️ Werkzeug) \u@\h:\w$ \[\033[0m\]" function tool_check() { echo -e "${YELLOW}=== Werkzeug-Verfügbarkeit ===${NC}" echo "" TOOLS="jq git curl wget python3 nano vim htop ncdu tree" for tool in $TOOLS; do if command -v "$tool" &> /dev/null; then echo -e "${GREEN}✅ $tool${NC} - $(command -v "$tool")" else echo -e "${RED}❌ $tool${NC} - Nicht installiert" fi done echo "" echo -e "${YELLOW}Mission System Requirements:${NC}" if command -v jq &> /dev/null; then echo -e "${GREEN}✅ jq verfügbar${NC} - Mission Selector funktioniert" else echo -e "${RED}⚠️ jq fehlt${NC} - Bitte installieren!" fi } alias check="tool_check" alias logs="tail -f /var/log/syslog 2>/dev/null || tail -f /var/log/system.log 2>/dev/null || echo 'Keine Standard-Logs gefunden'" echo "" echo "🌲 Willkommen im Crumbforest Werkzeugkasten!" echo "" echo "Befehle:" echo " check - Werkzeug-Verfügbarkeit prüfen" echo " logs - System-Logs anzeigen" echo " exit - Zurück zum Hauptmenü" echo "" tool_check EOF bash --rcfile "${TOOL_RC}" rm -f "${TOOL_RC}" } # ============================================================ # GIT DOKTOR (Interactive Shell) # ============================================================ function git_doktor() { echo -e "${BLUE}--- 🌲 Crumbforest Git Workstation ---${NC}" if [[ ! -d ".git" ]]; then echo -e "${RED}❌ Kein Git Repository gefunden.${NC}" read -p "Drücke Enter..." -r return fi # Temporäres RC File für die Shell GIT_RC="/tmp/crumb_git_$$.rc" cat > "${GIT_RC}" << 'EOF' if [ -f /etc/bashrc ]; then source /etc/bashrc; fi if [ -f ~/.bashrc ]; then source ~/.bashrc; fi # Farben GREEN='\033[0;32m' YELLOW='\033[1;33m' RED='\033[0;31m' NC='\033[0m' # Prompt im Crumbforest-Style export PS1="\[\033[0;34m\](🌲 Git) \u@\h:\w$ \[\033[0m\]" function check_health() { echo -e "${YELLOW}=== Repository Gesundheit ===${NC}" echo "" if [ ! -d ".git" ]; then echo -e "${RED}❌ Kein Git Repo!${NC}" return fi # Remote Info echo -e "${YELLOW}Remote:${NC}" git remote -v 2>/dev/null || echo "Keine Remotes" echo "" # Branch Info echo -e "${YELLOW}Current Branch:${NC}" git branch --show-current 2>/dev/null || git branch | grep '*' echo "" # Sync Check git remote update > /dev/null 2>&1 LOCAL=$(git rev-parse @ 2>/dev/null) REMOTE=$(git rev-parse @{u} 2>/dev/null) if [ "$LOCAL" = "$REMOTE" ]; then echo -e "${GREEN}✅ Synchron mit Remote${NC}" else echo -e "${YELLOW}⚠️ Nicht synchron / Push needed${NC}" fi echo "" # Status echo -e "${YELLOW}Status:${NC}" git status --short echo "" # Letzter Commit echo -e "${YELLOW}Letzter Commit:${NC}" git log -1 --oneline --decorate 2>/dev/null } # Praktische Aliases alias gst="git status" alias gd="git diff" alias gl="git log --oneline --graph --decorate --all -n 10" alias ga="git add" alias gc="git commit" alias gp="git push" alias health="check_health" echo "" echo "🌲 Willkommen in der Crumbforest Git Workstation!" echo "" echo "Befehle:" echo " health - Repository Gesundheit prüfen" echo " gst - git status" echo " gd - git diff" echo " gl - git log (graphisch)" echo " ga - git add" echo " gc - git commit" echo " gp - git push" echo " exit - Zurück zum Hauptmenü" echo "" check_health EOF bash --rcfile "${GIT_RC}" rm -f "${GIT_RC}" } # ============================================================ # HAUPTMENÜ # ============================================================ function main_menu() { while true; do show_header echo "1) 📚 Basics - Einsteiger Missionen" echo "2) 🚀 Advanced - Fortgeschrittene Missionen" echo "3) 🏆 Challenges - Herausforderungen" echo "" echo "--- Doktor Tools ---" echo "4) 🖥️ System Doktor" echo "5) 🛠️ Werkzeug-Check" echo "6) 🌲 Git Doktor" echo "" echo "7) 👋 Beenden" echo "" read -p "Auswahl [1-7]: " CHOICE case $CHOICE in 1) run_mission_menu "basics" "📚 Basics - Einsteiger" ;; 2) run_mission_menu "advanced" "🚀 Advanced - Fortgeschrittene" ;; 3) run_mission_menu "challenges" "🏆 Challenges" ;; 4) system_doktor ;; 5) tools_doktor ;; 6) git_doktor ;; 7) clear echo -e "${GREEN}" echo "👋 Auf bald im Crumbforest!" echo -e "${NC}" exit 0 ;; *) echo -e "${RED}Bitte 1-7 wählen.${NC}" sleep 1 ;; esac done } # ============================================================ # START # ============================================================ main_menu