Skip to content

Build Report Foundation — structured report, console modes, warning control - #12572

Draft
gnodet wants to merge 1 commit into
masterfrom
feature/12571-build-report
Draft

Build Report Foundation — structured report, console modes, warning control#12572
gnodet wants to merge 1 commit into
masterfrom
feature/12571-build-report

Conversation

@gnodet

@gnodet gnodet commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements the build output overhaul proposed in #12571: a structured BuildReport data model with JSON persistence, a DiagnosticCollector for deduplicated warning summaries, four --console modes (plain, rich, machine, verbose), a --warning-mode CLI flag, automatic Log.warn() interception for Maven 3 plugin warnings, per-key diagnostic suppression, and a mvnlog build report viewer.

What's included

Structured Build Report

  • BuildReportModuleReportMojoReport data model in maven-api-core with id() and findModule()/findMojo() lookup methods
  • Per-mojo and per-module log capture using structured LogEvent
  • FailureReport with timestamp, exception type, and stack trace
  • BuildReportCollector (EventSpy, @Named @Singleton) — captures lifecycle events
  • BuildReportJsonWriter — hand-written JSON serializer (no library dependency)
  • Persists target/build-reports/build-report-latest.json at session end, with timestamped history
  • API lives in org.apache.maven.api.build.report sub-package

DiagnosticCollector + Warning Summary

  • Diagnostic / DiagnosticCollector / DiagnosticSummary API
  • DefaultDiagnosticCollector — thread-safe (ConcurrentHashMap + LongAdder), dedup by key, capped at 1000
  • Deduplicated warning summary printed at end of build with counts, suggestions, doc URLs
  • Diagnostics written to build-report.json

Console Modes (--console)

Flag Behavior
--console=auto (default) CI → plain; TTY → rich; otherwise → verbose
--console=plain One line per module, no ANSI — auto-selected in CI
--console=rich JLine status bar with live reactor progress, parallel-build aware
--console=verbose Full mojo-level output (Maven 4.0 default)
--console=machine JSON lines — one typed event per line, designed for tools and LLM agents

Plain mode: compact footer, no ANSI control sequences.
Rich mode: live Display bar showing active modules, [n/total] progress, elapsed time, download progress. All output bypasses SLF4J (routed through BuildEventListener.log()) to avoid the ProjectBuildLogAppender filter chain. Warning/error counts are tracked and shown in the compact end-of-build summary. Falls back gracefully on dumb terminals.
Machine mode: one JSON object per line with typed "event" field and ISO-8601 timestamps. Events: build.started/finished, module.started/succeeded/failed/skipped, mojo.*, fork.*, transfer.*.

Warning Mode, Log Interception, Diagnostic Suppression

Flag Behavior
--warning-mode=summary (default) Collect and show deduplicated summary at end
--warning-mode=all Show inline + summary
--warning-mode=none Suppress diagnostic summary
--warning-mode=fail Show summary + fail build if warnings exist
  • Log.warn() interception — auto-feeds Maven 3 plugin WARN-level output into DiagnosticCollector via synthetic dedup keys (auto:<LoggerSuffix>:<hexHash>), with file-coordinate stripping so the same warning from different files deduplicates
  • -Dmaven.diagnostic.suppress=<key> — suppress diagnostics by exact key or prefix wildcard (auto:*)

Version Info on Failure (MNG-7372)

On BUILD FAILURE, all console modes now display the Maven version and Java version/vendor in the summary. This helps with bug reports and Stack Overflow questions where java -version output may not match the JDK Maven actually used.

Build Report Viewer (mvnlog)

A lightweight tool to view previous build reports without running a full Maven build or an external plugin. Available in two forms:

  • Standalone command: mvnlog (or mvn --log) — skips DI container setup for fast startup
  • Shell subcommand: mvnlog inside mvnsh — shares the shell session context
Flag Behavior
(no flag) Summary view — status, module table, timing, warning/failure counts
--diagnostics / -d Detailed warnings and errors from the build
--failures / -f Detailed failure information including stack traces
--full / -F Full per-module, per-mojo timing breakdown
--list / -L List all available build reports in target/build-reports/
--json / -j Output the raw JSON build report (useful for piping to jq)

Positional argument accepts a path to a specific report file; defaults to target/build-reports/build-report-latest.json.

Key implementation details:

  • LogInvoker extends LookupInvoker but overrides doInvoke() to skip the heavyweight DI container, settings, and repository setup
  • SimpleJsonReader — zero-dependency recursive descent JSON parser (matches the zero-dependency spirit of BuildReportJsonWriter)
  • BuildReportRenderer — shared rendering logic between standalone and mvnsh subcommand via Consumer<String> output pattern
  • LogOptions API interface with CommonsCliLogOptions CLI parsing
  • Shell wrapper scripts (mvnlog / mvnlog.cmd) for Unix and Windows

