S06: Tooling-Fix: checkpoint.ps1 robust gegen problematische Eingabedaten gemacht. Commit-Message wird jetzt via Temp-Datei und git commit -F uebergeben statt via -m mit String, damit doppelte Anfuehrungszeichen im Summary nicht mehr das Argument zerlegen (Ursache des fehlgeschlagenen Hotfix-Commits zuvor). Pipe-Zeichen im Summary werden vorab abgelehnt, da sie mit dem Changelog-Format Timestamp Pipe Session Pipe Summary kollidieren. Whitespace und Zeilenumbrueche im Summary werden zu einem einzelnen Leerzeichen normalisiert. Pre-flight-Checks ergaenzt: Existenz von .git, verwaiste .git/index.lock mit klarer Anleitung melden, changelog.md muss vor dem Lauf clean sein. Atomarer Rollback bei Fehler im Hauptablauf: changelog.md wird auf Original-Stand zurueckgeschrieben und Index-Stagung von changelog.md per git restore --staged oder git reset HEAD zurueckgesetzt, sodass der naechste Lauf nicht doppelt anhaengt. Cleanup-Robustheit: Temp-Message-Datei wird in finally geloescht, das Loeschen der Pending-Datei ist nicht mehr fatal sondern nur eine Warnung.

This commit is contained in:
tlg
2026-04-25 22:35:35 +02:00
parent 80a0323996
commit 24ff8ad48e
3 changed files with 134 additions and 39 deletions

View File

@@ -1,6 +1,8 @@
S06 S06
PDF-Build-Hotfix nach erstem Build der Tabellen-Revision: LuaLaTeX schlug in der Tabellen-Spaltenangabe mit der Meldung ueber einen nicht definierten Counter none fehl, weil Thomas Pandoc-Version (3.x) calc-basierte Spaltenbreiten der Form p von Klammer Spaltenbreite minus 2 mal tabcolsep Klammerzu mal real Faktor emittiert und das Template weder das calc-Paket noch das Pandoc-Hilfsmakro real bereitstellte (Sandbox-Pandoc 2.9 emittiert die simplere ll-Spaltenform und hat den Fehler nicht reproduziert). Tooling-Fix: checkpoint.ps1 robust gegen problematische Eingabedaten gemacht.
templates/template.tex Tabellen-Block ergaenzt um usepackage array, usepackage calc und providecommand real. Commit-Message wird jetzt via Temp-Datei und git commit -F uebergeben statt via -m mit String, damit doppelte Anfuehrungszeichen im Summary nicht mehr das Argument zerlegen (Ursache des fehlgeschlagenen Hotfix-Commits zuvor).
Sandbox-Verifikation: synthetischer Pandoc-3.x-Spalten-Output kompiliert mit dem erweiterten Template via LuaLaTeX zu PDF, nur eine harmlose longtable-Rerun-Warnung. Pipe-Zeichen im Summary werden vorab abgelehnt, da sie mit dem Changelog-Format Timestamp Pipe Session Pipe Summary kollidieren.
DOCX nach Tabellen-Revision von Thomas visuell bestaetigt (Tabelle sieht gut aus, nur Default-Word-Tabellenrahmenlinien noch da, Rahmen-Aus in Iteration B). Whitespace und Zeilenumbrueche im Summary werden zu einem einzelnen Leerzeichen normalisiert.
teilgebiete/01-lebenslauf.md und agent-prompt.md um Hotfix-Eintrag und DOCX-Bestaetigung ergaenzt. Pre-flight-Checks ergaenzt: Existenz von .git, verwaiste .git/index.lock mit klarer Anleitung melden, changelog.md muss vor dem Lauf clean sein.
Atomarer Rollback bei Fehler im Hauptablauf: changelog.md wird auf Original-Stand zurueckgeschrieben und Index-Stagung von changelog.md per git restore --staged oder git reset HEAD zurueckgesetzt, sodass der naechste Lauf nicht doppelt anhaengt.
Cleanup-Robustheit: Temp-Message-Datei wird in finally geloescht, das Loeschen der Pending-Datei ist nicht mehr fatal sondern nur eine Warnung.

View File

