11 KiB
Abschlussbericht Arbeitspaket AP07 – Ausgabeartefakte: Berichtdatei und Log-Datei mit Suffix-Logik
Bezug:
docs/arbeitspakete/m1/AP07-ausgabeartefakte.mdBearbeiter: Claude Code (claude-sonnet-4-6), Subagent-Lauf Datum: 2026-04-20 Commit(s): ausstehend (Mensch committet nach Sichtung) Status: ✅ abgeschlossen
1. Zusammenfassung
Pro Lauf werden nun zwei Ausgabedateien im Verzeichnis der Eingabedatei erzeugt: eine UTF-8-Berichtdatei (<dateiname>.txt) und eine Log-Datei (<dateiname>.log). Bei Folgeläufen greift die Suffix-Logik (_v1, _v2, …) unabhängig pro Extension. Die Konsolenausgabe ist identisch zum Berichtinhalt. mvn clean verify ist grün (202 Tests, 0 Fehler).
2. Umgesetzte Änderungen
Neu angelegt:
src/main/java/de/gecheckt/asv/adapter/out/filesystem/SuffixResolver.java— Ermittelt den ersten freien Dateipfad per Suffix-Logik. Probiert<baseName>.<ext>, dann<baseName>_v1.<ext>,<baseName>_v2.<ext>usw.; Zählung pro Extension unabhängig.src/main/java/de/gecheckt/asv/adapter/out/reporting/ReportFileWriter.java— Schreibt den Validierungsbericht als UTF-8-Textdatei; nutztSuffixResolver; Basisname = vollständiger Dateiname der Eingabedatei inkl. Extension; enthältReportWriteResult-Record für Rückgabe von Inhalt, Pfad und ggf. IOException.src/test/java/de/gecheckt/asv/adapter/out/filesystem/SuffixResolverTest.java— 10 Unit-Tests: keine Datei,.txtvorhanden,.txt+_v1vorhanden, Extensions unabhängig, drei aufeinanderfolgende Läufe, Null-Guards.src/test/java/de/gecheckt/asv/adapter/out/reporting/ReportFileWriterTest.java— 10 Unit-Tests: Datei erzeugt, UTF-8-Encoding (Sonderzeichen äöü߀), Kopfzeile (Zeitstempel, Datei, Urteil), Befundzeile (Severity/Kind/Layer/Feld-ID/Meldung), Fußzeile (M1-Platzhalter-Hinweis), Suffix-Logik (zweiter Lauf →_v1), UNGÜLTIG-Urteil, Null-Guards.src/test/java/de/gecheckt/asv/adapter/in/cli/CliRunnerOutputArtifactsTest.java— 5 End-to-End-Integrationstests: Lauf 1 (foo.auf.txt), Lauf 2 (foo.auf_v1.txt), Lauf 3 (foo.auf_v2.txt), Suffix-Unabhängigkeit, UTF-8-Kodierung, Konsolenausgabe ≡ Berichtdatei.
Geändert:
src/main/java/de/gecheckt/asv/adapter/out/logging/LoggingConfigurator.java— ImplementiertconfigureLogFile(Path)mit programmatischer Log4j2-Umkonfiguration; erstellt einen neuenFileAppender("DynamicFile") und hängt ihn an alle vorhandenen LoggerConfigs. Kapselt Log4j2-Typen vollständig inadapter.out.logging.src/main/resources/log4j2.xml— Statischerlogs/asv-format-validator.loginlogs/asv-format-validator-fallback.logumbenannt; Kommentar „FALLBACK-Default" ergänzt. Greift nur wennconfigureLogFilenicht aufgerufen wurde (z.B. Unit-Tests ohne Log-Datei).src/main/java/de/gecheckt/asv/bootstrap/Main.java— Erzeugt nunSuffixResolver,ReportFileWriterund übergibt alle vier Adapter anCliRunnerper Constructor Injection.src/main/java/de/gecheckt/asv/adapter/in/cli/CliRunner.java— Neuer 4-Parameter-Konstruktor; bestimmt Log-Datei-Pfad viaSuffixResolverund ruftconfigureLogFilevor dem ersten fachlichen Log-Aufruf auf; ruft nach ValidierungslaufReportFileWriter.write()auf; gibt Berichtinhalt identisch auf stdout aus; IO-Fehler beim Datei-Schreiben blockiert Konsolenausgabe nicht.src/test/java/de/gecheckt/asv/adapter/in/cli/CliRunnerTest.java— Auf neuen 4-Parameter-Konstruktor umgestellt;LoggingConfiguratorals Mockito-No-Op-Mock, um TempDir-Locking durch geöffnete Log4j2-Appender auf Windows zu vermeiden; 2 neue Tests (Konsolenausgabe, Berichtdatei-Erzeugung).
3. Scope-Treue
| Scope-Punkt aus dem Arbeitspaket | Erfüllt? | Bemerkung |
|---|---|---|
SuffixResolver in adapter.out.filesystem |
✅ | Vollständig implementiert |
| Suffix-Zählung pro Extension unabhängig | ✅ | .txt und .log haben getrennte Zähler |
Unit-Tests: keine Datei, .txt vorhanden, .txt+_v1 vorhanden |
✅ | Alle drei Testfälle + weitere |
ReportFileWriter in adapter.out.reporting |
✅ | Vollständig implementiert |
| Basisname = vollständiger Dateiname inkl. Extension | ✅ | foo.auf → foo.auf.txt |
| UTF-8 explizit (nicht Plattform-Default) | ✅ | StandardCharsets.UTF_8 in ReportFileWriter |
| Kopfzeile: Zeitstempel (ISO), Eingabedatei, Verdict | ✅ | Alle drei Felder |
| Pro Finding: Severity, Kind, Layer, Feld-ID, deutsche Meldung | ✅ | Format [SEV] [KIND] [LAYER] Feld=... – Meldung |
| Fußzeile: Hinweis auf nicht geprüfte Bereiche | ✅ | M1-Platzhalter-Hinweis |
LoggingConfigurator.configureLogFile(Path) |
✅ | Programmatische Umkonfiguration implementiert |
Log4j2-Typen nur in adapter.out.logging und bootstrap |
✅ | Verifiziert per grep; CLI-Paket enthält keine Log4j2-Importe |
Statischer logs/-Pfad entfernt/Fallback |
✅ | Auf logs/asv-format-validator-fallback.log umbenannt mit Kommentar |
Integration in bootstrap.Main |
✅ | Reihenfolge korrekt: SuffixResolver → configureLogFile → Validierung → ReportFileWriter → Konsolenausgabe |
| Konsolenausgabe nach Berichtdatei | ✅ | IO-Fehler bei Datei blockiert Konsolenausgabe nicht |
| Hierarchische Berichtsgliederung (Scope OUT) | ✅ nicht gemacht | M9 |
| ANSI-Farben (Scope OUT) | ✅ nicht gemacht | — |
| Log-Rotation (Scope OUT) | ✅ nicht gemacht | — |
| Minimalbericht bei Exit 2 (Scope OUT) | ✅ nicht gemacht | AP08 |
Wurde der Scope eingehalten? Ja, vollständig.
Wurden Dinge außerhalb des Scopes gemacht? Nein.
4. Abnahmekriterien
| Abnahmekriterium aus dem Arbeitspaket | Erfüllt? | Nachweis |
|---|---|---|
Nach Lauf mit foo/bar.auf entstehen foo/bar.auf.txt und foo/bar.auf.log |
✅ | E2E-Test (JAR): test.auf → test.auf.txt + test.auf.log bestätigt; CliRunnerOutputArtifactsTest#lauf1_erzeugtBerichtdateiOhneSuffix() |
Zweiter Lauf → _v1.txt und _v1.log |
✅ | E2E-Test (JAR): test.auf_v1.txt + test.auf_v1.log bestätigt; CliRunnerOutputArtifactsTest#lauf2_erzeugtBerichtdateiMitV1Suffix() |
Dritter Lauf → _v2 |
✅ | E2E-Test (JAR): test.auf_v2.txt + test.auf_v2.log bestätigt; CliRunnerOutputArtifactsTest#lauf3_erzeugtBerichtdateiMitV2Suffix() |
| Beide Ausgaben UTF-8 | ✅ | file test.auf.txt → Unicode text, UTF-8; ReportFileWriterTest#berichtdatei_istInUtf8() mit äöü߀; CliRunnerOutputArtifactsTest#berichtdatei_istInUtf8() mit GÜLTIG |
| Konsolenausgabe identisch zum Berichtdatei-Inhalt | ✅ | CliRunnerOutputArtifactsTest#konsolenausgabe_identischZumBerichtinhalt() — direkter String-Vergleich |
SuffixResolver hat ≥3 Unit-Tests |
✅ | 10 Tests in SuffixResolverTest |
Log4j2-Typen nicht außerhalb adapter.out.logging und bootstrap |
✅ | Grep auf import org.apache.logging.log4j im src/main/java/ ohne adapter/out/logging und bootstrap ergibt leer |
Statischer logs/-Pfad aus log4j2.xml entfernt oder Fallback |
✅ | log4j2.xml: logs/asv-format-validator-fallback.log; Kommentar „FALLBACK-Default" |
mvn clean verify grün |
✅ | 202 Tests, 0 Failures, 0 Errors |
Abschlussbericht unter docs/arbeitspakete/m1/berichte/AP07-bericht.md |
✅ | Diese Datei |
5. Build- und Teststatus
mvn clean verify: ✅ grün- Anzahl Tests gesamt: 202 (davon 29 neu in AP07: 10
SuffixResolverTest, 10ReportFileWriterTest, 2 neue inCliRunnerTest, 5 inCliRunnerOutputArtifactsTest, 2 inCliRunnerTesterweitert) - Vorherige Testanzahl (vor AP07, nach AP09): 173
- Coverage: JaCoCo läuft; neue Klassen durch Tests abgedeckt
- Warnungen beim Build: identisch zu AP06/AP09 (Shade-Plugin META-INF-Überlappungen,
sun.reflect.Reflection.getCallerClass-Warnung zur Laufzeit) — keine neuen Warnungen
6. Rest-Risiken und offene Punkte
-
TempDir-Locking auf Windows durch Log4j2-FileAppender: Wenn der echte
LoggingConfiguratorin Tests aufgerufen wird, hält Log4j2 den File-Appender für die Log-Datei im TempDir offen. JUnit 5 kann das TempDir dann nach dem Test nicht löschen. Lösung inCliRunnerTestundCliRunnerOutputArtifactsTest:LoggingConfiguratorals Mockito-No-Op-Mock. Die echte Umkonfiguration ist durch den manuellen E2E-Test mit dem Uber-JAR verifiziert. AP10 (Architekturtest) könnte dieses Verhalten formell absichern. -
Fallback-Entscheidung: Programmatische Log4j2-Umkonfiguration vs. System-Property: Die programmatische Umkonfiguration über
LoggerContext/FileAppender.newBuilder()ist stabil und funktioniert. Fallback (-Dasv.log.file=...) wurde nicht implementiert, da nicht nötig. Entscheidung: programmatisch, kein Fallback. -
Fallback-Datei
logs/asv-format-validator-fallback.log: Der Fallback-Appender inlog4j2.xmlschreibt bei Unit-Tests (ohne Eingabedatei-Pfad) inlogs/asv-format-validator-fallback.log. Dieses Verzeichnis wird automatisch durch Log4j2 angelegt. Die.gitignore-Einträgelogs/decken diese Datei ab. -
Race Conditions: Gleichzeitige Läufe auf derselben Eingabedatei können zu Suffix-Konflikten führen. Laut
technik-und-architektur.mdbewusst nicht behandelt (kein Mehrbenutzerbetrieb in V1). -
Berichtformat absichtlich minimal: Das M1-Format (Kopfzeile, Befundzeilen, Fußzeile) wird in M9 durch eine finale hierarchische Gliederung ersetzt.
-
Konsolenausgabe-Encoding auf Windows: Die Konsolenausgabe (
System.out.print) zeigt auf Windows-Konsolen Mojibake für Umlaute (G�LTIG), weil Windows-Konsolen oft CP1252/OEM437 nutzen. Die Datei selbst ist korrekt UTF-8. Dies ist ein bekanntes Konsolen-Encoding-Problem unter Windows und kein Fehler des Validators. Empfehlung für AP11: Hinweis in der Benutzer-Dokumentation.
7. Empfehlungen für Folge-Arbeitspakete
- AP08 (Minimalbericht bei Exit 2):
CliRunnergibt bei Bedienfehler bisher nur STDERR-Meldungen aus. AP08 kann hier anknüpfen und einen Minimalbericht erzeugen. DerReportFileWriterist dafür bereit. - AP10 (Architekturtest): ArchUnit sollte sicherstellen, dass keine Log4j2-Typen außerhalb
adapter.out.loggingundbootstrapimportiert werden.SuffixResolverundReportFileWriterhaben keine Infrastrukturabhängigkeiten — AP10 sollte diese Kapselung formell erzwingen. - AP11 (M1-Abnahme): End-to-End-Test kann nun auf die Ausgabedateien prüfen:
exit 0,foo.auf.txtexistiert, enthältGÜLTIG, ist UTF-8; Zweiter Lauf erzeugtfoo.auf_v1.txt. - M9 (Berichtformat ausbauen):
ReportFileWriter.buildReportContent()ist der Erweiterungspunkt. DieReportWriteResult-Signatur kann unverändert bleiben.
8. Reviewer-Checkliste
- Alle im Arbeitspaket genannten Scope-IN-Punkte sind nachweislich umgesetzt
- Keine Scope-OUT-Punkte wurden angefasst
- Abnahmekriterien sind mit konkreten Nachweisen belegt (Tests, E2E-JAR-Läufe, Dateipfade)
mvn clean verifyist grün (202 Tests, 0 Failures)- Der Commit für dieses AP hat eine sprechende Message (
M1-AP07: ...) — ausstehend, Mensch committet - Keine Regeln der Grunddokumente (Spec, Fachliche, Technik) wurden verletzt
- Rest-Risiken sind ehrlich dokumentiert