Rich Mode Timing Fix

The console-mode auto-detection in --console=auto reads context.interactive to decide between rich/plain/verbose. However, createTerminal() caches the BuildEventListener via determineBuildEventListener() early in doInvoke(), while context.interactive was only set later during settings(). This caused context.interactive to be false (Java default) at cache time, so rich mode never auto-activated on TTYs.

Fixed by adding preliminaryInteractiveDetection() before createTerminal() — sets context.interactive from CLI flags (--force-interactive, --non-interactive) and CI environment detection. The full settings-based resolution still runs later. Also excludes embedded mode from rich auto-detection since embedded builds capture output via ByteArrayOutputStream.

Shell Script Routing-Flag Fix

The mvn / mvn.cmd launcher scripts now strip routing flags (--debug, --yjp, --enc, --shell, --up, --log) from the argument list before invoking Java. Previously these flags were consumed by handle_args() to set MAVEN_MAIN_CLASS but still passed through in $@/%*, where Commons CLI's partial long-option matching would collide (e.g. --log prefix-matched --log-file, causing mvnlog --help to crash).

What's NOT included (separate work)

  • Core plugin migration (maven-compiler-plugin, maven-enforcer-plugin, maven-surefire-plugin, maven-dependency-plugin reporting structured Diagnostic objects)

Tests

74 unit tests across 12 test classes covering report assembly, JSON serialization, diagnostic dedup/suppression/concurrency, all console modes, warning modes, SLF4J bypass verification, warning summary display, version-on-failure behavior, JSON parsing, and build report rendering.

13 integration tests (MavenITgh12571BuildReportTest) covering end-to-end behavior:

  • Build report JSON generation (single-module and multi-module)
  • Console modes: plain, machine, verbose, auto with CI=true
  • Warning mode: --warning-mode=none suppresses diagnostics
  • Version info displayed on build failure
  • mvnlog viewer: summary view, --full per-module detail, --list reports, --json raw output, error when no report exists

Integration tests that assert on verbose log output explicitly set --console=verbose to work correctly under CI auto-detection.

Supersedes

This PR supersedes and unifies the following open issues:

Related:

@gnodet gnodet changed the title Fix #12571: Add structured build report (Phase 0) Fix #12571: Build output overhaul — structured report, console modes, warning control Jul 29, 2026
@gnodet gnodet changed the title Fix #12571: Build output overhaul — structured report, console modes, warning control Fix #12571: Build Report Foundation — structured report, console modes, warning control Jul 29, 2026
@gnodet
gnodet force-pushed the feature/12571-build-report branch 6 times, most recently from 3192bb4 to 87be78e Compare July 29, 2026 14:59
@gnodet gnodet changed the title Fix #12571: Build Report Foundation — structured report, console modes, warning control Build Report Foundation — structured report, console modes, warning control Jul 29, 2026
@gnodet gnodet added this to the 4.1.0 milestone Jul 30, 2026
…s, warning control

Add a comprehensive build reporting infrastructure to Maven 4.1.0:

**Structured Build Report** (Phase 0-1)
- BuildReport API in maven-api-core with ModuleReport, MojoReport,
  FailureReport, and LogEvent data model
- BuildReportCollector EventSpy that captures lifecycle events,
  per-mojo log output, and build diagnostics
- JSON writer producing timestamped build-report-*.json files
- Deduplicated warning summary printed at end of build

**Console Modes** (Phase 2-4)
- ConsoleMode enum (AUTO/PLAIN/RICH/MACHINE) with --console CLI flag
- PlainBuildEventListener for compact CI output
- RichBuildEventListener with JLine status bar for interactive terminals
- MachineBuildEventListener for JSON-lines structured output

**Warning Control** (Phase 5)
- --warning-mode CLI flag (ALL/SUMMARY/NONE)
- Log.warn() interception for automatic Maven 3 plugin coverage
- -Dmaven.diagnostic.suppress=key for selective suppression

**Build Log Viewer** (mvnlog)
- mvnlog CLI tool for post-build report inspection
- --json flag for raw JSON output
- Shell scripts for Unix and Windows

**Plugin API** (DiagnosticReporter)
- BuilderProblem.builder() static factory with fluent Builder API
- DiagnosticReporter Service interface for Maven 4 plugins
- DefaultDiagnosticReporter implementation with auto-discovery

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant