#!/usr/bin/env bash # Ownership-Gate: kein Paket editiert Dateien eines anderen. # Liest die Ownership-Tabelle aus STATE.md, mappt geaenderte Dateien (Branch vs. # Basis) auf Pakete und FAILt bei Cross-Editing ueber >1 Paket-Grenze hinweg. # Integration (Leader) ist ausgenommen: Branch main/master/integrate/*. # Konvention: Verzeichnis-Pfade in der Tabelle mit Slash beenden (src/api/). # Portabel gehalten (kein mapfile / keine assoziativen Arrays, laeuft auf bash 3.2). set -uo pipefail # Dormant solange das Template nicht initialisiert ist. if grep -q '' STATE.md 2>/dev/null; then echo "[ownership] Template noch nicht initialisiert — uebersprungen." echo "GATE: PASS"; exit 0 fi branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "") case "$branch" in main|master|integrate/*) echo "[ownership] '$branch' ist Integrations-Branch — uebersprungen." echo "GATE: PASS"; exit 0 ;; esac # (pkgprefix)-Zeilen aus der STATE.md-Ownership-Tabelle ziehen. pairs=$(awk -F'|' ' /Datei-Ownership/{f=1; next} f && /^[[:space:]]*$/{f=0} f && /^\|/{ pkg=$2; paths=$3; gsub(/^[ \t]+|[ \t]+$/,"",pkg); if(pkg=="" || pkg=="Paket" || pkg ~ /---/ || pkg ~ /…/ || pkg ~ /^_/) next; n=split(paths, a, ","); for(i=1;i<=n;i++){ p=a[i]; gsub(/^[ \t]+|[ \t]+$/,"",p); gsub(/`/,"",p); if(p=="" || p ~ /…/ || p ~ /^_/) continue; print pkg "\t" p } }' STATE.md 2>/dev/null) if [ -z "$pairs" ]; then echo "[ownership] keine befuellte Ownership-Tabelle in STATE.md — uebersprungen." echo "GATE: PASS"; exit 0 fi base=$(git merge-base HEAD main 2>/dev/null || git rev-parse HEAD~1 2>/dev/null || true) [ -n "$base" ] || { echo "[ownership] keine Diff-Basis — uebersprungen."; echo "GATE: PASS"; exit 0; } changed=$(git diff --name-only "$base"...HEAD 2>/dev/null) [ -n "$changed" ] || { echo "[ownership] keine Aenderungen — uebersprungen."; echo "GATE: PASS"; exit 0; } hit=""; unowned="" while IFS= read -r f; do [ -n "$f" ] || continue bestpre=""; bestpkg="" while IFS=" " read -r pkg pre; do [ -n "$pre" ] || continue case "$f" in "$pre"|"$pre"*) if [ "${#pre}" -gt "${#bestpre}" ]; then bestpre="$pre"; bestpkg="$pkg"; fi ;; esac done <