From: Kai Moritz Date: Sun, 31 May 2026 17:32:37 +0000 (+0000) Subject: Skripte: einheitliche --name-value-Parameter, --help, Umstrukturierung X-Git-Tag: scripting--2026-06-04~16 X-Git-Url: http://juplo.de/gitweb/?a=commitdiff_plain;h=54a438f5e059c88ee68bc6693e7c99e8138009f4;p=demos%2Fkafka%2Ftraining Skripte: einheitliche --name-value-Parameter, --help, Umstrukturierung Parameter-Vereinheitlichung (alle Skripte): - Alle Parameter verwenden --name value (Leerzeichen statt =, keine Positional-Argumente mehr): reset.sh --tag, diff.sh --tag/--from/--to, copy.sh --tag/--local - Alle Skripte erhalten --help mit vollständiger Beschreibung Umstrukturierung: - build.sh und patch-nexus.sh aus scripting entfernt; beide operieren auf kopierten Übungsverzeichnissen und gehören zu technik-check--vorlage - copy.sh: --nexus-url entfernt (patch-nexus.sh liegt jetzt in technik-check) - copy.sh: RSYNC_OPTS-Excludes für entfernte Skripte bereinigt CLAUDE.md: - Skript-Tabelle aufgeteilt nach Branch (scripting vs. technik-check--vorlage) - Parameter-Dokumentation entfernt (--help in jedem Skript) - Hinweis ergänzt, dass technik-check-Skripte nach copy.sh bereitstehen Co-Authored-By: Claude Sonnet 4.6 --- diff --git a/CLAUDE.md b/CLAUDE.md index 5f31f24a..4bb7e3a0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -202,31 +202,34 @@ wobei `` mit `pom.xml`s `` (Maven) oder `settings.gradle **Beim Überprüfen oder Rebasen eines Branches immer verifizieren**, dass der Image-Name und die Version in `docker-compose.yml` mit dem übereinstimmen, was die Build-Dateien tatsächlich erzeugen. Abweichungen sind Implementierungsfehler und müssen gekennzeichnet und korrigiert werden. -## Skripte im Scripting-Branch +## Verwaltungsskripte -Alle Skripte binden `lib.sh` ein, das seinerseits `branches.sh` lädt und gemeinsame Funktionen bereitstellt. +### Skripte im `scripting`-Branch + +Alle Skripte binden `lib.sh` ein, das seinerseits `branches.sh` lädt und gemeinsame Funktionen bereitstellt. Alle Skripte unterstützen `--help`. | 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 `--` | -| `build.sh` | Baut alle Branches (erkennt Maven/Gradle automatisch); `--vorlage`-Branches werden übersprungen. Mit `--publish`: Docker-Images veröffentlichen | -| `copy.sh` | Kopiert Branches anhand ihres Suffix in `../training-exercises/vorlagen/`, `../training-exercises/livecoding/` oder `../training-exercises/spickzettel/` (siehe Suffix-Tabelle oben); `--livecoding--schritte`-Branches werden übersprungen. `rsync --delete` ist immer aktiv. Verzeichnisse zu nicht mehr gelisteten Branches werden automatisch bereinigt. Ohne Schalter: aktualisiert zuerst alle Branches auf Remote-Stand (erfordert Remote-Zugriff). Mit `--local`: kopiert lokale Branch-HEADs ohne Remote-Aktualisierung. Mit `--tag=`: kopiert den jeweiligen Tag-Stand. Mit `--nexus-url=` werden Gradle-Setups anschließend für einen internen Nexus gepatcht | -| `patch-nexus.sh` | Patcht `build.gradle` (Nexus als Repository), `settings.gradle` (pluginManagement) und optional mit `--gradle-dist-url=` auch `gradle-wrapper.properties`. Wird aus dem Zielverzeichnis (`../vorlagen/`) aufgerufen | +| `lib.sh` | Shared Library mit `$BRANCH_NAMES`-Array und den Funktionen `find_common_tag_suffixes()` und `reset_branches_to_remote()` | +| `push.sh` | Force-pusht alle Branches und gemeinsame Tags zu origin; legt bei Bedarf TIMESTAMP-Backup-Tags an | +| `reset.sh` | Setzt alle Branches zurück — auf `origin/` oder auf einen Tag-Stand | +| `diff.sh` | Zeigt Diffs aller Branches an — lokal gegen origin, gegen einen Tag-Stand, oder zwei Tag-Stände gegeneinander | +| `copy.sh` | Kopiert alle Branches in die Übungsverzeichnisse (`vorlagen/`, `livecoding/`, `spickzettel/`); bereinigt veraltete Verzeichnisse automatisch | Nach Massenoperationen immer zu `scripting` zurückkehren — Skripte führen am Ende `git checkout scripting` aus. ### Skripte im `springkafka/technik-check--vorlage`-Branch -Dieser Branch enthält zwei zusätzliche Skripte für die Schulungs-Initialisierung: +Diese Skripte operieren auf den **kopierten** Übungsverzeichnissen (nicht auf den Quell-Branches) und liegen daher im `technik-check`-Branch. Nach einem Aufruf von `copy.sh` stehen sie unter `../training-exercises/vorlagen/springkafka/technik-check/` bereit. Alle Skripte unterstützen `--help`. | Skript | Zweck | |--------|-------| -| `init-exercises.sh` | Initialisiert die mit `copy.sh` kopierten Übungsverzeichnisse (`training-exercises/vorlagen/`, `training-exercises/livecoding/`, `training-exercises/spickzettel/`). Standard: `--maven` (entfernt Gradle-Artefakte). Mit `--gradle`: verteilt Gradle-Wrapper (JAR, properties, gradlew) und entfernt Maven-Artefakte. Beide Modi löschen Build-Ausgaben und Caches. Scheitert mit Fehler, wenn `--gradle` verwendet wird, aber der Wrapper noch nicht bereit ist — dann zuerst `README-gradle.sh` ausführen. | -| `README-gradle.sh` | Technik-Check für Gradle: stellt Gradle-Wrapper bereit (lädt ihn herunter, falls fehlend) und führt Build-Test durch. Ohne Schalter: scheitert laut, wenn installierte Version nicht zur benötigten passt. Mit `--update`: ersetzt veralteten Wrapper durch die benötigte Version. | +| `README-maven.sh` | Technik-Check für Maven: führt vollständigen Build- und Starttest durch | +| `README-gradle.sh` | Technik-Check für Gradle: stellt Gradle-Wrapper bereit und führt Build- und Starttest durch | +| `init-exercises.sh` | Initialisiert alle kopierten Übungsverzeichnisse für die Schulung (Maven- oder Gradle-Modus) | +| `build.sh` | Baut alle Musterlösungen aus `spickzettel/`; erkennt Maven/Gradle anhand des vorhandenen Build-Setups | +| `patch-nexus.sh` | Patcht Gradle-Setups für einen internen Nexus-Mirror; Aufruf aus dem Vorlagen-Wurzelverzeichnis | `gradle-wrapper.jar` ist absichtlich nicht im Repository (wird von Unternehmens-Mail-Filtern blockiert). `gradlew` und `gradle/wrapper/gradle-wrapper.properties` sind versioniert und definieren die maßgebliche Gradle-Version für alle Übungen der Schulung. Der Versions-Marker `gradle/wrapper/.gradle-version` ist gitignoriert. @@ -447,5 +450,5 @@ done ## Wesentliche Einschränkungen - `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). +- `--vorlage`-Branches werden von `copy.sh` in `vorlagen/` kopiert; das neue `build.sh` in `technik-check` baut nur Musterlösungen aus `spickzettel/` und überspringt diese damit automatisch. - 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 deleted file mode 100755 index 9c803352..00000000 --- a/build.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash -set -e - -source lib.sh - -# Ohne --publish: nur bauen (kein Docker-Image veröffentlichen) -# Mit --publish: bauen und Docker-Image in die Registry schieben -PUBLISH=false -[ "$1" = "--publish" ] && PUBLISH=true - -for i in $BRANCHES; do - declare -n branch=${i} - git checkout "$branch" - - if [[ "$branch" == *--vorlage ]]; then - echo -e "\nIgnoriere Vorlage: $branch\n" - continue - fi - - if [ -e 'pom.xml' ]; then - echo -e "\nBaue $branch (Maven)" - mvn clean install - if $PUBLISH; then - echo -e "\nVeröffentliche Docker-Image für $branch" - if [[ "$branch" == grundlagen/* ]]; then - mvn jib:build - else - mvn spring-boot:build-image -Dspring-boot.build-image.publish=true - fi - fi - elif [ -e 'build.gradle' ]; then - echo -e "\nBaue $branch (Gradle)" - [ -f bootstrap-gradle.sh ] && ./bootstrap-gradle.sh - ./gradlew build - if $PUBLISH; then - echo -e "\nVeröffentliche Docker-Image für $branch" - ./gradlew bootBuildImage --publishImage - fi - else - echo -e "\nIgnoriere Branch ohne Build-Dateien: $branch\n" - fi -done - -git checkout scripting diff --git a/copy.sh b/copy.sh index d221184b..3c44a954 100755 --- a/copy.sh +++ b/copy.sh @@ -7,23 +7,31 @@ MUSTERLOESUNGEN=../training-exercises/spickzettel source lib.sh -# --tag=: Kopiert den jeweiligen Tag-Stand statt den aktuellen Branch-HEAD -# --local: Kopiert lokale Branch-HEADs ohne Remote-Aktualisierung -# --nexus-url=: Ruft patch-nexus.sh auf die Vorlagen an TAG_SUFFIX="" -NEXUS_URL="" LOCAL=false -for arg in "$@"; do - case "$arg" in - --tag=*) TAG_SUFFIX="${arg#--tag=}" ;; - --nexus-url=*) NEXUS_URL="${arg#--nexus-url=}" ;; - --local) LOCAL=true ;; - *) echo "Unbekannter Parameter: $arg"; exit 1 ;; +while [ $# -gt 0 ]; do + case "$1" in + --tag) + [ -n "$2" ] || { echo "Fehler: --tag erfordert einen Wert" >&2; exit 1; } + TAG_SUFFIX="$2"; shift 2 ;; + --local) + LOCAL=true; shift ;; + --help) + echo "Kopiert alle Branches in die Übungsverzeichnisse." + echo "" + echo "Verwendung: ./copy.sh [OPTIONEN] [--help]" + echo "" + echo " --tag Kopiert den jeweiligen Tag-Stand statt den Branch-HEAD" + echo " --local Kopiert lokale Branch-HEADs ohne Remote-Aktualisierung" + echo " --help Diese Hilfe anzeigen" + echo "" + echo "Ohne --tag und ohne --local: Aktualisiert alle Branches zuerst auf Remote-Stand" + echo "(erfordert Remote-Zugriff und einheitliche Tags über alle Branches)." + exit 0 ;; + *) echo "Unbekannter Parameter: $1" >&2; exit 1 ;; esac done -SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" - RSYNC_OPTS=( rsync -av --delete @@ -36,10 +44,8 @@ RSYNC_OPTS=( --exclude=gradle/wrapper/.gradle-version --exclude=branches.sh --exclude=lib.sh - --exclude=build.sh --exclude=copy.sh --exclude=diff.sh - --exclude=patch-nexus.sh --exclude=push.sh --exclude=reset.sh ) @@ -58,7 +64,7 @@ sync_to() { } if [ "$TAG_SUFFIX" = "" ] && ! $LOCAL; then - echo "Kein Tag-Suffix angegeben — prüfe einheitliche Tags vor der Aktualisierung auf Remote-Stände..." + echo "Kein --tag angegeben — prüfe einheitliche Tags vor der Aktualisierung auf Remote-Stände..." _common_suffixes=$(find_common_tag_suffixes) || { echo " Alle Branches müssen einheitlich getagged sein, bevor auf Remote-Stände aktualisiert wird." >&2 exit 1 @@ -115,9 +121,4 @@ for base in "$VORLAGEN" "$LIVECODING" "$MUSTERLOESUNGEN"; do done < <(find "$base" -mindepth 2 -maxdepth 2 -type d | sort) done -if [ "$NEXUS_URL" != "" ]; then - echo -e "\nPatche Gradle-Setups für Nexus: $NEXUS_URL" - (cd "$VORLAGEN" && "$SCRIPT_DIR/patch-nexus.sh" "$NEXUS_URL") -fi - git checkout scripting diff --git a/diff.sh b/diff.sh index 6517ddf1..8c22cc99 100755 --- a/diff.sh +++ b/diff.sh @@ -3,17 +3,51 @@ set -e source lib.sh -# Kein Argument: lokaler Branch gegen origin/ -# Ein Argument: lokaler Branch gegen -- -# Zwei Argumente: -- gegen -- +TAG="" +FROM="" +TO="" +while [ $# -gt 0 ]; do + case "$1" in + --tag) + [ -n "$2" ] || { echo "Fehler: --tag erfordert einen Wert" >&2; exit 1; } + TAG="$2"; shift 2 ;; + --from) + [ -n "$2" ] || { echo "Fehler: --from erfordert einen Wert" >&2; exit 1; } + FROM="$2"; shift 2 ;; + --to) + [ -n "$2" ] || { echo "Fehler: --to erfordert einen Wert" >&2; exit 1; } + TO="$2"; shift 2 ;; + --help) + echo "Zeigt Diffs aller Branches an." + echo "" + echo "Verwendung: ./diff.sh [OPTIONEN] [--help]" + echo "" + echo " Ohne Optionen: lokaler Branch gegen origin/" + echo " --tag lokaler Branch gegen --" + echo " --from --to -- gegen --" + echo " --help Diese Hilfe anzeigen" + exit 0 ;; + *) echo "Unbekannter Parameter: $1" >&2; exit 1 ;; + esac +done + +if [ -n "$FROM" ] && [ -z "$TO" ]; then + echo "Fehler: --from erfordert auch --to" >&2; exit 1 +fi +if [ -n "$TO" ] && [ -z "$FROM" ]; then + echo "Fehler: --to erfordert auch --from" >&2; exit 1 +fi +if [ -n "$TAG" ] && [ -n "$FROM" ]; then + echo "Fehler: --tag und --from/--to schließen sich aus" >&2; exit 1 +fi 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}" - elif [ "$1" != "" ]; then - echo -e "\nDiff $branch gegen ${branch}--${1}\n" - git diff "${branch}--${1}" "$branch" + if [ -n "$FROM" ]; then + echo -e "\nDiff ${branch}--${FROM} gegen ${branch}--${TO}\n" + git diff "${branch}--${FROM}" "${branch}--${TO}" + elif [ -n "$TAG" ]; then + echo -e "\nDiff $branch gegen ${branch}--${TAG}\n" + git diff "${branch}--${TAG}" "$branch" else echo -e "\nDiff $branch gegen origin/$branch\n" git diff "origin/$branch" "$branch" diff --git a/patch-nexus.sh b/patch-nexus.sh deleted file mode 100755 index 4a1a41b0..00000000 --- a/patch-nexus.sh +++ /dev/null @@ -1,103 +0,0 @@ -#!/bin/bash -set -e - -# Passt Gradle-Setups an einen internen Nexus-Mirror an. -# Aufruf (aus dem Zielverzeichnis, z.B. ../vorlagen/): -# -# patch-nexus.sh [--gradle-dist-url=] -# -# Ohne --gradle-dist-url bleibt gradle-wrapper.properties unverändert. -# Falls Gradle-Distributionen ebenfalls über Nexus bereitgestellt werden, -# muss dort ein "raw proxy"-Repository auf services.gradle.org/distributions/ -# eingerichtet sein. - -if [ "$1" = "" ]; then - echo "Aufruf: $(basename "$0") [--gradle-dist-url=]" - echo "" - echo "Beispiel:" - echo " $(basename "$0") https://nexus.example.com/repository/maven-public/" - echo " $(basename "$0") https://nexus.example.com/repository/maven-public/ \\" - echo " --gradle-dist-url=https://nexus.example.com/repository/gradle-distributions/" - exit 1 -fi - -NEXUS_URL="$1" -GRADLE_DIST_URL="" -for arg in "${@:2}"; do - case "$arg" in - --gradle-dist-url=*) GRADLE_DIST_URL="${arg#--gradle-dist-url=}" ;; - *) echo "Unbekannter Parameter: $arg"; exit 1 ;; - esac -done - -TMP_REPO_BLOCK=$(mktemp) -TMP_PLUGIN_BLOCK=$(mktemp) - -cat > "$TMP_REPO_BLOCK" < "$TMP_PLUGIN_BLOCK" < "$file.tmp" && mv "$file.tmp" "$file" - else - cat "$TMP_REPO_BLOCK" "$file" > "$file.tmp" && mv "$file.tmp" "$file" - fi -done - -echo "Bearbeite settings.gradle-Dateien..." -for file in */*/settings.gradle; do - [ -f "$file" ] || continue - echo " $file" - if ! grep -q 'pluginManagement' "$file"; then - cat "$TMP_PLUGIN_BLOCK" "$file" > "$file.tmp" && mv "$file.tmp" "$file" - else - echo " (pluginManagement bereits vorhanden -- uebersprungen)" - fi -done - -if [ "$GRADLE_DIST_URL" != "" ]; then - echo "Bearbeite gradle-wrapper.properties-Dateien..." - for file in */*/gradle/wrapper/gradle-wrapper.properties; do - [ -f "$file" ] || continue - echo " $file" - # In .properties-Dateien muss ':' als '\:' escaped werden; awk erledigt das sauber - awk -v url="$GRADLE_DIST_URL" ' - BEGIN { gsub(/:/, "\\:", url) } - /^distributionUrl=/ { print "distributionUrl=" url; next } - { print } - ' "$file" > "$file.tmp" && mv "$file.tmp" "$file" - done -fi - -rm -f "$TMP_REPO_BLOCK" "$TMP_PLUGIN_BLOCK" -echo "Fertig." diff --git a/push.sh b/push.sh index d289c49c..6d6dd80b 100755 --- a/push.sh +++ b/push.sh @@ -3,6 +3,24 @@ set -e source lib.sh +for arg in "$@"; do + case "$arg" in + --help) + echo "Force-pusht alle Branches zu origin." + echo "Prüft vorab, ob umzuschreibende Remote-Stände bereits gesichert sind;" + echo "fehlt ein Tag, werden TIMESTAMP-Backup-Tags für alle Remote-Stände im Remote angelegt." + echo "Gemeinsame lokale Tag-Suffixe (z.B. --claude-5 für alle Branches) werden ebenfalls gepusht," + echo "sofern noch nicht im Remote vorhanden." + echo "" + echo "Verwendung: ./push.sh [--help]" + echo "" + echo " --help Diese Hilfe anzeigen" + exit 0 + ;; + *) echo "Unbekannter Parameter: $arg" >&2; exit 1 ;; + esac +done + # Fetch remote tags once to avoid repeated network calls remote_tags=$(git ls-remote --tags origin) diff --git a/reset.sh b/reset.sh index 0ad86566..98f6dadd 100755 --- a/reset.sh +++ b/reset.sh @@ -3,14 +3,33 @@ set -e source lib.sh -if [ "$1" = "" ]; then - echo "No Tag-Prefix specified: Resetting to remote branches" +TAG="" +while [ $# -gt 0 ]; do + case "$1" in + --tag) + [ -n "$2" ] || { echo "Fehler: --tag erfordert einen Wert" >&2; exit 1; } + TAG="$2"; shift 2 ;; + --help) + echo "Setzt alle Branches zurück." + echo "" + echo "Verwendung: ./reset.sh [--tag ] [--help]" + echo "" + echo " --tag Setzt alle Branches auf -- zurück" + echo " Ohne --tag: Setzt auf origin/ zurück (erfordert Remote-Zugriff)" + echo " --help Diese Hilfe anzeigen" + exit 0 ;; + *) echo "Unbekannter Parameter: $1" >&2; exit 1 ;; + esac +done + +if [ -z "$TAG" ]; then + echo "Kein --tag angegeben: Setze alle Branches auf Remote-Stand zurück" reset_branches_to_remote else for branch in "${BRANCH_NAMES[@]}"; do - echo -e "\nResetting $branch to ${branch}--$1" + echo -e "\nResetting $branch to ${branch}--${TAG}" git checkout "$branch" - git reset --hard "${branch}--$1" + git reset --hard "${branch}--${TAG}" done git checkout scripting fi