Some checks failed
gates / quality (push) Has been cancelled
Eine Leerzeile oder Blockquote zwischen der 'Datei-Ownership'-Ueberschrift und der Tabelle setzte den Parser zurueck -> Tabelle wurde nicht gefunden, Gate faelschlich uebersprungen. Jetzt: f=0 erst, nachdem die Tabelle begonnen hat. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
82 lines
2.9 KiB
Bash
Executable File
82 lines
2.9 KiB
Bash
Executable File
#!/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 '<id / datum>' 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
|
|
|
|
# (pkg<TAB>prefix)-Zeilen aus der STATE.md-Ownership-Tabelle ziehen.
|
|
pairs=$(awk -F'|' '
|
|
/Datei-Ownership/{f=1; started=0; next}
|
|
f && started && $0 !~ /^\|/ {f=0} # erst NACH Tabellenbeginn abbrechen
|
|
f && /^\|/{
|
|
started=1;
|
|
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 <<EOF
|
|
$pairs
|
|
EOF
|
|
if [ -n "$bestpkg" ]; then
|
|
hit="$hit$bestpkg
|
|
"
|
|
else
|
|
unowned="$unowned $f"
|
|
fi
|
|
done <<EOF
|
|
$changed
|
|
EOF
|
|
|
|
distinct=$(printf '%s' "$hit" | sed '/^$/d' | sort -u)
|
|
n=$(printf '%s' "$distinct" | sed '/^$/d' | grep -c . || true)
|
|
echo "[ownership] Branch '$branch' beruehrt $n Paket(e): $(printf '%s ' $distinct)"
|
|
[ -n "$unowned" ] && echo "[ownership] Hinweis: ohne Owner in STATE.md:$unowned"
|
|
|
|
if [ "${n:-0}" -gt 1 ]; then
|
|
echo " - FAIL: Aenderungen ueber mehrere Ownership-Grenzen (Cross-Editing)."
|
|
echo " Worker editieren nur ihr Paket; Integration macht der Leader (Branch integrate/*)."
|
|
echo "GATE: FAIL"; exit 1
|
|
fi
|
|
echo "GATE: PASS"
|