@@ -40,3 +40,4 @@ Chronologisches Log aller Entscheidungen und Prozessereignisse.
2026-04-25 14:28 | S06 | Teilgebiet 01 Iteration A abgeschlossen: Ausbildung als 2-Spalten-Layout via Pandoc-Definition-List umgesetzt. source/cv.md Ausbildungs-Abschnitt auf Term/Definition-Syntax umgestellt (Datum als Term, Inhalt als Definition). templates/template.tex um enumitem-Konfiguration der description-Liste erweitert (style=multiline, labelwidth=5.5em, leftmargin=6.5em, font=\normalfont). Sandbox-Verifikation: Pandoc-LaTeX rendert sauberes \begin{description} mit vier Eintraegen, Pandoc-DOCX nutzt die Standardstile DefinitionTerm und Definition (in Iteration B in Word zu stylen). Hinweis: Pandoc setzt \tightlist innerhalb der Description-Liste und ueberschreibt damit zur Laufzeit das itemsep auf 0 — fuer vier kurze Eintraege visuell vertretbar. teilgebiete/01-lebenslauf.md um Iteration-A-Block ergaenzt und Naechste-Schritte-Liste auf B/C/D reduziert. agent-prompt.md Aktueller-Stand-Abschnitt auf S06 fortgeschrieben. 2026-04-25 14:28 | S06 | Teilgebiet 01 Iteration A abgeschlossen: Ausbildung als 2-Spalten-Layout via Pandoc-Definition-List umgesetzt. source/cv.md Ausbildungs-Abschnitt auf Term/Definition-Syntax umgestellt (Datum als Term, Inhalt als Definition). templates/template.tex um enumitem-Konfiguration der description-Liste erweitert (style=multiline, labelwidth=5.5em, leftmargin=6.5em, font=\normalfont). Sandbox-Verifikation: Pandoc-LaTeX rendert sauberes \begin{description} mit vier Eintraegen, Pandoc-DOCX nutzt die Standardstile DefinitionTerm und Definition (in Iteration B in Word zu stylen). Hinweis: Pandoc setzt \tightlist innerhalb der Description-Liste und ueberschreibt damit zur Laufzeit das itemsep auf 0 — fuer vier kurze Eintraege visuell vertretbar. teilgebiete/01-lebenslauf.md um Iteration-A-Block ergaenzt und Naechste-Schritte-Liste auf B/C/D reduziert. agent-prompt.md Aktueller-Stand-Abschnitt auf S06 fortgeschrieben.
2026-04-25 20:58 | S06 | Iteration A revidiert: Ausbildungs-Layout von Definition-List auf Pandoc-Multiline-Tabelle umgestellt, weil Definition-List im DOCX kein echtes 2-Spalten-Layout liefert (Word kann Term und Definition als zwei Absatzstile nicht in eine Zeile zwingen). source/cv.md Ausbildungs-Abschnitt nutzt jetzt headerless Multiline-Tabelle mit Strich-Verhaeltnis 10:70 (Pandoc berechnet Spaltenbreiten von ca. 14 Prozent und 80 Prozent der Textbreite). templates/template.tex Description-List-Block wieder entfernt; neuer Tabellen-Block mit booktabs und longtable, Linienbreiten und Rule-Separations auf 0pt, LTpre/LTpost auf 0.4em. Sandbox-Verifikation: Pandoc-LaTeX rendert longtable mit Minipage-Auto-Wrap und vier Datenzeilen, Pandoc-DOCX rendert eine native Word-Tabelle mit vier Zeilen und acht Zellen, keine Reste der Definition-List-Stile. teilgebiete/01-lebenslauf.md Iteration-A-Block umgeschrieben mit Begruendung der Revision und Beschreibung des neuen Setups. agent-prompt.md Aktueller-Stand-Abschnitt auf die Tabellen-Variante fortgeschrieben. 2026-04-25 20:58 | S06 | Iteration A revidiert: Ausbildungs-Layout von Definition-List auf Pandoc-Multiline-Tabelle umgestellt, weil Definition-List im DOCX kein echtes 2-Spalten-Layout liefert (Word kann Term und Definition als zwei Absatzstile nicht in eine Zeile zwingen). source/cv.md Ausbildungs-Abschnitt nutzt jetzt headerless Multiline-Tabelle mit Strich-Verhaeltnis 10:70 (Pandoc berechnet Spaltenbreiten von ca. 14 Prozent und 80 Prozent der Textbreite). templates/template.tex Description-List-Block wieder entfernt; neuer Tabellen-Block mit booktabs und longtable, Linienbreiten und Rule-Separations auf 0pt, LTpre/LTpost auf 0.4em. Sandbox-Verifikation: Pandoc-LaTeX rendert longtable mit Minipage-Auto-Wrap und vier Datenzeilen, Pandoc-DOCX rendert eine native Word-Tabelle mit vier Zeilen und acht Zellen, keine Reste der Definition-List-Stile. teilgebiete/01-lebenslauf.md Iteration-A-Block umgeschrieben mit Begruendung der Revision und Beschreibung des neuen Setups. agent-prompt.md Aktueller-Stand-Abschnitt auf die Tabellen-Variante fortgeschrieben.
2026-04-25 22:15 | S06 | PDF-Build-Hotfix nach erstem Build der Tabellen-Revision: LuaLaTeX schlug in der Tabellen-Spaltenangabe mit der Meldung ueber einen nicht definierten Counter none fehl, weil Thomas Pandoc-Version (3.x) calc-basierte Spaltenbreiten der Form p von Klammer Spaltenbreite minus 2 mal tabcolsep Klammerzu mal real Faktor emittiert und das Template weder das calc-Paket noch das Pandoc-Hilfsmakro real bereitstellte (Sandbox-Pandoc 2.9 emittiert die simplere ll-Spaltenform und hat den Fehler nicht reproduziert). templates/template.tex Tabellen-Block ergaenzt um usepackage array, usepackage calc und providecommand real. Sandbox-Verifikation: synthetischer Pandoc-3.x-Spalten-Output kompiliert mit dem erweiterten Template via LuaLaTeX zu PDF, nur eine harmlose longtable-Rerun-Warnung. DOCX nach Tabellen-Revision von Thomas visuell bestaetigt (Tabelle sieht gut aus, nur Default-Word-Tabellenrahmenlinien noch da, Rahmen-Aus in Iteration B). teilgebiete/01-lebenslauf.md und agent-prompt.md um Hotfix-Eintrag und DOCX-Bestaetigung ergaenzt. 2026-04-25 22:15 | S06 | PDF-Build-Hotfix nach erstem Build der Tabellen-Revision: LuaLaTeX schlug in der Tabellen-Spaltenangabe mit der Meldung ueber einen nicht definierten Counter none fehl, weil Thomas Pandoc-Version (3.x) calc-basierte Spaltenbreiten der Form p von Klammer Spaltenbreite minus 2 mal tabcolsep Klammerzu mal real Faktor emittiert und das Template weder das calc-Paket noch das Pandoc-Hilfsmakro real bereitstellte (Sandbox-Pandoc 2.9 emittiert die simplere ll-Spaltenform und hat den Fehler nicht reproduziert). templates/template.tex Tabellen-Block ergaenzt um usepackage array, usepackage calc und providecommand real. Sandbox-Verifikation: synthetischer Pandoc-3.x-Spalten-Output kompiliert mit dem erweiterten Template via LuaLaTeX zu PDF, nur eine harmlose longtable-Rerun-Warnung. DOCX nach Tabellen-Revision von Thomas visuell bestaetigt (Tabelle sieht gut aus, nur Default-Word-Tabellenrahmenlinien noch da, Rahmen-Aus in Iteration B). teilgebiete/01-lebenslauf.md und agent-prompt.md um Hotfix-Eintrag und DOCX-Bestaetigung ergaenzt.
2026-04-25 22:35 | S06 | Tooling-Fix: checkpoint.ps1 robust gegen problematische Eingabedaten gemacht. Commit-Message wird jetzt via Temp-Datei und git commit -F uebergeben statt via -m mit String, damit doppelte Anfuehrungszeichen im Summary nicht mehr das Argument zerlegen (Ursache des fehlgeschlagenen Hotfix-Commits zuvor). Pipe-Zeichen im Summary werden vorab abgelehnt, da sie mit dem Changelog-Format Timestamp Pipe Session Pipe Summary kollidieren. Whitespace und Zeilenumbrueche im Summary werden zu einem einzelnen Leerzeichen normalisiert. Pre-flight-Checks ergaenzt: Existenz von .git, verwaiste .git/index.lock mit klarer Anleitung melden, changelog.md muss vor dem Lauf clean sein. Atomarer Rollback bei Fehler im Hauptablauf: changelog.md wird auf Original-Stand zurueckgeschrieben und Index-Stagung von changelog.md per git restore --staged oder git reset HEAD zurueckgesetzt, sodass der naechste Lauf nicht doppelt anhaengt. Cleanup-Robustheit: Temp-Message-Datei wird in finally geloescht, das Loeschen der Pending-Datei ist nicht mehr fatal sondern nur eine Warnung.

