From 9e14a5fe9014550e8af9a7e6b26c539d998d68de Mon Sep 17 00:00:00 2001 From: Conrad Schulz Date: Wed, 10 Jun 2026 10:26:55 +0200 Subject: [PATCH] feat(deploy): non-invasive git config + opt-in init-copilot + portable detection WP6: Globaler 'git init'-Override und init.templateDir werden nicht mehr gesetzt (griff auch bei git clone fremder Repos). Stattdessen Opt-in-Alias 'git init-copilot'. Frueher gesetzte invasive Werte werden gezielt entfernt (nur wenn sie auf unsere Templates/Bootstrap zeigen). WP7: post-merge Auto-Deploy im Setup-Repo nur noch mit --with-self-update-hook. WP4: detect_vscode_user_dir (Server/Insiders/VSCodium/Cursor/Flatpak/macOS/Windows-WSL), identisch in deploy + copilot-update; ${USER:-} gegen set -u abgesichert. Getestet isoliert: kein alias.init, init-copilot gesetzt, kein init.templateDir, Hook nur mit Flag, unbekanntes Arg -> exit 2. --- scripts/copilot-update.sh | 4 +- scripts/deploy.fish | 98 ++++++++++++++++++++++++++++--------- scripts/deploy.sh | 100 +++++++++++++++++++++++++++++--------- 3 files changed, 153 insertions(+), 49 deletions(-) diff --git a/scripts/copilot-update.sh b/scripts/copilot-update.sh index 72f2824..08c96f3 100644 --- a/scripts/copilot-update.sh +++ b/scripts/copilot-update.sh @@ -72,8 +72,8 @@ detect_vscode_user_dir() { "$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" + "/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" diff --git a/scripts/deploy.fish b/scripts/deploy.fish index b7e2219..a5813b0 100644 --- a/scripts/deploy.fish +++ b/scripts/deploy.fish @@ -1,6 +1,22 @@ #!/usr/bin/env fish # deploy.fish – Copilot-Setup auf Linux mit fish-Shell deployen -# Usage: fish scripts/deploy.fish +# Usage: +# fish scripts/deploy.fish # Standard-Deploy (nicht-invasiv) +# fish scripts/deploy.fish --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: 'git init-copilot'. + +set WITH_SELF_HOOK 0 +for arg in $argv + switch $arg + case --with-self-update-hook + set WITH_SELF_HOOK 1 + case '*' + echo "Unbekanntes Argument: $arg" >&2 + exit 2 + end +end set REPO_DIR (dirname (status filename))/.. set REPO_DIR (realpath $REPO_DIR) @@ -8,18 +24,37 @@ set REPO_DIR (realpath $REPO_DIR) echo "=== Copilot Setup Deploy (Linux/fish) ===" echo "Source: $REPO_DIR" -# ── 1. VS Code User-Verzeichnis ermitteln ───────────────────────────────────── -# Remote (VS Code Server) -if test -d /home/(whoami)/.vscode-server/data/User - set VSCODE_USER /home/(whoami)/.vscode-server/data/User -# Flatpak -else if test -d $HOME/.var/app/com.visualstudio.code/config/Code/User - set VSCODE_USER $HOME/.var/app/com.visualstudio.code/config/Code/User -# Standard Linux -else - set VSCODE_USER $HOME/.config/Code/User +# VS Code User-Verzeichnis portabel ueber Editionen/OS ermitteln (identisch zu copilot-update.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 +# ── 1. VS Code User-Verzeichnis ermitteln ───────────────────────────────────── +set VSCODE_USER (detect_vscode_user_dir) echo "VS Code User dir: $VSCODE_USER" # ── 2. User settings.json mergen / anlegen ──────────────────────────────────── @@ -58,9 +93,15 @@ 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/history/summary/PROJECT_CONTEXT.md $GIT_TEMPLATE_DIR/history/summary/ -git config --global init.templateDir $GIT_TEMPLATE_DIR echo " ✓ git-templates deployed → $GIT_TEMPLATE_DIR" -echo " ✓ git config init.templateDir set" +# init.templateDir bewusst NICHT global setzen (sonst erbt jeder git init/clone den Gate). +set CURRENT_TPL (git config --global --get init.templateDir 2>/dev/null) +if test "$CURRENT_TPL" = "$GIT_TEMPLATE_DIR" + git config --global --unset init.templateDir + echo " ✓ altes globales init.templateDir entfernt (nicht mehr invasiv)" +else + echo " ─ init.templateDir nicht global gesetzt (gewollt)" +end # ── 5. Bootstrap- & Update-Skripte ─────────────────────────────────────────── mkdir -p $HOME/.local/bin @@ -81,29 +122,38 @@ end # ── 6. Git-Aliase: init → auto-bootstrap | copilot-update → updater ────────── # Verwendet git --exec-path um Rekursion zu vermeiden (kein Alias-Loop). -git config --global alias.init '!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' gesetzt (führt copilot-bootstrap.sh automatisch aus)" +# Kein Override des Standard-'git init' mehr. Frueheren invasiven Alias entfernen. +set CURRENT_INIT_ALIAS (git config --global --get alias.init 2>/dev/null) +if string match -q '*copilot-bootstrap*' -- "$CURRENT_INIT_ALIAS" + git config --global --unset alias.init + echo " ✓ alter invasiver 'git init'-Alias entfernt" +end +# Opt-in: explizites 'git init-copilot' macht git init + bootstrap. +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 + post-commit Hook für dieses Setup-Repo ─────────────────── set SELF_HOOKS_DIR $REPO_DIR/.git/hooks -if test -d $SELF_HOOKS_DIR - echo '#!/usr/bin/env sh +if test $WITH_SELF_HOOK -eq 1 + if test -d $SELF_HOOKS_DIR + echo '#!/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"' > $SELF_HOOKS_DIR/post-merge - chmod +x $SELF_HOOKS_DIR/post-merge - echo " ✓ post-merge Hook im Setup-Repo installiert (auto-deploy nach git pull)" - # post-commit aus git-templates kopieren (History-Logs) - cp $REPO_DIR/git-templates/hooks/post-commit $SELF_HOOKS_DIR/post-commit - chmod +x $SELF_HOOKS_DIR/post-commit - echo " ✓ post-commit Hook im Setup-Repo installiert (History-Logs)" + chmod +x $SELF_HOOKS_DIR/post-merge + echo " ✓ post-merge Hook im Setup-Repo installiert (auto-deploy nach git pull)" + end +else + echo " ─ post-merge Auto-Deploy nicht installiert (opt-in: --with-self-update-hook)" end echo "" echo "=== Done ===" echo "Next: Activate Settings Sync in VS Code (Ctrl+Shift+P → 'Settings Sync: Turn On')" -echo " Templates aktuell halten: git copilot-update (in jedem Repo)" +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)" diff --git a/scripts/deploy.sh b/scripts/deploy.sh index 9a4f6fa..c6cb764 100644 --- a/scripts/deploy.sh +++ b/scripts/deploy.sh @@ -1,25 +1,58 @@ #!/usr/bin/env bash # deploy.sh – Copilot-Setup auf macOS oder Linux mit bash deployen -# Usage: bash scripts/deploy.sh +# 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" -# ── 1. VS Code User-Verzeichnis ermitteln ───────────────────────────────────── -if [[ "$OSTYPE" == "darwin"* ]]; then - VSCODE_USER="$HOME/Library/Application Support/Code/User" - # VS Code Server (Cursor, Codium, etc.) - VSCODE_USER_ALT="$HOME/Library/Application Support/Cursor/User" -elif [[ -d "$HOME/.vscode-server/data/User" ]]; then - # Remote / VS Code Server - VSCODE_USER="$HOME/.vscode-server/data/User" -else - VSCODE_USER="$HOME/.config/Code/User" -fi +# 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" @@ -58,9 +91,17 @@ 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/history/summary/PROJECT_CONTEXT.md" "$GIT_TEMPLATE_DIR/history/summary/" -git config --global init.templateDir "$GIT_TEMPLATE_DIR" echo " ✓ git-templates deployed → $GIT_TEMPLATE_DIR" -echo " ✓ git config init.templateDir set" +# 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" @@ -83,17 +124,25 @@ fi # ── 6. Git-Aliase: init → auto-bootstrap | copilot-update → updater ────────── # Verwendet git --exec-path um Rekursion zu vermeiden (kein Alias-Loop). -git config --global alias.init '!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' gesetzt (führt copilot-bootstrap.sh automatisch aus)" +# 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. +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 ───────────────────────────────── -# Nach jedem 'git pull' auf dem Setup-Repo selbst wird deploy.sh automatisch -# ausgeführt, sodass Templates immer auf dem neuesten Stand sind. +# 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 [[ -d "$SELF_HOOKS_DIR" ]]; then - cat > "$SELF_HOOKS_DIR/post-merge" << 'HOOK' +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 "" @@ -101,11 +150,16 @@ 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)" + 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 " Templates aktuell halten: git copilot-update (in jedem Repo)" +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)"