diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/event/ExecutionEventLogger.java b/maven-embedder/src/main/java/org/apache/maven/cli/event/ExecutionEventLogger.java index d081cc4b711e..5ed5400e078f 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/event/ExecutionEventLogger.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/event/ExecutionEventLogger.java @@ -20,6 +20,7 @@ import java.io.File; import java.nio.file.Path; +import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -170,39 +171,48 @@ private void logReactorSummary(MavenSession session) { String failureMessage = builder().failure("FAILURE").build(); String unknownMessage = builder().warning("UNKNOWN").build(); - boolean lastWasSkipped = false; + List entries = new ArrayList<>(projects.size()); for (MavenProject project : projects) { BuildSummary buildSummary = result.getBuildSummary(project); String statusMessage; - boolean shouldSkip = result.hasExceptions(); - if (buildSummary == null) { - statusMessage = skippedMessage; - } else if (buildSummary instanceof BuildSuccess) { + int group; + if (buildSummary instanceof BuildSuccess) { statusMessage = successMessage; + group = 1; } else if (buildSummary instanceof BuildFailure) { statusMessage = failureMessage; - shouldSkip = false; + group = 2; + } else if (buildSummary == null) { + statusMessage = skippedMessage; + group = 0; } else { statusMessage = unknownMessage; + group = 2; } + entries.add(new ReactorSummaryEntry(project, buildSummary, group, statusMessage)); + } + + ReactorSummaryRequest request = new ReactorSummaryRequest(entries, isSingleVersion); - if (shouldSkip) { - lastWasSkipped = true; + logReactorSummaryGroup(request, 0); + logReactorSummaryGroup(request, 1); + logReactorSummaryGroup(request, 2); + } + + private void logReactorSummaryGroup(ReactorSummaryRequest request, int group) { + StringBuilder buffer = new StringBuilder(128); + + for (ReactorSummaryEntry entry : request.getEntries()) { + if (entry.getGroup() != group) { continue; } - if (lastWasSkipped) { - logger.info("..."); - lastWasSkipped = false; - } - StringBuilder buffer = new StringBuilder(128); - - buffer.append(project.getName()); + buffer.append(entry.getProject().getName()); buffer.append(' '); - if (!isSingleVersion) { - buffer.append(project.getVersion()); + if (!request.isSingleVersion()) { + buffer.append(entry.getProject().getVersion()); buffer.append(' '); } @@ -213,16 +223,65 @@ private void logReactorSummary(MavenSession session) { buffer.append(' '); } - buffer.append(statusMessage); - if (buildSummary != null) { - formatBuildTime(buffer, buildSummary); + buffer.append(entry.getStatusMessage()); + if (entry.getBuildSummary() != null) { + formatBuildTime(buffer, entry.getBuildSummary()); } - logger.info(buffer.toString()); + if (entry.getBuildSummary() instanceof BuildFailure) { + logger.error(buffer.toString()); + } else { + logger.info(buffer.toString()); + } + buffer.setLength(0); + } + } + + private static final class ReactorSummaryRequest { + private final List entries; + private final boolean singleVersion; + + private ReactorSummaryRequest(List entries, boolean singleVersion) { + this.entries = entries; + this.singleVersion = singleVersion; } - if (lastWasSkipped) { - logger.info("..."); + private List getEntries() { + return entries; + } + + private boolean isSingleVersion() { + return singleVersion; + } + } + + private static final class ReactorSummaryEntry { + private final MavenProject project; + private final BuildSummary buildSummary; + private final int group; + private final String statusMessage; + + private ReactorSummaryEntry(MavenProject project, BuildSummary buildSummary, int group, String statusMessage) { + this.project = project; + this.buildSummary = buildSummary; + this.group = group; + this.statusMessage = statusMessage; + } + + private MavenProject getProject() { + return project; + } + + private BuildSummary getBuildSummary() { + return buildSummary; + } + + private int getGroup() { + return group; + } + + private String getStatusMessage() { + return statusMessage; } } @@ -241,12 +300,17 @@ private void logResult(MavenSession session) { infoLine('-'); MessageBuilder buffer = MessageUtils.builder(); - if (session.getResult().hasExceptions()) { + boolean failure = session.getResult().hasExceptions(); + if (failure) { buffer.failure("BUILD FAILURE"); } else { buffer.success("BUILD SUCCESS"); } - logger.info(buffer.toString()); + if (failure) { + logger.error(buffer.toString()); + } else { + logger.info(buffer.toString()); + } } private void logStats(MavenSession session) { diff --git a/maven-embedder/src/test/java/org/apache/maven/cli/event/ExecutionEventLoggerTest.java b/maven-embedder/src/test/java/org/apache/maven/cli/event/ExecutionEventLoggerTest.java index 00ce1f79c30e..0d4d0730bce0 100644 --- a/maven-embedder/src/test/java/org/apache/maven/cli/event/ExecutionEventLoggerTest.java +++ b/maven-embedder/src/test/java/org/apache/maven/cli/event/ExecutionEventLoggerTest.java @@ -279,11 +279,11 @@ public void testSessionEndedFailureMultimodule() { inOrder.verify(logger).info("------------------------------------------------------------------------"); inOrder.verify(logger).info("Reactor Summary for Maven Project artifact1 1.0.0-SNAPSHOT:"); inOrder.verify(logger).info(""); - inOrder.verify(logger).info("..."); - inOrder.verify(logger).info("Maven Project artifact2 ............................ FAILURE [ 2.000 s]"); - inOrder.verify(logger).info("..."); + inOrder.verify(logger).info("Maven Project artifact3 ............................ SKIPPED"); + inOrder.verify(logger).info("Maven Project artifact1 ............................ SUCCESS [ 1.000 s]"); + inOrder.verify(logger).error("Maven Project artifact2 ............................ FAILURE [ 2.000 s]"); inOrder.verify(logger).info("------------------------------------------------------------------------"); - inOrder.verify(logger).info("BUILD FAILURE"); + inOrder.verify(logger).error("BUILD FAILURE"); inOrder.verify(logger).info("------------------------------------------------------------------------"); inOrder.verify(logger).info(eq("Total time: {}{}"), anyString(), anyString()); inOrder.verify(logger).info(eq("Finished at: {}"), anyString()); @@ -335,13 +335,107 @@ public void testSessionEndedFailureMultimoduleWithSeparatedFailures() { inOrder.verify(logger).info("------------------------------------------------------------------------"); inOrder.verify(logger).info("Reactor Summary for Maven Project artifact1 1.0.0-SNAPSHOT:"); inOrder.verify(logger).info(""); - inOrder.verify(logger).info("..."); - inOrder.verify(logger).info("Maven Project artifact2 ............................ FAILURE [ 2.000 s]"); - inOrder.verify(logger).info("..."); - inOrder.verify(logger).info("Maven Project artifact5 ............................ FAILURE [ 5.000 s]"); - inOrder.verify(logger).info("..."); + inOrder.verify(logger).info("Maven Project artifact6 ............................ SKIPPED"); + inOrder.verify(logger).info("Maven Project artifact1 ............................ SUCCESS [ 1.000 s]"); + inOrder.verify(logger).info("Maven Project artifact3 ............................ SUCCESS [ 3.000 s]"); + inOrder.verify(logger).info("Maven Project artifact4 ............................ SUCCESS [ 4.000 s]"); + inOrder.verify(logger).error("Maven Project artifact2 ............................ FAILURE [ 2.000 s]"); + inOrder.verify(logger).error("Maven Project artifact5 ............................ FAILURE [ 5.000 s]"); + inOrder.verify(logger).info("------------------------------------------------------------------------"); + inOrder.verify(logger).error("BUILD FAILURE"); + inOrder.verify(logger).info("------------------------------------------------------------------------"); + inOrder.verify(logger).info(eq("Total time: {}{}"), anyString(), anyString()); + inOrder.verify(logger).info(eq("Finished at: {}"), anyString()); + inOrder.verify(logger).info("------------------------------------------------------------------------"); + } + + @Test + public void testSessionEndedSuccessWithSkippedModules() { + // prepare + MavenProject project1 = aProject("artifact1"); + MavenProject project2 = aProject("artifact2"); + MavenProject project3 = aProject("artifact3"); + + MavenExecutionResult executionResult = new DefaultMavenExecutionResult(); + executionResult.addBuildSummary(new BuildSuccess(project1, 1000)); + executionResult.addBuildSummary(new BuildSuccess(project3, 3000)); + + MavenExecutionRequest executionRequest = new DefaultMavenExecutionRequest(); + executionRequest.setStartTime(new Date()); + + ProjectDependencyGraph projectDependencyGraph = mock(ProjectDependencyGraph.class); + when(projectDependencyGraph.getSortedProjects()).thenReturn(Arrays.asList(project1, project2, project3)); + + MavenSession mavenSession = mock(MavenSession.class); + when(mavenSession.getResult()).thenReturn(executionResult); + when(mavenSession.getRequest()).thenReturn(executionRequest); + when(mavenSession.getProjects()).thenReturn(Arrays.asList(project1, project2, project3)); + when(mavenSession.getTopLevelProject()).thenReturn(project1); + when(mavenSession.getProjectDependencyGraph()).thenReturn(projectDependencyGraph); + + ExecutionEvent event = mock(ExecutionEvent.class); + when(event.getSession()).thenReturn(mavenSession); + + // execute + executionEventLogger.sessionEnded(event); + + // verify + InOrder inOrder = inOrder(logger); + inOrder.verify(logger).info("------------------------------------------------------------------------"); + inOrder.verify(logger).info("Reactor Summary for Maven Project artifact1 1.0.0-SNAPSHOT:"); + inOrder.verify(logger).info(""); + inOrder.verify(logger).info("Maven Project artifact2 ............................ SKIPPED"); + inOrder.verify(logger).info("Maven Project artifact1 ............................ SUCCESS [ 1.000 s]"); + inOrder.verify(logger).info("Maven Project artifact3 ............................ SUCCESS [ 3.000 s]"); + inOrder.verify(logger).info("------------------------------------------------------------------------"); + inOrder.verify(logger).info("BUILD SUCCESS"); + inOrder.verify(logger).info("------------------------------------------------------------------------"); + inOrder.verify(logger).info(eq("Total time: {}{}"), anyString(), anyString()); + inOrder.verify(logger).info(eq("Finished at: {}"), anyString()); + inOrder.verify(logger).info("------------------------------------------------------------------------"); + } + + @Test + public void testSessionEndedFailureMixedWithSkippedModules() { + // prepare + MavenProject project1 = aProject("artifact1"); + MavenProject project2 = aProject("artifact2"); + MavenProject project3 = aProject("artifact3"); + + MavenExecutionResult executionResult = new DefaultMavenExecutionResult(); + executionResult.addBuildSummary(new BuildSuccess(project1, 1000)); + executionResult.addBuildSummary(new BuildSuccess(project3, 3000)); + executionResult.addException(new Exception("Failure")); + + MavenExecutionRequest executionRequest = new DefaultMavenExecutionRequest(); + executionRequest.setStartTime(new Date()); + + ProjectDependencyGraph projectDependencyGraph = mock(ProjectDependencyGraph.class); + when(projectDependencyGraph.getSortedProjects()).thenReturn(Arrays.asList(project1, project2, project3)); + + MavenSession mavenSession = mock(MavenSession.class); + when(mavenSession.getResult()).thenReturn(executionResult); + when(mavenSession.getRequest()).thenReturn(executionRequest); + when(mavenSession.getProjects()).thenReturn(Arrays.asList(project1, project2, project3)); + when(mavenSession.getTopLevelProject()).thenReturn(project1); + when(mavenSession.getProjectDependencyGraph()).thenReturn(projectDependencyGraph); + + ExecutionEvent event = mock(ExecutionEvent.class); + when(event.getSession()).thenReturn(mavenSession); + + // execute + executionEventLogger.sessionEnded(event); + + // verify + InOrder inOrder = inOrder(logger); + inOrder.verify(logger).info("------------------------------------------------------------------------"); + inOrder.verify(logger).info("Reactor Summary for Maven Project artifact1 1.0.0-SNAPSHOT:"); + inOrder.verify(logger).info(""); + inOrder.verify(logger).info("Maven Project artifact2 ............................ SKIPPED"); + inOrder.verify(logger).info("Maven Project artifact1 ............................ SUCCESS [ 1.000 s]"); + inOrder.verify(logger).info("Maven Project artifact3 ............................ SUCCESS [ 3.000 s]"); inOrder.verify(logger).info("------------------------------------------------------------------------"); - inOrder.verify(logger).info("BUILD FAILURE"); + inOrder.verify(logger).error("BUILD FAILURE"); inOrder.verify(logger).info("------------------------------------------------------------------------"); inOrder.verify(logger).info(eq("Total time: {}{}"), anyString(), anyString()); inOrder.verify(logger).info(eq("Finished at: {}"), anyString());