#!/usr/bin/env bash # deploy.sh – Copilot-Setup auf macOS oder Linux mit bash deployen # Usage: # bash scripts/deploy.sh # Standard-Deploy (nicht-invasiv) # bash scripts/deploy.sh --with-self-update-hook # + post-merge Auto-Deploy im Setup-Repo # # Hinweis: Setzt KEINEN globalen 'git init'-Alias und KEIN init.templateDir. # Standard-'git init'/'git clone' bleiben unberuehrt. Opt-in pro Repo: # git init-copilot [pfad] (Alias wird hier angelegt) # copilot-bootstrap.sh [pfad] (bestehende Repos ausstatten) set -euo pipefail WITH_SELF_HOOK=0 for arg in "$@"; do case "$arg" in --with-self-update-hook) WITH_SELF_HOOK=1 ;; *) echo "Unbekanntes Argument: $arg" >&2; exit 2 ;; esac done REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" echo "=== Copilot Setup Deploy (bash) ===" echo "Source: $REPO_DIR" # VS Code User-Verzeichnis portabel ermitteln (identisch zu copilot-update.sh) 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" do if [ -d "$d" ]; then printf '%s\n' "$d" return 0 fi done case "$(uname -s)" in Darwin) printf '%s\n' "$HOME/Library/Application Support/Code/User" ;; *) printf '%s\n' "$HOME/.config/Code/User" ;; esac } # ── 1. VS Code User-Verzeichnis ermitteln ───────────────────────────────────── VSCODE_USER="$(detect_vscode_user_dir)" echo "VS Code User dir: $VSCODE_USER" mkdir -p "$VSCODE_USER" # ── 2. User settings.json ───────────────────────────────────────────────────── if [[ -f "$VSCODE_USER/settings.json" ]]; then echo " ─ settings.json exists – skipping (merge manually if needed)" echo " Reference: $REPO_DIR/user-settings/settings.json" else cp "$REPO_DIR/user-settings/settings.json" "$VSCODE_USER/settings.json" echo " ✓ settings.json deployed" fi # ── 3. Prompt Files ─────────────────────────────────────────────────────────── mkdir -p "$VSCODE_USER/prompts" for f in "$REPO_DIR/prompts/"*.prompt.md; do fname="$(basename "$f")" if [[ -f "$VSCODE_USER/prompts/$fname" ]]; then echo " ─ prompts/$fname already exists, skipping" else cp "$f" "$VSCODE_USER/prompts/$fname" echo " ✓ prompts/$fname deployed" fi done # ── 4. Git-Templates ────────────────────────────────────────────────────────── 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/docs/history/summary" cp "$REPO_DIR/git-templates/.github/copilot-instructions.md" "$GIT_TEMPLATE_DIR/.github/" cp "$REPO_DIR/git-templates/.vscode/settings.json" "$GIT_TEMPLATE_DIR/.vscode/" cp "$REPO_DIR/git-templates/.vscode/extensions.json" "$GIT_TEMPLATE_DIR/.vscode/" cp "$REPO_DIR/git-templates/hooks/pre-commit" "$GIT_TEMPLATE_DIR/hooks/" chmod +x "$GIT_TEMPLATE_DIR/hooks/pre-commit" cp "$REPO_DIR/git-templates/docs/USER.md" "$GIT_TEMPLATE_DIR/docs/" cp "$REPO_DIR/git-templates/docs/ADMIN.md" "$GIT_TEMPLATE_DIR/docs/" cp "$REPO_DIR/git-templates/docs/MAINTAINER.md" "$GIT_TEMPLATE_DIR/docs/" cp "$REPO_DIR/git-templates/docs/history/summary/PROJECT_CONTEXT.md" "$GIT_TEMPLATE_DIR/docs/history/summary/" echo " ✓ git-templates deployed → $GIT_TEMPLATE_DIR" # init.templateDir wird bewusst NICHT global gesetzt – sonst wuerde jeder # 'git init'/'git clone' (auch fremde Repos) automatisch den Quality Gate erben. # Frueher gesetzten Wert entfernen, falls er auf unsere Templates zeigt. CURRENT_TPL="$(git config --global --get init.templateDir || true)" if [[ "$CURRENT_TPL" == "$GIT_TEMPLATE_DIR" ]]; then git config --global --unset init.templateDir || true echo " ✓ altes globales init.templateDir entfernt (nicht mehr invasiv)" else echo " ─ init.templateDir nicht global gesetzt (gewollt)" fi # ── 5. Bootstrap- & Update-Skripte ─────────────────────────────────────────── mkdir -p "$HOME/.local/bin" cp "$REPO_DIR/scripts/copilot-bootstrap.sh" "$HOME/.local/bin/copilot-bootstrap.sh" chmod +x "$HOME/.local/bin/copilot-bootstrap.sh" echo " ✓ copilot-bootstrap.sh installed to ~/.local/bin/" if [[ -f "$REPO_DIR/scripts/copilot-bootstrap.fish" ]]; then cp "$REPO_DIR/scripts/copilot-bootstrap.fish" "$HOME/.local/bin/copilot-bootstrap.fish" chmod +x "$HOME/.local/bin/copilot-bootstrap.fish" echo " ✓ copilot-bootstrap.fish installed to ~/.local/bin/" fi cp "$REPO_DIR/scripts/copilot-update.sh" "$HOME/.local/bin/copilot-update.sh" chmod +x "$HOME/.local/bin/copilot-update.sh" echo " ✓ copilot-update.sh installed to ~/.local/bin/" if [[ -f "$REPO_DIR/scripts/copilot-update.fish" ]]; then cp "$REPO_DIR/scripts/copilot-update.fish" "$HOME/.local/bin/copilot-update.fish" chmod +x "$HOME/.local/bin/copilot-update.fish" echo " ✓ copilot-update.fish installed to ~/.local/bin/" fi # ── 6. Git-Aliase: init → auto-bootstrap | copilot-update → updater ────────── # Verwendet git --exec-path um Rekursion zu vermeiden (kein Alias-Loop). # Kein Override des Standard-'git init' mehr. Frueheren invasiven Alias entfernen. CURRENT_INIT_ALIAS="$(git config --global --get alias.init || true)" if [[ "$CURRENT_INIT_ALIAS" == *copilot-bootstrap* ]]; then git config --global --unset alias.init || true echo " ✓ alter invasiver 'git init'-Alias entfernt" fi # Opt-in: explizites 'git init-copilot' macht git init + bootstrap. # shellcheck disable=SC2016 # Alias absichtlich literal – git expandiert zur Laufzeit git config --global alias.init-copilot '!f() { dir=.; for a in "$@"; do case "$a" in -*) ;; *) dir="$a" ;; esac; done; "$(git --exec-path)/git-init" "$@" && "$HOME/.local/bin/copilot-bootstrap.sh" "$dir"; }; f' echo " ✓ git alias 'init-copilot' gesetzt (opt-in: git init + copilot-bootstrap)" git config --global alias.copilot-update '!~/.local/bin/copilot-update.sh' echo " ✓ git alias 'copilot-update' gesetzt (aktualisiert Templates & Prompts)" # ── 7. post-merge Hook für dieses Setup-Repo ───────────────────────────────── # Nur mit --with-self-update-hook: nach jedem 'git pull' auf dem Setup-Repo # wird deploy.sh automatisch erneut ausgeführt. SELF_HOOKS_DIR="$REPO_DIR/.git/hooks" if [[ "$WITH_SELF_HOOK" -eq 1 ]]; then if [[ -d "$SELF_HOOKS_DIR" ]]; then cat > "$SELF_HOOKS_DIR/post-merge" << 'HOOK' #!/usr/bin/env sh # post-merge – Auto-Deploy nach git pull auf dem Setup-Repo echo "" echo " [post-merge] Setup-Repo aktualisiert – deploye Templates neu..." SCRIPT_DIR="$(cd "$(dirname "$0")/../../scripts" && pwd)" bash "$SCRIPT_DIR/deploy.sh" HOOK chmod +x "$SELF_HOOKS_DIR/post-merge" echo " ✓ post-merge Hook im Setup-Repo installiert (auto-deploy nach git pull)" fi else echo " ─ post-merge Auto-Deploy nicht installiert (opt-in: --with-self-update-hook)" fi echo "" echo "=== Done ===" echo "Next: Activate Settings Sync in VS Code (Cmd+Shift+P → 'Settings Sync: Turn On')" echo " Neues Repo mit Copilot-Setup: git init-copilot [pfad]" echo " Bestehendes Repo ausstatten: copilot-bootstrap.sh [pfad]" echo " Templates aktuell halten: git copilot-update (in jedem Repo)"