View File

@@ -5,23 +5,68 @@
# .checkpoint-pending.txt, haengt einen Eintrag an changelog.md # .checkpoint-pending.txt, haengt einen Eintrag an changelog.md
# an (mit aktuellem Timestamp vom lokalen PC), fuehrt einen # an (mit aktuellem Timestamp vom lokalen PC), fuehrt einen
# Git-Commit aus und loescht die Pending-Datei. # Git-Commit aus und loescht die Pending-Datei.
#
# Robust gegen problematische Eingabedaten:
# - Doppelte Anfuehrungszeichen in der Zusammenfassung werden
# sauber durchgereicht, weil die Commit-Message via
# "git commit -F <tempfile>" uebergeben wird (keine
# Shell-Argument-Quoting-Probleme).
# - Pipe-Zeichen "|" in der Zusammenfassung werden abgelehnt,
# weil sie mit dem Changelog-Format
# Timestamp | Session | Summary kollidieren.
# - Whitespace und Zeilenumbrueche in der Zusammenfassung
# werden zu einem Leerzeichen normalisiert.
# - Bei Fehler im Hauptablauf wird der Anhang an changelog.md
# und die Index-Stagung von changelog.md zurueckgerollt,
# sodass der naechste Lauf nicht doppelt anhaengt.
# - Eine verwaiste .git/index.lock wird vor dem Lauf erkannt
# und mit klarer Anleitung gemeldet.
# ============================================================ # ============================================================
$ErrorActionPreference = 'Stop' $ErrorActionPreference = 'Stop'
# Repo-Root = Ordner, in dem dieses Skript liegt # --- Pfade -------------------------------------------------
$repoRoot = $PSScriptRoot $repoRoot = $PSScriptRoot
Set-Location $repoRoot Set-Location $repoRoot
$pendingFile = Join-Path $repoRoot '.checkpoint-pending.txt' $pendingFile = Join-Path $repoRoot '.checkpoint-pending.txt'
$changelogFile = Join-Path $repoRoot 'changelog.md' $changelogFile = Join-Path $repoRoot 'changelog.md'
$gitDir = Join-Path $repoRoot '.git'
$indexLock = Join-Path $gitDir 'index.lock'
# --- Pending-Datei lesen ----------------------------------- $utf8NoBom = New-Object System.Text.UTF8Encoding $false
# --- Pre-flight Checks -------------------------------------
if (-not (Test-Path $pendingFile)) { if (-not (Test-Path $pendingFile)) {
Write-Error ".checkpoint-pending.txt nicht gefunden." Write-Error ".checkpoint-pending.txt nicht gefunden."
exit 1 exit 1
} }
if (-not (Test-Path $changelogFile)) {
Write-Error "changelog.md nicht gefunden."
exit 1
}
if (-not (Test-Path $gitDir)) {
Write-Error ".git-Verzeichnis nicht gefunden ($gitDir)."
exit 1
}
if (Test-Path $indexLock) {
Write-Error ".git/index.lock existiert bereits. Eine vorherige Git-Operation hat sich nicht aufgeraeumt. Falls kein Git-Prozess mehr laeuft, manuell loeschen: Remove-Item '$indexLock' -Force"
exit 1
}
# changelog.md darf vor dem Lauf keine lokalen Aenderungen haben,
# damit ein eventueller Rollback eindeutig bleibt.
$clStatus = & git status --porcelain -- changelog.md 2>$null
if ($LASTEXITCODE -ne 0) {
Write-Error "git status fehlgeschlagen (Exit Code $LASTEXITCODE). Liegt das Repo in einem konsistenten Zustand vor?"
exit 1
}
if ($null -ne $clStatus -and ($clStatus -join '').Trim() -ne '') {
Write-Error "changelog.md hat lokale Aenderungen. Bitte erst per Hand committen oder mit 'git checkout -- changelog.md' verwerfen, bevor checkpoint.cmd laeuft."
exit 1
}
# --- Pending-Datei einlesen --------------------------------
$lines = Get-Content $pendingFile -Encoding UTF8 $lines = Get-Content $pendingFile -Encoding UTF8
if ($lines.Count -lt 2) { if ($lines.Count -lt 2) {
Write-Error ".checkpoint-pending.txt muss mindestens 2 Zeilen enthalten (Session, Zusammenfassung)." Write-Error ".checkpoint-pending.txt muss mindestens 2 Zeilen enthalten (Session, Zusammenfassung)."
@@ -29,8 +74,10 @@ if ($lines.Count -lt 2) {
} }
$session = $lines[0].Trim() $session = $lines[0].Trim()
$summary = ($lines | Select-Object -Skip 1 | Where-Object { $_.Trim() -ne '' }) -join ' ' $summaryLines = $lines | Select-Object -Skip 1 | Where-Object { $_.Trim() -ne '' }
$summary = $summary.Trim() $summary = ($summaryLines -join ' ')
# Whitespace und Steuerzeichen normalisieren
$summary = ($summary -replace '\s+', ' ').Trim()
if ([string]::IsNullOrWhiteSpace($session)) { if ([string]::IsNullOrWhiteSpace($session)) {
Write-Error "Session-Nummer (Zeile 1) ist leer." Write-Error "Session-Nummer (Zeile 1) ist leer."
@@ -44,49 +91,94 @@ if ([string]::IsNullOrWhiteSpace($summary)) {
Write-Error "Zusammenfassung (Zeile 2+) ist leer." Write-Error "Zusammenfassung (Zeile 2+) ist leer."
exit 1 exit 1
} }
if ($summary -match '\|') {
Write-Error "Zusammenfassung enthaelt das Pipe-Zeichen '|', das mit dem Changelog-Format Timestamp | Session | Summary kollidiert. Bitte ersetzen."
exit 1
}
# --- Timestamp und Eintrag bauen --------------------------- # --- Timestamp und Eintrag bauen ---------------------------
$timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm' $timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm'
$entry = "$timestamp | $session | $summary" $entry = "$timestamp | $session | $summary"
$commitMsg = "${session}: $summary"
Write-Host "" Write-Host ""
Write-Host "[checkpoint] Neuer Eintrag:" -ForegroundColor Cyan Write-Host "[checkpoint] Neuer Eintrag:" -ForegroundColor Cyan
Write-Host " $entry" Write-Host " $entry"
Write-Host "" Write-Host ""
# --- Eintrag an changelog.md anhaengen --------------------- # --- Backup fuer Rollback und Temp-Message-Datei -----------
# Immer erst sicherstellen, dass die Datei mit einem Zeilenumbruch endet. $originalChangelog = [System.IO.File]::ReadAllText($changelogFile, $utf8NoBom)
$utf8NoBom = New-Object System.Text.UTF8Encoding $false $tempMsgFile = Join-Path ([System.IO.Path]::GetTempPath()) ("checkpoint-msg-" + [guid]::NewGuid().ToString() + ".txt")
if (Test-Path $changelogFile) { # --- Hauptablauf -------------------------------------------
$existing = [System.IO.File]::ReadAllText($changelogFile, $utf8NoBom) $success = $false
if ($existing.Length -gt 0 -and -not ($existing.EndsWith("`n"))) { $errorMsg = $null
try {
# 1. Sicherstellen, dass changelog.md mit Newline endet
if ($originalChangelog.Length -gt 0 -and -not ($originalChangelog.EndsWith("`n"))) {
[System.IO.File]::AppendAllText($changelogFile, "`r`n", $utf8NoBom) [System.IO.File]::AppendAllText($changelogFile, "`r`n", $utf8NoBom)
} }
} else {
Write-Error "changelog.md nicht gefunden." # 2. Eintrag anhaengen
[System.IO.File]::AppendAllText($changelogFile, $entry + "`r`n", $utf8NoBom)
Write-Host "[checkpoint] An changelog.md angehaengt." -ForegroundColor Green
# 3. Commit-Message-Datei schreiben (UTF-8 ohne BOM)
[System.IO.File]::WriteAllText($tempMsgFile, $commitMsg + "`n", $utf8NoBom)
# 4. git add -A
& git add -A
if ($LASTEXITCODE -ne 0) {
throw "git add fehlgeschlagen (Exit Code $LASTEXITCODE)."
}
# 5. git commit -F <tempfile> (umgeht Shell-Argument-Quoting)
& git commit -F $tempMsgFile
if ($LASTEXITCODE -ne 0) {
throw "git commit fehlgeschlagen (Exit Code $LASTEXITCODE)."
}
Write-Host "[checkpoint] Commit erstellt: $commitMsg" -ForegroundColor Green
$success = $true
}
catch {
$errorMsg = $_.Exception.Message
}
finally {
# Temp-Message-Datei aufraeumen
if (Test-Path $tempMsgFile) {
Remove-Item $tempMsgFile -Force -ErrorAction SilentlyContinue
}
}
if (-not $success) {
Write-Host ""
Write-Host "[checkpoint] FEHLER: $errorMsg" -ForegroundColor Red
Write-Host "[checkpoint] Rollback wird ausgefuehrt..." -ForegroundColor Yellow
# changelog.md auf Original-Stand zurueckschreiben
try {
[System.IO.File]::WriteAllText($changelogFile, $originalChangelog, $utf8NoBom)
Write-Host "[checkpoint] changelog.md auf Original-Stand zurueckgerollt." -ForegroundColor Yellow
} catch {
Write-Host "[checkpoint] WARNUNG: Rollback von changelog.md fehlgeschlagen ($($_.Exception.Message))." -ForegroundColor Red
}
# Index-Stagung fuer changelog.md auf HEAD zuruecksetzen
& git restore --staged -- changelog.md 2>$null | Out-Null
if ($LASTEXITCODE -ne 0) {
# Fallback fuer aelteres Git ohne 'restore'
& git reset HEAD -- changelog.md 2>$null | Out-Null
}
Write-Host "[checkpoint] FEHLGESCHLAGEN - .checkpoint-pending.txt bleibt erhalten fuer einen erneuten Lauf." -ForegroundColor Red
exit 1 exit 1
} }
[System.IO.File]::AppendAllText($changelogFile, $entry + "`r`n", $utf8NoBom) # --- Pending-Datei loeschen (nicht fatal wenn das fehlschlaegt) ---
Write-Host "[checkpoint] An changelog.md angehaengt." -ForegroundColor Green try {
Remove-Item $pendingFile -Force
# --- Git add + commit -------------------------------------- Write-Host "[checkpoint] .checkpoint-pending.txt entfernt." -ForegroundColor Green
& git add -A } catch {
if ($LASTEXITCODE -ne 0) { Write-Host "[checkpoint] WARNUNG: .checkpoint-pending.txt konnte nicht geloescht werden ($($_.Exception.Message)). Bitte manuell entfernen." -ForegroundColor Yellow
Write-Error "git add fehlgeschlagen (Exit Code $LASTEXITCODE)."
exit $LASTEXITCODE
} }
$commitMsg = "${session}: $summary"
& git commit -m $commitMsg
if ($LASTEXITCODE -ne 0) {
Write-Error "git commit fehlgeschlagen (Exit Code $LASTEXITCODE)."
exit $LASTEXITCODE
}
Write-Host "[checkpoint] Commit erstellt: $commitMsg" -ForegroundColor Green
# --- Pending-Datei loeschen --------------------------------
Remove-Item $pendingFile -Force
Write-Host "[checkpoint] .checkpoint-pending.txt entfernt." -ForegroundColor Green