rd13_copilot_setup/scripts/copilot-bootstrap.fish
Conrad Schulz 5d0194a7b8
Some checks are pending
CI / Lint & self-test (push) Waiting to run
feat(bootstrap): auto-detect dev shell into copilot-instructions
Neues Default-Shell-Feld in der Projekt-Sektion (nach ---), damit der Agent die richtige Shell-Syntax waehlt. Bootstrap erkennt $SHELL (Fallback fish, Whitelist gegen sed-Injection) und schreibt es in frisch erzeugte copilot-instructions.md; manuell aenderbar und ueberlebt copilot-update. selftest +3 Faelle (sh & fish), beide MAINTAINER.md dokumentiert.
2026-06-18 10:05:46 +02:00

192 lines
7.7 KiB
Fish
Executable file
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env fish
# copilot-bootstrap.fish
# Fügt Copilot-Grundkonfiguration zu einem bestehenden oder neu geklonten Repo hinzu.
# Funktions-Parität mit copilot-bootstrap.sh (POSIX-Variante).
#
# Usage:
# fish copilot-bootstrap.fish # aktuelles Verzeichnis
# fish copilot-bootstrap.fish /path/to/repo # anderes Verzeichnis
# fish copilot-bootstrap.fish --with-update-hook # + post-merge Hook (auto-update nach git pull)
set TEMPLATE_DIR $HOME/.git-templates
set WITH_UPDATE_HOOK 0
set TARGET .
for arg in $argv
switch $arg
case --with-update-hook
set WITH_UPDATE_HOOK 1
case '-*'
# andere Flags ignorieren
case '*'
set TARGET $arg
end
end
if not test -d "$TARGET/.git"
echo "Error: $TARGET is not a git repository" >&2
exit 1
end
echo "Bootstrapping Copilot config in: $TARGET"
# ── Default-Shell des Entwicklungssystems erkennen ───────────────────────────
# Wird in die frisch erzeugte copilot-instructions.md geschrieben, damit der
# Agent die richtige Shell-Syntax fuer Terminal-Kommandos waehlt. Fallback: fish.
if test -n "$SHELL"
set -g DEV_SHELL (basename "$SHELL")
else
set -g DEV_SHELL fish
end
if test -z "$DEV_SHELL"; or not string match -qr '^[a-z0-9_-]+$' -- "$DEV_SHELL"
set -g DEV_SHELL fish
end
# Ersetzt die `- **Default-Shell:** …`-Zeile in $f durch den erkannten Wert.
# set -g DEV_SHELL oben, damit die Funktion den Wert im Skript-Scope sieht.
function _set_dev_shell --argument-names f
test -f "$f"; or return 0
grep -q '^- \*\*Default-Shell:\*\*' "$f" 2>/dev/null; or return 0
set tmp "$f.tmp.$fish_pid"
if sed "s|^- \*\*Default-Shell:\*\* .*|- **Default-Shell:** $DEV_SHELL|" "$f" >$tmp 2>/dev/null
mv $tmp "$f"
else
rm -f $tmp
end
end
# .github/copilot-instructions.md
if not test -f "$TARGET/.github/copilot-instructions.md"
mkdir -p "$TARGET/.github"
cp "$TEMPLATE_DIR/.github/copilot-instructions.md" "$TARGET/.github/copilot-instructions.md"
_set_dev_shell "$TARGET/.github/copilot-instructions.md"
echo " ✓ .github/copilot-instructions.md created (Default-Shell: $DEV_SHELL; TODO-Felder ausfüllen)"
else
echo " ─ .github/copilot-instructions.md already exists, skipping"
end
# .vscode/settings.json
if not test -f "$TARGET/.vscode/settings.json"
mkdir -p "$TARGET/.vscode"
cp "$TEMPLATE_DIR/.vscode/settings.json" "$TARGET/.vscode/settings.json"
echo " ✓ .vscode/settings.json created"
else
echo " ─ .vscode/settings.json already exists, skipping"
end
# .vscode/extensions.json
if not test -f "$TARGET/.vscode/extensions.json"
mkdir -p "$TARGET/.vscode"
cp "$TEMPLATE_DIR/.vscode/extensions.json" "$TARGET/.vscode/extensions.json"
echo " ✓ .vscode/extensions.json created"
else
echo " ─ .vscode/extensions.json already exists, skipping"
end
# ── data/ Persistente Service-Daten ────────────────────────────────────────
if not test -d "$TARGET/data"
mkdir -p "$TARGET/data"
touch "$TARGET/data/.gitkeep"
echo " ✓ data/ created (persistente Service-Daten gitignored)"
else
echo " ─ data/ already exists, skipping"
end
# ── docs/history/ Agent-History und Kontext-Summary ────────────────────────
if not test -d "$TARGET/docs/history/prompts"
mkdir -p "$TARGET/docs/history/prompts"
echo " ✓ docs/history/prompts/ created (Agent-Logs committed)"
end
if not test -f "$TARGET/docs/history/summary/PROJECT_CONTEXT.md"
mkdir -p "$TARGET/docs/history/summary"
cp "$TEMPLATE_DIR/docs/history/summary/PROJECT_CONTEXT.md" "$TARGET/docs/history/summary/PROJECT_CONTEXT.md"
echo " ✓ docs/history/summary/PROJECT_CONTEXT.md created (Agent-Kontext committed)"
else
echo " ─ docs/history/summary/PROJECT_CONTEXT.md already exists, skipping"
end
# ── docs/ Zielgruppen-Dokumentation ────────────────────────────────────────
if not test -d "$TARGET/docs"
mkdir -p "$TARGET/docs"
cp "$TEMPLATE_DIR/docs/USER.md" "$TARGET/docs/USER.md"
cp "$TEMPLATE_DIR/docs/ADMIN.md" "$TARGET/docs/ADMIN.md"
cp "$TEMPLATE_DIR/docs/MAINTAINER.md" "$TARGET/docs/MAINTAINER.md"
echo " ✓ docs/ created with USER.md, ADMIN.md, MAINTAINER.md (TODO-Felder ausfüllen)"
else
# Fehlende Zielgruppen-Docs ergänzen ohne vorhandene zu überschreiben
for doc in USER ADMIN MAINTAINER
if not test -f "$TARGET/docs/$doc.md"
cp "$TEMPLATE_DIR/docs/$doc.md" "$TARGET/docs/$doc.md"
echo " ✓ docs/$doc.md created"
else
echo " ─ docs/$doc.md already exists, skipping"
end
end
end
# ── Git-Hooks Quality Gate + History ───────────────────────────────────────
mkdir -p "$TARGET/.git/hooks"
if not test -f "$TARGET/.git/hooks/pre-commit"
cp "$TEMPLATE_DIR/hooks/pre-commit" "$TARGET/.git/hooks/pre-commit"
chmod +x "$TARGET/.git/hooks/pre-commit"
echo " ✓ .git/hooks/pre-commit installed (Quality Gate: Tests + Docs)"
else
echo " ─ .git/hooks/pre-commit already exists, skipping"
end
if not test -f "$TARGET/.git/hooks/post-commit"; and test -f "$TEMPLATE_DIR/hooks/post-commit"
cp "$TEMPLATE_DIR/hooks/post-commit" "$TARGET/.git/hooks/post-commit"
chmod +x "$TARGET/.git/hooks/post-commit"
echo " ✓ .git/hooks/post-commit installed (Auto-History-Log)"
end
# ── post-merge Hook opt-in: automatisches copilot-update nach git pull ──────
if test "$WITH_UPDATE_HOOK" -eq 1
if test -f "$TEMPLATE_DIR/hooks/post-merge"
if not test -f "$TARGET/.git/hooks/post-merge"
cp "$TEMPLATE_DIR/hooks/post-merge" "$TARGET/.git/hooks/post-merge"
chmod +x "$TARGET/.git/hooks/post-merge"
echo " ✓ .git/hooks/post-merge installed (Copilot-Update nach git pull)"
else
echo " ─ .git/hooks/post-merge already exists, skipping"
end
end
end
# ── .gitignore data/ + Windows-ADS ausschließen ───────────────────────────
set -g GITIGNORE "$TARGET/.gitignore"
set -g GITIGNORE_UPDATED 0
# set -g, damit die Funktion den Zähler im Skript-Scope ändern kann (fish-Scoping)
function _append_gitignore --argument-names pattern comment
if not grep -qF "$pattern" "$GITIGNORE" 2>/dev/null
printf '\n%s\n%s\n' "$comment" "$pattern" >> "$GITIGNORE"
set -g GITIGNORE_UPDATED 1
end
end
_append_gitignore "data/**/*" "# Persistente Service-Daten (nie committen!)"
_append_gitignore "!data/.gitkeep" ""
_append_gitignore "*:Zone.Identifier" "# Windows Mark-of-the-Web / NTFS ADS cruft"
if test "$GITIGNORE_UPDATED" -eq 1
echo " ✓ .gitignore aktualisiert (data/ + Windows-ADS excluded)"
else
echo " ─ .gitignore already has required entries, skipping"
end
functions -e _append_gitignore
functions -e _set_dev_shell
echo ""
echo "Done. Nächste Schritte:"
echo " 1. TODO-Felder ausfüllen:"
echo " - .github/copilot-instructions.md"
echo " - docs/history/summary/PROJECT_CONTEXT.md"
echo " - docs/USER.md, docs/ADMIN.md, docs/MAINTAINER.md"
echo " 2. git add .github .vscode docs"
echo " git commit -m 'chore: add copilot workspace config'"
echo " 3. Templates aktuell halten: git copilot-update"
echo ""
echo " Hinweis: Git-Hooks (pre-commit, post-commit) werden NICHT automatisch"
echo " aktualisiert wenn sie bereits existieren. Neue Hook-Versionen holen mit:"
echo " git copilot-update"