From: Kai Moritz Date: Sun, 31 May 2026 17:06:38 +0000 (+0000) Subject: lib.sh: Gemeinsame Logik aus Skripten extrahiert X-Git-Tag: scripting--2026-06-04~17 X-Git-Url: http://juplo.de/gitweb/?a=commitdiff_plain;h=b7e69b50f1823bee507314f89199af8455c0bb0f;p=demos%2Fkafka%2Ftraining lib.sh: Gemeinsame Logik aus Skripten extrahiert Neue Shared Library lib.sh, die branches.sh einbindet und drei zentrale Bausteine bereitstellt, die zuvor in mehreren Skripten dupliziert waren: - $BRANCH_NAMES: Array aller Branch-Namen (inkl. grundlagen/docker), ersetzt das wiederholte `for i in grundlagen__docker $BRANCHES; do declare -n branch=$i`-Muster in push.sh, reset.sh, diff.sh, copy.sh und die manuelle BRANCH_LIST-Konstruktion in push.sh. - find_common_tag_suffixes(): Vereinheitlicht zwei unterschiedliche Implementierungen desselben Algorithmus (push.sh nutzte git rev-parse, copy.sh nutzte git tag -l + comm). - reset_branches_to_remote(): Extrahiert die identische Reset-Schleife aus copy.sh und reset.sh. Alle Skripte binden nun lib.sh statt branches.sh ein. lib.sh wird ebenfalls in den rsync-Excludes von copy.sh geführt. Co-Authored-By: Claude Sonnet 4.6 --- diff --git a/CLAUDE.md b/CLAUDE.md index 1b5b5292..5f31f24a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -204,11 +204,12 @@ wobei `` mit `pom.xml`s `` (Maven) oder `settings.gradle ## Skripte im Scripting-Branch -Alle Skripte laden zuerst `branches.sh`, das die vollständige Branch-Liste definiert. +Alle Skripte binden `lib.sh` ein, das seinerseits `branches.sh` lädt und gemeinsame Funktionen bereitstellt. | Skript | Zweck | |--------|-------| | `branches.sh` | Definiert alle Branch-Namen als Variablen und die Iterationsliste `$BRANCHES` | +| `lib.sh` | Shared Library: bindet `branches.sh` ein, stellt `$BRANCH_NAMES`-Array (alle Branches inkl. `grundlagen/docker`) sowie `find_common_tag_suffixes()` und `reset_branches_to_remote()` bereit | | `push.sh` | Force-pusht alle Branches zu origin. Prüft vorab, ob umzuschreibende Remote-Stände bereits Tags im Remote haben; fehlt ein Tag, werden TIMESTAMP-Backup-Tags für alle Remote-Stände direkt im Remote angelegt. Existiert lokal ein gemeinsames Tag-Suffix für alle Branches (z.B. `--claude-5`), wird es ebenfalls gepusht, sofern noch nicht im Remote vorhanden. | | `reset.sh` | Ohne Argument: setzt alle Branches auf `origin/` zurück. Mit Argument: auf Tag `--` | | `diff.sh` | Ohne Arg: lokaler Branch gegen `origin/`. Ein Arg: gegen `--`. Zwei Args: `--` gegen `--` | @@ -447,4 +448,4 @@ done - `push.sh` force-pusht — das ist für diesen Schulungsworkflow absichtlich und erwartet. - `--vorlage`-Branches werden von Build-Skripten übersprungen (sie sind absichtlich unvollständig). -- Der `grundlagen/docker`-Branch ist nicht in `$BRANCHES`, wird aber in mehreren Skripten explizit behandelt (`push.sh`, `diff.sh`, `reset.sh`). +- Der `grundlagen/docker`-Branch ist nicht in `$BRANCHES`, ist aber in `$BRANCH_NAMES` (aus `lib.sh`) enthalten und wird so automatisch von `push.sh`, `diff.sh`, `reset.sh` und `copy.sh` mitbehandelt. diff --git a/build.sh b/build.sh index f95b6440..9c803352 100755 --- a/build.sh +++ b/build.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -source branches.sh +source lib.sh # Ohne --publish: nur bauen (kein Docker-Image veröffentlichen) # Mit --publish: bauen und Docker-Image in die Registry schieben diff --git a/copy.sh b/copy.sh index 126e8e7f..d221184b 100755 --- a/copy.sh +++ b/copy.sh @@ -5,7 +5,7 @@ VORLAGEN=../training-exercises/vorlagen LIVECODING=../training-exercises/livecoding MUSTERLOESUNGEN=../training-exercises/spickzettel -source branches.sh +source lib.sh # --tag=: Kopiert den jeweiligen Tag-Stand statt den aktuellen Branch-HEAD # --local: Kopiert lokale Branch-HEADs ohne Remote-Aktualisierung @@ -35,6 +35,7 @@ RSYNC_OPTS=( --exclude=gradle/wrapper/gradle-wrapper.jar --exclude=gradle/wrapper/.gradle-version --exclude=branches.sh + --exclude=lib.sh --exclude=build.sh --exclude=copy.sh --exclude=diff.sh @@ -58,37 +59,20 @@ sync_to() { if [ "$TAG_SUFFIX" = "" ] && ! $LOCAL; then echo "Kein Tag-Suffix angegeben — prüfe einheitliche Tags vor der Aktualisierung auf Remote-Stände..." - - _common_suffixes="" - for i in grundlagen__docker $BRANCHES; do - declare -n _bref=$i - _suffixes=$(git tag -l "${_bref}--*" | sed "s|^${_bref}--||" | sort) - if [ -z "$_suffixes" ]; then - echo "Fehler: Branch '$_bref' hat keine Tags." >&2 - echo " Alle Branches müssen einheitlich getagged sein, bevor auf Remote-Stände aktualisiert wird." >&2 - exit 1 - fi - if [ -z "$_common_suffixes" ]; then - _common_suffixes="$_suffixes" - else - _common_suffixes=$(comm -12 <(echo "$_common_suffixes") <(echo "$_suffixes")) - if [ -z "$_common_suffixes" ]; then - echo "Fehler: Branch '$_bref' hat kein gemeinsames Tag mit allen vorhergehenden Branches." >&2 - echo " Alle Branches müssen einheitlich getagged sein, bevor auf Remote-Stände aktualisiert wird." >&2 - exit 1 - fi - fi - done + _common_suffixes=$(find_common_tag_suffixes) || { + echo " Alle Branches müssen einheitlich getagged sein, bevor auf Remote-Stände aktualisiert wird." >&2 + exit 1 + } + if [ -z "$_common_suffixes" ]; then + echo "Fehler: Kein gemeinsames Tag für alle Branches gefunden." >&2 + echo " Alle Branches müssen einheitlich getagged sein, bevor auf Remote-Stände aktualisiert wird." >&2 + exit 1 + fi echo "Einheitliche Tags vorhanden: $(echo "$_common_suffixes" | tr '\n' ' ')" echo "Aktualisiere alle Branches auf Remote-Stand..." git fetch origin - for i in grundlagen__docker $BRANCHES; do - declare -n _bref=$i - git checkout "$_bref" - git reset --hard "origin/$_bref" - done - git checkout scripting + reset_branches_to_remote fi EXPECTED=$(mktemp) diff --git a/diff.sh b/diff.sh index 664a8673..6517ddf1 100755 --- a/diff.sh +++ b/diff.sh @@ -1,14 +1,13 @@ #!/bin/bash set -e -source branches.sh +source lib.sh # Kein Argument: lokaler Branch gegen origin/ # Ein Argument: lokaler Branch gegen -- # Zwei Argumente: -- gegen -- -for i in grundlagen__docker $BRANCHES; do - declare -n branch=${i} +for branch in "${BRANCH_NAMES[@]}"; do if [ "$1" != "" ] && [ "$2" != "" ]; then echo -e "\nDiff ${branch}--${1} gegen ${branch}--${2}\n" git diff "${branch}--${1}" "${branch}--${2}" diff --git a/lib.sh b/lib.sh new file mode 100755 index 00000000..638efa39 --- /dev/null +++ b/lib.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# Gemeinsame Hilfsfunktionen für alle Verwaltungsskripte. +# Bindet branches.sh ein und stellt $BRANCH_NAMES sowie Hilfsfunktionen bereit. + +source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/branches.sh" + +# Array aller Branch-Namen als Strings (inkl. grundlagen/docker) +BRANCH_NAMES=() +for _i in grundlagen__docker $BRANCHES; do + declare -n _b=$_i + BRANCH_NAMES+=("$_b") + unset -n _b +done + +# Gibt gemeinsame Tag-Suffixe aller Branches auf stdout aus (einen pro Zeile). +# Schlägt mit Fehler fehl, wenn ein Branch keine Tags hat. +# Gibt leere Ausgabe zurück, wenn kein gemeinsames Suffix existiert. +find_common_tag_suffixes() { + local common="" branch suffixes + for branch in "${BRANCH_NAMES[@]}"; do + suffixes=$(git tag -l "${branch}--*" | sed "s|^${branch}--||" | sort) + if [ -z "$suffixes" ]; then + echo "Fehler: Branch '$branch' hat keine Tags." >&2 + return 1 + fi + if [ -z "$common" ]; then + common="$suffixes" + else + common=$(comm -12 <(echo "$common") <(echo "$suffixes")) + fi + done + [ -n "$common" ] && echo "$common" + return 0 +} + +# Setzt alle Branches auf origin/ zurück. +# Erwartet, dass origin aktuell ist — ggf. vorher git fetch origin aufrufen. +# Kehrt am Ende zu scripting zurück. +reset_branches_to_remote() { + local branch + for branch in "${BRANCH_NAMES[@]}"; do + echo -e "\nResetting $branch to origin/$branch" + git checkout "$branch" + git reset --hard "origin/$branch" + done + git checkout scripting +} diff --git a/push.sh b/push.sh index cc8358d8..d289c49c 100755 --- a/push.sh +++ b/push.sh @@ -1,14 +1,7 @@ #!/bin/bash set -e -source branches.sh - -# Build list of all branch names -BRANCH_LIST=() -for i in grundlagen__docker $BRANCHES; do - declare -n _b=${i} - BRANCH_LIST+=("$_b") -done +source lib.sh # Fetch remote tags once to avoid repeated network calls remote_tags=$(git ls-remote --tags origin) @@ -20,7 +13,7 @@ remote_has_tag() { # Step 1: Check if any branch would be rewritten (not just extended) and has no remote tag need_timestamp_backup=false -for branch in "${BRANCH_LIST[@]}"; do +for branch in "${BRANCH_NAMES[@]}"; do remote_commit=$(git rev-parse "refs/remotes/origin/$branch" 2>/dev/null) || continue git rev-parse --verify "$branch" &>/dev/null || continue # Skip if remote would only be extended (fast-forward) @@ -36,7 +29,7 @@ done if [ "$need_timestamp_backup" = true ]; then TIMESTAMP=$(date +%Y%m%d%H%M%S) echo -e "\nCreating backup tags with timestamp $TIMESTAMP in remote..." - for branch in "${BRANCH_LIST[@]}"; do + for branch in "${BRANCH_NAMES[@]}"; do remote_commit=$(git rev-parse "refs/remotes/origin/$branch" 2>/dev/null) || continue tag_name="${branch}--${TIMESTAMP}" echo " Tagging $branch -> $tag_name" @@ -46,26 +39,10 @@ if [ "$need_timestamp_backup" = true ]; then fi # Step 3: Find common local tag suffixes (suffix S where every branch B has local tag B--S) -common_suffixes=() -first_branch="${BRANCH_LIST[0]}" -while IFS= read -r tag; do - prefix="${first_branch}--" - [[ "$tag" == "$prefix"* ]] || continue - suffix="${tag#$prefix}" - all_have=true - for branch in "${BRANCH_LIST[@]}"; do - if ! git rev-parse --verify "${branch}--${suffix}" &>/dev/null; then - all_have=false - break - fi - done - if [ "$all_have" = true ]; then - common_suffixes+=("$suffix") - fi -done < <(git tag) +mapfile -t common_suffixes < <(find_common_tag_suffixes 2>/dev/null || true) # Step 4: Push all branches -for branch in "${BRANCH_LIST[@]}"; do +for branch in "${BRANCH_NAMES[@]}"; do echo -e "\nPushing $branch over origin/$branch" git push --force origin "$branch:$branch" done @@ -74,7 +51,7 @@ done if [ ${#common_suffixes[@]} -gt 0 ]; then echo "" for suffix in "${common_suffixes[@]}"; do - for branch in "${BRANCH_LIST[@]}"; do + for branch in "${BRANCH_NAMES[@]}"; do tag_name="${branch}--${suffix}" if ! echo "$remote_tags" | grep -qF "refs/tags/${tag_name}"; then echo "Pushing tag: $tag_name" diff --git a/reset.sh b/reset.sh index cffbfd55..0ad86566 100755 --- a/reset.sh +++ b/reset.sh @@ -1,20 +1,16 @@ #!/bin/bash set -e -source branches.sh +source lib.sh -[ "$1" = "" ] && echo "No Tag-Prefix specified: Resetting to remote branches" - -for i in grundlagen__docker $BRANCHES; do - declare -n branch=${i} - if [ "$1" = "" ]; then - ref="origin/$branch" - else - ref="${branch}--$1" - fi - echo -e "\nResetting $branch to $ref" - git checkout "$branch" - git reset --hard "$ref" -done - -git checkout scripting +if [ "$1" = "" ]; then + echo "No Tag-Prefix specified: Resetting to remote branches" + reset_branches_to_remote +else + for branch in "${BRANCH_NAMES[@]}"; do + echo -e "\nResetting $branch to ${branch}--$1" + git checkout "$branch" + git reset --hard "${branch}--$1" + done + git checkout scripting +fi