Conversation
|
One format worth considering for the machine-readable console mode: logfmt. It sits nicely between plain text (human-readable) and JSON lines (fully structured): parseable by Loki, Vector, Grafana out of the box, but still legible with a plain The interesting property: with Could be offered as a |
7eaa538 to
869e497
Compare
gnodet-bot
left a comment
There was a problem hiding this comment.
Console modes review — overall this is solid. Three specific issues worth addressing before merge.
This review was generated by an AI agent, Hermès on behalf of @gnodet.
…enhancements - Add LogEvent interface (maven-api-core) with projectId/mojoId context fields - Add DefaultLogEvent record (maven-core) implementing LogEvent - Add MavenJulHandler (maven-logging): bridge JUL→SLF4J for plugin logging - Enhance DefaultLog (maven-core): carry LOG_API_METADATA for mojo log capture - Add ProjectBuildLogAppender (maven-core): MDC-aware log sink feeding LogEvent stream - Suppress JLine terminal-init DEBUG logs before activateLogging in quiet mode - Gate StackWalker behind hasReportCapture() for zero overhead in normal builds - Fix warn(Supplier<String>, Throwable) incorrectly calling logger.info() - Add @PARAM tags on trace(Supplier) overloads; fix sequenceNumber() @return javadoc - Fix LogEvent.message() @return javadoc copy-paste from formattedMessage() - Strengthen logApiMetadataIsClearedAfterCall() test to exercise the remove() path
cbc7623 to
f656ea9
Compare
- Add BuildReport, ModuleReport, MojoReport, FailureReport, BuildStatus API types (maven-api-core) - Add BuildEnvironment API type and Session.buildEnvironment() accessor - Implement BuildReportCollector in maven-core: captures per-mojo log output, timing, failures - Implement BuildReportJsonWriter: writes structured JSON report to file at build end - Integrate into MavenInvoker and DefaultMavenExecutionRequest - Extend MavenSimpleLogger and MavenJulHandler with LogSink support for log capture - Add SessionStub.buildEnvironment() stub for maven-testing - Add BuildReportCollectorTest, BuildReportJsonWriterTest, BuildReportIntegrationTest - Handle MojoSkipped events in BuildReportCollector - Fix ConcurrentModificationException in buildReport() log buffer iteration
11205e6 to
92a187f
Compare
7b65dd4 to
14521d5
Compare
gnodet-bot
left a comment
There was a problem hiding this comment.
Console modes + build report review — the three findings from the previous review (PR #12697 / old SHA 7b65dd40) are all addressed in this resubmission. One new concurrency issue found, and one pre-existing concern persists.
Addressed from prior review:
- ✅
MachineExecutionEventLoggermojo key now includesgroupId— module collision in multi-module builds fixed - ✅
BUILD FAILUREheader correctly atlogger.error()inlogResult() - ✅
currentVisitedProjectCountis nowAtomicIntegerinMachineExecutionEventLogger
This review was generated by an AI agent, Hermès on behalf of @gnodet.
gnodet-bot
left a comment
There was a problem hiding this comment.
Console modes re-review (SHA 67d50688) — all four findings from the prior review are addressed. One nit remains unresolved.
Addressed from prior review:
- ✅
RichBuildEventListener.completedProjectsrace — fixed:volatile int→final AtomicIntegerwith.incrementAndGet()/.get()throughout - ✅ Per-module FAILURE lines in
ExecutionEventLoggerlogged at wrong level — fixed:if (buildSummary instanceof BuildFailure) logger.error(...)branch added - ✅
PlainExecutionEventLoggerBUILD FAILURE logged at INFO — fixed:session.getResult().hasExceptions()check added, tests updated - ✅
PlainExecutionEventLogger.volatile int currentVisitedProjectCount— fixed:volatiledropped (lock provides the memory ordering) - ✅ Unknown
--console=value silent fallthrough — fixed: warning now logged viacontext.logger.warn()
One missed fix:
This review was generated by an AI agent, Hermès on behalf of @gnodet.
67d5068 to
3487903
Compare
gnodet-bot
left a comment
There was a problem hiding this comment.
Re-review after 3487903335 ("fix review: RichBuildEventListener race, logger.error on failures, unknown --console warn, drop volatile")
All four findings from the previous CHANGES_REQUESTED reviews are addressed:
| Finding | Status |
|---|---|
completedProjects++ race in RichBuildEventListener |
✅ Fixed — volatile int → AtomicInteger, incrementAndGet() used throughout |
Per-module FAILURE lines logged at INFO in ExecutionEventLogger.logReactorSummary |
✅ Fixed — BuildFailure instanceof check now routes to logger.error() |
BUILD FAILURE logged at INFO in PlainExecutionEventLogger.logResult |
✅ Fixed — session.getResult().hasExceptions() check now routes to logger.error() |
Silent fallthrough for unknown --console= values in MavenInvoker.determineConsoleMode |
✅ Fixed — unknown values now emit a warn(); "auto" falls through silently as before |
Misleading volatile on currentVisitedProjectCount in PlainExecutionEventLogger |
✅ Fixed — volatile dropped |
One nit from the prior inline comment (already posted on this SHA) remains open:
RichExecutionEventLogger.java:85 — private volatile int currentVisitedProjectCount still has the misleading volatile modifier. The field is only ever mutated inside synchronized (this) blocks, and the lock already provides the required happens-before. The volatile is redundant and signals incorrect intent to future readers — same fix as applied to PlainExecutionEventLogger.
This review was generated by an AI agent, Hermès on behalf of @gnodet.
gnodet-bot
left a comment
There was a problem hiding this comment.
Console modes re-review (SHA a39b4c2e) — the remaining nit from the previous review is addressed.
Addressed:
- ✅
volatileremoved fromcurrentVisitedProjectCountinRichExecutionEventLogger— correct. The field is only written insidesynchronized (this)(line 258:number = ++currentVisitedProjectCount) and assigned single-threadedly at session start (line 147). The JMM happens-before guarantee from the monitor makesvolatileredundant and misleading (it implied an unsynchronized read path that does not exist).
All prior findings from all previous reviews are addressed. The PR is ready.
This review was generated by an AI agent, Hermès on behalf of @gnodet.
a39b4c2 to
0855915
Compare
gnodet-bot
left a comment
There was a problem hiding this comment.
Console modes re-review (SHA 08559154) — re-reviewing the delta since the prior APPROVE (a39b4c2e).
Delta since last review:
- ✅ Trailing newline added to 7 files (
MachineBuildEventListener.java,LayeredOptions.java,LookupInvoker.java, 4 test files) — trivial formatting fix, no logic change. - ✅
WorkspaceParentProjectBuilderTest.java(new, 141 lines) — solid test for workspace parent basedir handling. Correctly overridesgetWorkspaceReader()(the hook exists on master since #13212). Two scenarios well-covered: parent from project-local repository gets no basedir, parent that is a session project keeps its basedir. Test structure is clean —@TempDir, proper POM helpers, correct use ofassertNull/assertEquals. No issues. - ✅
domtripVersion1.6.0 → 1.7.0,jlineVersion4.4.3 → 4.4.5 — both are minor bug-fix releases with no breaking API changes. JLine 4.4.5 includes fixes for FFM SIGQUIT handler, ColorPalette OSC 4 fallback, ReDoS-vulnerable regex, and paginated layout defects. domtrip 1.7.0 is from the maveniverse project (same maintainer). Both bumps are safe. - ✅
.worktrees/**added to RAT exclusion — correct, avoids false license-header hits on git worktree admin files.
All prior findings from the review chain remain addressed. APPROVED.
This review was generated by an AI agent, Hermès on behalf of @gnodet.
gnodet-bot
left a comment
There was a problem hiding this comment.
Console modes re-review (SHA f6bb3306) — single commit since the prior APPROVE (08559154).
Delta: Restores getWorkspaceReader() hook in AbstractCoreMavenComponentTestCase.
- ✅
getWorkspaceReader()returnsnullby default —DefaultSessionBuilder.setWorkspaceReader(null)is a plain field assignment, no NPE risk. - ✅
SessionBuilder.setWorkspaceReader(WorkspaceReader)exists in resolver 2.0.23 — the call site is valid. - ✅
WorkspaceParentProjectBuilderTest.getWorkspaceReader()override (already in-tree) is now wired intoinitRepoSession(), which is the whole point of this commit. - ✅ Javadoc on the new method is correct and sufficient.
Clean fix. APPROVE.
This review was generated by an AI agent, Hermès on behalf of @gnodet.
gnodet-bot
left a comment
There was a problem hiding this comment.
Console modes re-review (SHA 48f67cdb) — single commit since the prior APPROVE (f6bb3306).
Delta: Restores isProjectPom() helper and its use in resolveProjectSource() in DefaultProjectBuilder.
- ✅
isProjectPom(Path pomFile)— logic is correct.pomFile == nullguard handlesArtifact.getPath()returningnullbefore resolution.projects == nullguard matches the existing pattern at line 371 (defensive for UT environments).filter(Objects::nonNull)is appropriate even though the list is@Nonnull. The use ofnormalize()is more correct than the existing line 371 equivalent. - ✅
localProject = isWorkspaceRepo && isProjectPom(pomArtifact.getPath())— restores the original invariant: only POMs belonging to actual session projects get a basedir. FixesWorkspaceParentProjectBuilderTest.parentFromProjectLocalRepositoryHasNoBasedir. - ✅ No new behavior introduced — pure restoration of code accidentally dropped in the squash commit.
Clean fix, no issues.
This review was generated by an AI agent, Hermès on behalf of @gnodet.
- Add --console=plain/rich/verbose/machine option to select output mode - plain: compact one-line-per-module output with structured summary - rich: JLine status bar with live reactor progress and mojo tracking - verbose: full mojo-level output (Maven 4.0 default behaviour) - machine: JSON lines stream of lifecycle events for CI/LLM/IDE tooling - MachineBuildEventListener: structured JSON log/transfer events - MachineExecutionEventLogger: JSON lifecycle events (build/module/mojo) - RichBuildEventListener: JLine terminal status bar with parallel progress - RichExecutionEventLogger: minimal per-module logger for rich mode - PlainExecutionEventLogger: compact logger for plain mode - BUILD FAILURE logged at ERROR level; per-module FAILURE lines at ERROR - Unknown --console values emit a warning and fall back to auto - mojoKey uses groupId to avoid collision in multi-module builds - Use AtomicInteger for thread-safe counters (completedProjects, etc.) - Apply spotless formatting to all modified files
…estCase The console-modes squash removed the getWorkspaceReader() extension point that was added by 25be7b8, breaking the compilation of WorkspaceParentProjectBuilderTest which overrides that method.
…acts from getting a basedir The console-modes squash accidentally removed the isProjectPom() helper and the associated check in resolveProjectSource(). This caused any POM served by the workspace reader (including those from the project-local repository) to be treated as a local checkout with a basedir, breaking the invariant that only actual session projects should have a basedir. Restore the original logic: localProject = isWorkspaceRepo && isProjectPom(). Fixes WorkspaceParentProjectBuilderTest.parentFromProjectLocalRepositoryHasNoBasedir.
…g output
When running on GitHub Actions, CI=true is inherited by child Maven
processes spawned by the IT framework. With the new console-modes feature,
CI detection causes auto mode to select plain, which suppresses mojo-start
banners ([INFO] --- plugin:version:goal @ module) and 'Reactor Summary'
lines that many ITs rely on.
Fix: call removeCIEnvironmentVariables() in AbstractMavenIntegrationTestCase.
newVerifier() so all ITs run in verbose mode by default (the same output
format they were written against). ITs that test CI-specific behaviour
can opt back in with verifier.setEnvironmentVariable("CI", "true").
Also add --console=verbose to MavenITmng8655SettingsParserTest.coreRealmParserReadsBootstrapSettings
which uses ForkedMavenExecutor directly (bypasses the Verifier) and
inherits the CI env from the parent process.
gnodet-bot
left a comment
There was a problem hiding this comment.
Console modes re-review (SHA 905812cd) — single commit since the prior APPROVE (48f67cdb).
Delta: Isolates ITs from the CI environment so CI → plain auto-detection does not suppress output that ITs rely on.
- ✅
AbstractMavenIntegrationTestCase.newVerifier()—removeCIEnvironmentVariables()called in the base method. Verified against all six CI detectors:GenericCIDetector(CI="false"),GithubCIDetector(GITHUB_ACTIONS=""),TravisCIDetector(TRAVIS=""),CircleCIDetector(CIRCLECI=""),JenkinsCIDetector(WORKSPACE=""),TeamcityCIDetector(TEAMCITY_VERSION="") — every detector is correctly neutralized. - ✅
MavenITmng8655SettingsParserTest.coreRealmParserReadsBootstrapSettings()— adds--console=verboseto theForkedMavenExecutorcall (which bypassesnewVerifier()and thus the base-class fix). Correct:verbosemode usesExecutionEventLoggerwhich emits theBuilding bootstrap-settings 0.1line the assertion checks. - ✅ Existing CI-aware ITs: tests that called
removeCIEnvironmentVariables()individually (mng4829, mng6240, mng4461) are now redundant but harmless. No regression.
All prior findings remain resolved. Clean delta.
This review was generated by an AI agent, Hermès on behalf of @gnodet.
905812c to
512629a
Compare
gnodet-bot
left a comment
There was a problem hiding this comment.
Console modes re-review (SHA 512629a5) — re-reviewing the delta since the prior APPROVE (905812cd).
Context: The branch was force-pushed. The new HEAD collapses several prior commits into a different squash. Comparing the PR diff vs master (the only merge-relevant delta), the sole net-new code change is the JUL-level clamping in LookupInvoker.
Items that appeared to regress vs 905812cd but are not merge regressions:
jlineVersion4.4.5 → 4.4.3,domtripVersion1.7.0 → 1.6.0,.worktrees/**RAT exclude absent — these were squashed out of the PR branch, but all three are already on master via independent commits (ebb415b5,77944f80,18806b1a45). They will survive the merge.WorkspaceParentProjectBuilderTestnot in PR branch — was added+deleted within the feature branch squash. master has it independently viac3b52889c3. Merge will keep master's version.
New JUL-level clamping in LookupInvoker (configureLogging + activateLogging):
configureLogging (quiet mode): MavenJulHandler.install() sets Level.ALL internally, then setLevel(Level.SEVERE) immediately overrides it. These two calls are synchronous in a single thread — zero event-processing window between them. Level.SEVERE blocks JUL events before they reach publish(), preventing the SLF4J-bootstrap reentrancy flood that Level.ALL would cause while SLF4J is still pre-activated. Correct.
activateLogging: post-activate() JUL root level is set to mirror the SLF4J effective level (quiet→SEVERE, verbose→ALL, default→INFO). The isInstalled() guard prevents double-install. The three-way mapping is correct.
The fix correctly closes the race window described in the comment: between configureLogging and activateLogging, createTerminal() runs and JLine emits JUL events. In quiet mode those events were leaking before this change. Setting Level.SEVERE at source (JUL root) before createTerminal() is the right fix — the isLevelEnabled() check in MavenJulHandler.publish() would not suffice because newly created SLF4J loggers briefly see the default INFO level during the reentrancy window.
IT coverage via MavenITmng4387QuietLoggingTest (on master, already exercises quiet-mode output expectations). The change is narrowly scoped and well-explained. APPROVE.
This review was generated by an AI agent, Hermès on behalf of @gnodet.
Summary
Part 3 of the logging feature chain. Depends on #12695 (build report).
Adds the
--consoleCLI flag with four output modes:plain— compact one-line-per-module output, ideal for CI (auto-selected in CI environments)rich— JLine status bar with live reactor progress (auto-selected on interactive TTYs)verbose— full mojo-level output, current Maven 4.0 default behaviormachine— JSON lines: one typed JSON object per lifecycle event, designed for piping to external toolsAuto-detection (
--console=auto, the default): CI → plain, interactive TTY → rich, otherwise → verbose.Files changed (17 files)
Options.java(+console())PlainExecutionEventLogger,RichBuildEventListener,RichExecutionEventLogger,MachineBuildEventListener,MachineExecutionEventLoggerCommonsCliOptions,LayeredOptions,LookupInvoker(preliminary interactive detection),MavenInvoker(console mode switch + transfer listener)ExecutionEventLogger(version info on failure, linear reactor summary)PR chain
mvnlogviewerTest plan
mvn verify -pl api/maven-api-cli,impl/maven-cli -am— all tests pass