#!/usr/bin/env fish # copilot-update.fish # Zieht die neueste Version des Copilot-Setup-Repos und aktualisiert: # - Dieses Script selbst (~/.local/bin/copilot-update.fish) # - Globale Git-Templates (~/.git-templates/) # - VS Code Prompt-Dateien # - Git-Hooks im aktuellen Repo (pre-commit) # - .github/copilot-instructions.md (Framework-Sektion immer, Projekt-Teil bleibt) # # Usage: # fish ~/.local/bin/copilot-update.fish # git copilot-update (via Alias, ruft copilot-update.sh auf) # ── Konfiguration laden: env > config-file > leer ───────────────────────── # Env-Variablen (Vorrang): # COPILOT_SETUP_REMOTE_SSH / _HTTP Remote-URLs des Setup-Repos # COPILOT_SETUP_DIR lokaler Klon/Arbeitskopie (Offline) # COPILOT_SETUP_CONFIG alternativer Pfad zur Config-Datei # Config-Datei (sh-Syntax KEY="value", wird geparst): $XDG_CONFIG_HOME/copilot-setup/config # Standalone-Skript -> keine gemeinsame Lib sourcebar; gleiche Aufloesung in deploy.fish. # Wert fuer KEY aus sh-style Config lesen (KEY="value" | KEY=value); letzte Definition gewinnt function _cfg_get --argument-names file key test -f "$file"; or return 1 set -l line (grep -E "^[[:space:]]*$key=" "$file" 2>/dev/null | tail -n1) test -n "$line"; or return 1 set -l val (string replace -r "^[[:space:]]*$key=" '' -- $line) set val (string trim -- $val) set val (string trim --chars '"' -- $val) set val (string trim --chars "'" -- $val) printf '%s' $val end # VS Code User-Verzeichnis portabel ueber Editionen/OS ermitteln (identisch zu deploy.fish) function detect_vscode_user_dir for d in \ "$HOME/.vscode-server/data/User" \ "$HOME/.vscode-server-insiders/data/User" \ "$HOME/Library/Application Support/Code/User" \ "$HOME/Library/Application Support/Code - Insiders/User" \ "$HOME/Library/Application Support/VSCodium/User" \ "$HOME/Library/Application Support/Cursor/User" \ "$HOME/.config/Code/User" \ "$HOME/.config/Code - Insiders/User" \ "$HOME/.config/VSCodium/User" \ "$HOME/.config/Cursor/User" \ "$HOME/.var/app/com.visualstudio.code/config/Code/User" \ "/mnt/c/Users/$USER/AppData/Roaming/Code/User" \ "/mnt/c/Users/$USER/AppData/Roaming/Code - Insiders/User" if test -d "$d" echo $d return 0 end end switch (uname -s) case Darwin echo "$HOME/Library/Application Support/Code/User" case '*' echo "$HOME/.config/Code/User" end end # Config-Datei-Pfad bestimmen if set -q COPILOT_SETUP_CONFIG set CONFIG_FILE $COPILOT_SETUP_CONFIG else if set -q XDG_CONFIG_HOME set CONFIG_FILE $XDG_CONFIG_HOME/copilot-setup/config else set CONFIG_FILE $HOME/.config/copilot-setup/config end # Remote/Cache aufloesen: env hat Vorrang, sonst Config, sonst Default if set -q COPILOT_SETUP_REMOTE_SSH; and test -n "$COPILOT_SETUP_REMOTE_SSH" set SETUP_REPO_SSH $COPILOT_SETUP_REMOTE_SSH else set SETUP_REPO_SSH (_cfg_get $CONFIG_FILE COPILOT_SETUP_REMOTE_SSH) end if set -q COPILOT_SETUP_REMOTE_HTTP; and test -n "$COPILOT_SETUP_REMOTE_HTTP" set SETUP_REPO_HTTP $COPILOT_SETUP_REMOTE_HTTP else set SETUP_REPO_HTTP (_cfg_get $CONFIG_FILE COPILOT_SETUP_REMOTE_HTTP) end if set -q COPILOT_SETUP_DIR; and test -n "$COPILOT_SETUP_DIR" set CACHE_DIR $COPILOT_SETUP_DIR else set CACHE_DIR (_cfg_get $CONFIG_FILE COPILOT_SETUP_DIR) test -n "$CACHE_DIR"; or set CACHE_DIR $HOME/.copilot-setup end echo "=== Copilot Update ===" # ── 1. Setup-Repo Cache aktuell halten ─────────────────────────────────────── set HAVE_REMOTE 0 if test -n "$SETUP_REPO_SSH"; or test -n "$SETUP_REPO_HTTP" set HAVE_REMOTE 1 end set SOURCE_OK 0 if test -d $CACHE_DIR/.git if test $HAVE_REMOTE -eq 1 echo " → Pulling latest from setup repo..." if git -C $CACHE_DIR pull --ff-only --quiet 2>/dev/null echo " ✓ Cache aktualisiert: $CACHE_DIR" else echo " ⚠ git pull fehlgeschlagen – nutze vorhandenen Cache (offline)" end else echo " ─ Kein Remote konfiguriert – nutze lokalen Klon: $CACHE_DIR" end set SOURCE_OK 1 else if test -d $CACHE_DIR/git-templates echo " ─ Lokale Setup-Quelle ohne .git (Offline-Betrieb): $CACHE_DIR" set SOURCE_OK 1 else if test -n "$SETUP_REPO_SSH" echo " → Klone Setup-Repo (SSH)..." if git clone --quiet $SETUP_REPO_SSH $CACHE_DIR 2>/dev/null echo " ✓ Geklont via SSH" set SOURCE_OK 1 else echo " ✗ SSH fehlgeschlagen" end end if test $SOURCE_OK -eq 0; and test -n "$SETUP_REPO_HTTP" echo " → Klone Setup-Repo (HTTP)..." if git clone --quiet $SETUP_REPO_HTTP $CACHE_DIR 2>/dev/null echo " ✓ Geklont via HTTP" set SOURCE_OK 1 else echo " ✗ HTTP fehlgeschlagen" end end end if test $SOURCE_OK -eq 0 echo "" echo " ⚠ Keine Setup-Quelle verfuegbar – Update uebersprungen." if test $HAVE_REMOTE -eq 1 echo " Remote nicht erreichbar:" test -n "$SETUP_REPO_SSH"; and echo " SSH: $SETUP_REPO_SSH" test -n "$SETUP_REPO_HTTP"; and echo " HTTP: $SETUP_REPO_HTTP" else echo " Kein Remote konfiguriert. Setze COPILOT_SETUP_REMOTE_SSH/_HTTP," echo " COPILOT_SETUP_DIR (lokaler Klon) oder lege $CONFIG_FILE an." end echo " (Kein Fehler – ohne Quelle gibt es nichts zu aktualisieren.)" exit 0 end set SOURCE $CACHE_DIR # ── 1b. Self-update ────────────────────────────────────────────────────── set SELF $HOME/.local/bin/copilot-update.fish if test -f $SOURCE/scripts/copilot-update.fish if not diff -q $SOURCE/scripts/copilot-update.fish $SELF >/dev/null 2>&1 cp $SOURCE/scripts/copilot-update.fish $SELF chmod +x $SELF echo " ✓ copilot-update.fish selbst aktualisiert – starte neue Version..." exec fish $SELF $argv end end # ── 2. ~/.git-templates/ aktualisieren ────────────────────────────────────── set GIT_TEMPLATE_DIR $HOME/.git-templates mkdir -p $GIT_TEMPLATE_DIR/.github $GIT_TEMPLATE_DIR/.vscode \ $GIT_TEMPLATE_DIR/hooks $GIT_TEMPLATE_DIR/docs \ $GIT_TEMPLATE_DIR/history/summary cp $SOURCE/git-templates/.github/copilot-instructions.md $GIT_TEMPLATE_DIR/.github/ cp $SOURCE/git-templates/.vscode/settings.json $GIT_TEMPLATE_DIR/.vscode/ cp $SOURCE/git-templates/.vscode/extensions.json $GIT_TEMPLATE_DIR/.vscode/ cp $SOURCE/git-templates/hooks/pre-commit $GIT_TEMPLATE_DIR/hooks/ chmod +x $GIT_TEMPLATE_DIR/hooks/pre-commit if test -f $SOURCE/git-templates/hooks/post-merge cp $SOURCE/git-templates/hooks/post-merge $GIT_TEMPLATE_DIR/hooks/ chmod +x $GIT_TEMPLATE_DIR/hooks/post-merge end cp $SOURCE/git-templates/docs/USER.md $GIT_TEMPLATE_DIR/docs/ cp $SOURCE/git-templates/docs/ADMIN.md $GIT_TEMPLATE_DIR/docs/ cp $SOURCE/git-templates/docs/MAINTAINER.md $GIT_TEMPLATE_DIR/docs/ cp $SOURCE/git-templates/history/summary/PROJECT_CONTEXT.md $GIT_TEMPLATE_DIR/history/summary/ echo " ✓ ~/.git-templates/ aktualisiert" # ── 3. VS Code Prompt-Dateien aktualisieren ─────────────────────────────────── set VSCODE_USER (detect_vscode_user_dir) if test -d "$VSCODE_USER" mkdir -p $VSCODE_USER/prompts set PROMPTS_UPDATED 0 for f in $SOURCE/prompts/*.prompt.md set fname (basename $f) cp $f $VSCODE_USER/prompts/$fname set PROMPTS_UPDATED (math $PROMPTS_UPDATED + 1) end echo " ✓ $PROMPTS_UPDATED Prompt-Dateien aktualisiert → $VSCODE_USER/prompts/" else echo " ─ VS Code User-Verzeichnis nicht gefunden, Prompts übersprungen" end # ── 4. Repo-lokale Updates (nur wenn in einem Git-Repo) ────────────────────── set REPO_ROOT (git rev-parse --show-toplevel 2>/dev/null) if test -z "$REPO_ROOT" echo "" echo " ─ Kein Git-Repo erkannt – repo-lokale Updates übersprungen" echo "" echo "=== Done ===" exit 0 end echo "" echo " Git-Repo erkannt: $REPO_ROOT" # ── 4a. Git-Hooks aktualisieren ─────────────────────────────────────────────── set HOOKS_DIR $REPO_ROOT/.git/hooks mkdir -p $HOOKS_DIR set HOOKS_UPDATED 0 for hook in pre-commit if test -f $SOURCE/git-templates/hooks/$hook cp $SOURCE/git-templates/hooks/$hook $HOOKS_DIR/$hook chmod +x $HOOKS_DIR/$hook set HOOKS_UPDATED (math $HOOKS_UPDATED + 1) echo " ✓ .git/hooks/$hook aktualisiert" end end if test $HOOKS_UPDATED -eq 0 echo " ─ Keine Hook-Templates gefunden" end # ── 4b. copilot-instructions.md: Framework-Sektion immer aktualisieren ───────── set COPILOT_INSTRUCTIONS $REPO_ROOT/.github/copilot-instructions.md set TEMPLATE_INSTRUCTIONS $SOURCE/git-templates/.github/copilot-instructions.md if test -f $COPILOT_INSTRUCTIONS; and test -f $TEMPLATE_INSTRUCTIONS set framework (awk '/^---$/{exit} {print}' $TEMPLATE_INSTRUCTIONS) set project (awk '/^---$/{found=1} found{print}' $COPILOT_INSTRUCTIONS) if test -n "$project" printf '%s\n\n%s\n' (string join \n $framework) (string join \n $project) > $COPILOT_INSTRUCTIONS echo " ✓ .github/copilot-instructions.md Framework-Sektion aktualisiert" else cp $TEMPLATE_INSTRUCTIONS $COPILOT_INSTRUCTIONS echo " ✓ .github/copilot-instructions.md aktualisiert (noch nicht angepasst)" end else echo " ─ .github/copilot-instructions.md nicht vorhanden, übersprungen" end # ── 4c. Fehlende 3-Zielgruppen-Docs anlegen (nur wenn noch nicht vorhanden) ── if test -d $REPO_ROOT/docs set DOCS_CREATED 0 for doc in USER.md ADMIN.md MAINTAINER.md if not test -f $REPO_ROOT/docs/$doc; and test -f $GIT_TEMPLATE_DIR/docs/$doc cp $GIT_TEMPLATE_DIR/docs/$doc $REPO_ROOT/docs/$doc echo " ✓ docs/$doc angelegt (Template)" set DOCS_CREATED (math $DOCS_CREATED + 1) end end if test $DOCS_CREATED -eq 0 echo " ─ docs/ 3-Zielgruppen-Docs bereits vorhanden" end end echo "" echo "=== Done ===" echo "Tipp: 'git copilot-update' jederzeit ausführen um Templates aktuell zu halten."