73 lines
3.3 KiB
Bash
Executable File
73 lines
3.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Werkbaum — mirror-docs: mehrere Server-Dokumente in ein git-Worktree
|
|
# spiegeln. Liest eine Liste, ruft je Zeile `pull-doc --git-commit` und pusht
|
|
# auf Wunsch einmal am Ende. Gedacht für einen Timer auf dem Backend-Host
|
|
# (D88-Nachtrag 3): Der geteilte Plan bekommt so ohne Zutun eine Git-Historie.
|
|
#
|
|
# Verwendung:
|
|
# mirror-docs [--push] [--api <basis>] <worktree> <liste>
|
|
#
|
|
# --push Nach dem Durchlauf `git push`, wenn etwas committet wurde.
|
|
# Der Branch braucht dafür einen Upstream.
|
|
# --api <basis> Basis-Adresse des Backends (…/api/v1) für Zeilen, die nur
|
|
# eine UUID nennen; sonst aus WERKBAUM_API.
|
|
# <worktree> Wurzel des git-Worktrees, in das gespiegelt wird.
|
|
# <liste> Textdatei, je Zeile `<uuid-oder-url> <pfad>`; der Pfad ist
|
|
# relativ zum Worktree. Leerzeilen und `#`-Zeilen sind
|
|
# Kommentar. Ein neues Dokument ist eine Zeile mehr.
|
|
#
|
|
# Jede Zeile läuft für sich: Ein gescheiterter Abruf bricht die übrigen nicht
|
|
# ab, steht aber auf stderr, und der Lauf endet dann mit 1 — ein Timer sieht
|
|
# so im Journal, was fehlt, statt still zu bleiben. Unverändertes committet
|
|
# nichts (das regelt pull-doc); ohne neuen Commit wird nicht gepusht.
|
|
#
|
|
# Siehe docs/DECISIONS.md D88.
|
|
|
|
set -euo pipefail
|
|
|
|
usage(){ sed -n '2,25p' "$0" | sed 's/^# \{0,1\}//'; }
|
|
|
|
do_push=0; api="${WERKBAUM_API:-}"
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
-h|--help) usage; exit 0;;
|
|
--push) do_push=1; shift;;
|
|
--api) [ $# -ge 2 ] || { echo "Fehler: --api braucht eine Adresse." >&2; exit 2; }; api="$2"; shift 2;;
|
|
--*) echo "Fehler: unbekannter Schalter $1" >&2; echo >&2; usage >&2; exit 2;;
|
|
*) break;;
|
|
esac
|
|
done
|
|
[ $# -eq 2 ] || { echo "Fehler: erwartet [--push] [--api <basis>] Worktree und Liste." >&2; echo >&2; usage >&2; exit 2; }
|
|
tree="$1"; list="$2"
|
|
pulldoc="$(dirname -- "$0")/pull-doc"
|
|
|
|
[ -x "$pulldoc" ] || { echo "Fehler: $pulldoc fehlt oder ist nicht ausführbar." >&2; exit 2; }
|
|
[ -f "$list" ] || { echo "Fehler: Liste $list gibt es nicht." >&2; exit 2; }
|
|
[ "$(git -C "$tree" rev-parse --is-inside-work-tree 2>/dev/null)" = "true" ] \
|
|
|| { echo "Fehler: $tree ist kein git-Worktree." >&2; exit 2; }
|
|
|
|
before="$(git -C "$tree" rev-parse HEAD)"
|
|
fail=0; n=0
|
|
while read -r src path _; do
|
|
case "$src" in ''|'#'*) continue;; esac
|
|
n=$((n+1))
|
|
[ -n "$path" ] || { echo "Fehler: Zeile ohne Pfad: $src" >&2; fail=1; continue; }
|
|
case "$src" in
|
|
http://*|https://*) url="$src";;
|
|
*) [ -n "$api" ] || { echo "Fehler: $src ist keine URL, und --api/WERKBAUM_API fehlt." >&2; fail=1; continue; }
|
|
url="${api%/}/documents/$src";;
|
|
esac
|
|
case "$path" in /*|*..*) echo "Fehler: Pfad muss relativ und ohne .. sein: $path" >&2; fail=1; continue;; esac
|
|
mkdir -p -- "$tree/$(dirname -- "$path")"
|
|
"$pulldoc" --git-commit "$url" "$tree/$path" || { echo "Fehler bei $path (siehe oben)." >&2; fail=1; }
|
|
done < "$list"
|
|
[ "$n" -gt 0 ] || echo "Hinweis: Liste $list nennt kein Dokument." >&2
|
|
|
|
after="$(git -C "$tree" rev-parse HEAD)"
|
|
if [ "$do_push" = 1 ] && [ "$before" != "$after" ]; then
|
|
git -C "$tree" push -q || { echo "Fehler: push gescheitert — Commits liegen lokal in $tree." >&2; fail=1; }
|
|
[ "$fail" = 0 ] && echo "Gepusht: $(git -C "$tree" rev-parse --short HEAD)"
|
|
fi
|
|
exit "$fail"
|