This is an automated email from the ASF dual-hosted git repository. gnodet pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/maven.git
The following commit(s) were added to refs/heads/master by this push: new 5d449f9a24 [MNG-8244] Using before:all / all / after:all is not triggered (#1973) 5d449f9a24 is described below commit 5d449f9a247742dc0bdf89cab0fbe6d8623881ee Author: Guillaume Nodet <gno...@gmail.com> AuthorDate: Sat Dec 14 00:04:37 2024 +0100 [MNG-8244] Using before:all / all / after:all is not triggered (#1973) --- .../main/java/org/apache/maven/api/Lifecycle.java | 21 ++-- .../internal/impl/DefaultLifecycleRegistry.java | 107 ++++++++---------- .../java/org/apache/maven/lifecycle/Lifecycle.java | 8 +- .../DefaultLifecycleExecutionPlanCalculator.java | 8 +- .../internal/DefaultLifecycleMappingDelegate.java | 23 ++-- .../maven/lifecycle/internal/PhaseComparator.java | 11 +- .../internal/concurrent/BuildPlanExecutor.java | 11 +- .../maven/lifecycle/LifecycleExecutorTest.java | 124 +++++++++------------ .../maven/it/MavenITmng8244PhaseAllTest.java | 65 +++++++++++ .../org/apache/maven/it/TestSuiteOrdering.java | 1 + .../src/test/resources/mng-8244-phase-all/pom.xml | 117 +++++++++++++++++++ 11 files changed, 326 insertions(+), 170 deletions(-) diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/Lifecycle.java b/api/maven-api-core/src/main/java/org/apache/maven/api/Lifecycle.java index 9fdabb2854..de7fe1ff90 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/Lifecycle.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/Lifecycle.java @@ -20,7 +20,6 @@ package org.apache.maven.api; import java.util.Collection; import java.util.List; -import java.util.Optional; import java.util.stream.Stream; import org.apache.maven.api.annotations.Experimental; @@ -66,10 +65,19 @@ public interface Lifecycle extends ExtensibleEnum { String id(); /** - * Collection of phases for this lifecycle + * Collection of main phases for this lifecycle */ Collection<Phase> phases(); + /** + * Collection of main phases for this lifecycle used with the Maven 3 builders. + * Those builders does not operate on a graph, but on the list and expect a slightly + * different ordering (mainly unit test being executed before packaging). + */ + default Collection<Phase> v3phases() { + return phases(); + } + /** * Stream of phases containing all child phases recursively. */ @@ -82,14 +90,6 @@ public interface Lifecycle extends ExtensibleEnum { */ Collection<Alias> aliases(); - /** - * Pre-ordered list of phases. - * If not provided, a default order will be computed. - */ - default Optional<List<String>> orderedPhases() { - return Optional.empty(); - } - /** * A phase in the lifecycle. * @@ -101,6 +101,7 @@ public interface Lifecycle extends ExtensibleEnum { // ====================== // Maven defined phases // ====================== + String ALL = "all"; String BUILD = "build"; String INITIALIZE = "initialize"; String VALIDATE = "validate"; diff --git a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultLifecycleRegistry.java b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultLifecycleRegistry.java index d5d474611e..d72ee709e1 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultLifecycleRegistry.java +++ b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultLifecycleRegistry.java @@ -24,7 +24,6 @@ import javax.inject.Provider; import javax.inject.Singleton; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; @@ -50,6 +49,9 @@ import org.apache.maven.lifecycle.mapping.LifecyclePhase; import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; +import static org.apache.maven.api.Lifecycle.AFTER; +import static org.apache.maven.api.Lifecycle.BEFORE; +import static org.apache.maven.api.Lifecycle.Phase.ALL; import static org.apache.maven.api.Lifecycle.Phase.BUILD; import static org.apache.maven.api.Lifecycle.Phase.COMPILE; import static org.apache.maven.api.Lifecycle.Phase.DEPLOY; @@ -129,34 +131,20 @@ public class DefaultLifecycleRegistry implements LifecycleRegistry { public List<String> computePhases(Lifecycle lifecycle) { Graph graph = new Graph(); - lifecycle.phases().forEach(phase -> addPhase(graph, null, null, phase)); + addPhases(graph, null, null, lifecycle.v3phases()); List<String> allPhases = graph.visitAll(); Collections.reverse(allPhases); List<String> computed = allPhases.stream().filter(s -> !s.startsWith("$")).collect(Collectors.toList()); - List<String> given = lifecycle.orderedPhases().orElse(null); - if (given != null) { - if (given.size() != computed.size()) { - Set<String> s1 = - given.stream().filter(s -> !computed.contains(s)).collect(Collectors.toSet()); - Set<String> s2 = - computed.stream().filter(s -> !given.contains(s)).collect(Collectors.toSet()); - throw new IllegalStateException( - "List of phases differ in size: expected " + computed.size() + ", but received " + given.size() - + (s1.isEmpty() ? "" : ", missing " + s1) - + (s2.isEmpty() ? "" : ", unexpected " + s2)); - } - return given; - } return computed; } private static void addPhase( Graph graph, Graph.Vertex before, Graph.Vertex after, org.apache.maven.api.Lifecycle.Phase phase) { - Graph.Vertex ep0 = graph.addVertex("$" + phase.name()); + Graph.Vertex ep0 = graph.addVertex(BEFORE + phase.name()); Graph.Vertex ep1 = graph.addVertex("$$" + phase.name()); Graph.Vertex ep2 = graph.addVertex(phase.name()); - Graph.Vertex ep3 = graph.addVertex("$$$" + phase.name()); + Graph.Vertex ep3 = graph.addVertex(AFTER + phase.name()); graph.addEdge(ep0, ep1); graph.addEdge(ep1, ep2); graph.addEdge(ep2, ep3); @@ -171,11 +159,28 @@ public class DefaultLifecycleRegistry implements LifecycleRegistry { if (link.kind() == Lifecycle.Link.Kind.AFTER) { graph.addEdge(graph.addVertex(link.pointer().phase()), ep0); } else { - graph.addEdge(ep3, graph.addVertex("$" + link.pointer().phase())); + graph.addEdge(ep3, graph.addVertex(BEFORE + link.pointer().phase())); } } }); - phase.phases().forEach(child -> addPhase(graph, ep1, ep2, child)); + addPhases(graph, ep1, ep2, phase.phases()); + } + + private static void addPhases( + Graph graph, Graph.Vertex before, Graph.Vertex after, Collection<Lifecycle.Phase> phases) { + // We add ordering between internal phases. + // This would be wrong at execution time, but we are here computing a list and not a graph, + // so in order to obtain the expected order, we add these links between phases. + Lifecycle.Phase prev = null; + for (Lifecycle.Phase child : phases) { + // add phase + addPhase(graph, before, after, child); + if (prev != null) { + // add link between end of previous phase and beginning of this one + graph.addEdge(graph.addVertex(AFTER + prev.name()), graph.addVertex(BEFORE + child.name())); + } + prev = child; + } } @Named @@ -375,8 +380,8 @@ public class DefaultLifecycleRegistry implements LifecycleRegistry { @Override public Collection<Phase> phases() { return List.of(phase( - "all", - phase(INITIALIZE, phase(VALIDATE)), + ALL, + phase(VALIDATE, phase(INITIALIZE)), phase( BUILD, after(VALIDATE), @@ -407,6 +412,28 @@ public class DefaultLifecycleRegistry implements LifecycleRegistry { phase(DEPLOY, after(PACKAGE)))); } + @Override + public Collection<Phase> v3phases() { + return List.of(phase( + ALL, + phase(INITIALIZE, phase(VALIDATE)), + phase( + BUILD, + phase(SOURCES), + phase(RESOURCES), + phase(COMPILE), + phase(READY), + phase(TEST_SOURCES), + phase(TEST_RESOURCES), + phase(TEST_COMPILE), + phase(TEST), + phase(UNIT_TEST), + phase(PACKAGE)), + phase(VERIFY, phase(INTEGRATION_TEST)), + phase(INSTALL), + phase(DEPLOY))); + } + @Override public Collection<Alias> aliases() { return List.of( @@ -424,42 +451,6 @@ public class DefaultLifecycleRegistry implements LifecycleRegistry { alias("pre-integration-test", BEFORE + INTEGRATION_TEST), alias("post-integration-test", AFTER + INTEGRATION_TEST)); } - - @Override - public Optional<List<String>> orderedPhases() { - return Optional.of(Arrays.asList( - VALIDATE, - INITIALIZE, - // "generate-sources", - SOURCES, - // "process-sources", - // "generate-resources", - RESOURCES, - // "process-resources", - COMPILE, - // "process-classes", - READY, - // "generate-test-sources", - TEST_SOURCES, - // "process-test-sources", - // "generate-test-resources", - TEST_RESOURCES, - // "process-test-resources", - TEST_COMPILE, - // "process-test-classes", - TEST, - UNIT_TEST, - // "prepare-package", - PACKAGE, - BUILD, - // "pre-integration-test", - INTEGRATION_TEST, - // "post-integration-test", - VERIFY, - INSTALL, - DEPLOY, - "all")); - } } static class SiteLifecycle implements Lifecycle { diff --git a/impl/maven-core/src/main/java/org/apache/maven/lifecycle/Lifecycle.java b/impl/maven-core/src/main/java/org/apache/maven/lifecycle/Lifecycle.java index cc05a32ca6..91d392e280 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/lifecycle/Lifecycle.java +++ b/impl/maven-core/src/main/java/org/apache/maven/lifecycle/Lifecycle.java @@ -23,13 +23,9 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; -import java.util.stream.Stream; import org.apache.maven.lifecycle.mapping.LifecyclePhase; -import static org.apache.maven.api.Lifecycle.AFTER; -import static org.apache.maven.api.Lifecycle.BEFORE; - /** * Lifecycle definition, with eventual plugin bindings (when they are not packaging-specific). */ @@ -46,9 +42,7 @@ public class Lifecycle { org.apache.maven.api.services.LifecycleRegistry registry, org.apache.maven.api.Lifecycle lifecycle) { this.lifecycle = lifecycle; this.id = lifecycle.id(); - this.phases = registry.computePhases(lifecycle).stream() - .flatMap(p -> Stream.of(BEFORE + p, p, AFTER + p)) - .toList(); + this.phases = registry.computePhases(lifecycle); this.defaultPhases = getDefaultPhases(lifecycle); } diff --git a/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java b/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java index 35eadd54c3..bdd6e8e5be 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java +++ b/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java @@ -25,7 +25,6 @@ import javax.xml.stream.XMLStreamException; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -264,13 +263,10 @@ public class DefaultLifecycleExecutionPlanCalculator implements LifecycleExecuti } LifecycleMappingDelegate delegate; - if (Arrays.binarySearch(DefaultLifecycles.STANDARD_LIFECYCLES, lifecycle.getId()) >= 0) { + if (List.of(DefaultLifecycles.STANDARD_LIFECYCLES).contains(lifecycle.getId())) { delegate = standardDelegate; } else { - delegate = delegates.get(lifecycle.getId()); - if (delegate == null) { - delegate = standardDelegate; - } + delegate = delegates.getOrDefault(lifecycle.getId(), standardDelegate); } return delegate.calculateLifecycleMappings(session, project, lifecycle, lifecyclePhase); diff --git a/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleMappingDelegate.java b/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleMappingDelegate.java index 43598103f1..82407e1948 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleMappingDelegate.java +++ b/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleMappingDelegate.java @@ -82,14 +82,23 @@ public class DefaultLifecycleMappingDelegate implements LifecycleMappingDelegate lifecyclePhase = PhaseId.of(aliases.get(lifecyclePhase)).phase(); } + boolean passed = false; for (String phase : lifecycle.getPhases()) { - Map<PhaseId, List<MojoExecution>> phaseBindings = - new TreeMap<>(Comparator.comparing(PhaseId::toString, new PhaseComparator(lifecycle.getPhases()))); - - mappings.put(phase, phaseBindings); - + boolean include = true; if (phase.equals(lifecyclePhase)) { - break; + passed = true; + } else if (passed) { + if (phase.startsWith(org.apache.maven.api.Lifecycle.AFTER)) { + String realPhase = phase.substring(org.apache.maven.api.Lifecycle.AFTER.length()); + include = mappings.containsKey(org.apache.maven.api.Lifecycle.BEFORE + realPhase); + } else { + include = false; + } + } + if (include) { + Map<PhaseId, List<MojoExecution>> phaseBindings = new TreeMap<>( + Comparator.comparing(PhaseId::toString, new PhaseComparator(lifecycle.getPhases()))); + mappings.put(phase, phaseBindings); } } @@ -163,7 +172,7 @@ public class DefaultLifecycleMappingDelegate implements LifecycleMappingDelegate Map<String, Map<PhaseId, List<MojoExecution>>> mappings, String phase) { if (phase != null) { PhaseId id = PhaseId.of(phase); - return mappings.get(id.phase()); + return mappings.get(id.executionPoint().prefix() + id.phase()); } return null; } diff --git a/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/PhaseComparator.java b/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/PhaseComparator.java index 7c8004b8c3..2a1efccfbf 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/PhaseComparator.java +++ b/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/PhaseComparator.java @@ -43,8 +43,8 @@ public class PhaseComparator implements Comparator<String> { public int compare(String o1, String o2) { PhaseId p1 = PhaseId.of(o1); PhaseId p2 = PhaseId.of(o2); - int i1 = lifecyclePhases.indexOf(p1.phase()); - int i2 = lifecyclePhases.indexOf(p2.phase()); + int i1 = lifecyclePhases.indexOf(p1.executionPoint().prefix() + p1.phase()); + int i2 = lifecyclePhases.indexOf(p2.executionPoint().prefix() + p2.phase()); if (i1 == -1 && i2 == -1) { // unknown phases, leave in existing order return 0; @@ -61,13 +61,6 @@ public class PhaseComparator implements Comparator<String> { if (rv != 0) { return rv; } - // same phase, now compare execution points - i1 = p1.executionPoint().ordinal(); - i2 = p2.executionPoint().ordinal(); - rv = Integer.compare(i1, i2); - if (rv != 0) { - return rv; - } // same execution point, now compare priorities return Integer.compare(p1.priority(), p2.priority()); } diff --git a/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/concurrent/BuildPlanExecutor.java b/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/concurrent/BuildPlanExecutor.java index 57fdc9dabb..5dfa27cb9b 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/concurrent/BuildPlanExecutor.java +++ b/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/concurrent/BuildPlanExecutor.java @@ -410,6 +410,9 @@ public class BuildPlanExecutor { MojoDescriptor mojoDescriptor = getMojoDescriptor(project, plugin, goal); String phase = execution.getPhase() != null ? execution.getPhase() : mojoDescriptor.getPhase(); + if (phase == null) { + continue; + } String tmpResolvedPhase = plan.aliases().getOrDefault(phase, phase); String resolvedPhase = tmpResolvedPhase.startsWith(AT) ? tmpResolvedPhase.substring(AT.length()) @@ -680,9 +683,7 @@ public class BuildPlanExecutor { + " or a goal in the format <plugin-prefix>:<goal> or" + " <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: " + lifecycles.stream() - .flatMap(l -> l.orderedPhases() - .map(List::stream) - .orElseGet(() -> l.allPhases().map(Lifecycle.Phase::name))) + .flatMap(l -> l.allPhases().map(Lifecycle.Phase::name)) .collect(Collectors.joining(", ")) + ".", lifecyclePhase)); @@ -735,6 +736,10 @@ public class BuildPlanExecutor { ? lifecyclePhase.substring(AT.length()) : AFTER + lifecyclePhase; Set<BuildStep> toKeep = steps.get(endPhase).allPredecessors().collect(Collectors.toSet()); + toKeep.addAll(toKeep.stream() + .filter(s -> s.name.startsWith(BEFORE)) + .map(s -> steps.get(AFTER + s.name.substring(BEFORE.length()))) + .toList()); steps.values().stream().filter(n -> !toKeep.contains(n)).forEach(BuildStep::skip); plan.addProject(project, steps); diff --git a/impl/maven-core/src/test/java/org/apache/maven/lifecycle/LifecycleExecutorTest.java b/impl/maven-core/src/test/java/org/apache/maven/lifecycle/LifecycleExecutorTest.java index 46f3553c9e..ca7a81f0bf 100644 --- a/impl/maven-core/src/test/java/org/apache/maven/lifecycle/LifecycleExecutorTest.java +++ b/impl/maven-core/src/test/java/org/apache/maven/lifecycle/LifecycleExecutorTest.java @@ -173,26 +173,21 @@ class LifecycleExecutorTest extends AbstractCoreMavenComponentTestCase { // [09] jar:jar // [10] install:install // - assertEquals(10, executionPlan.size()); - - assertEquals("clean:clean", executionPlan.get(0).getMojoDescriptor().getFullGoalName()); - assertEquals( - "resources:resources", executionPlan.get(1).getMojoDescriptor().getFullGoalName()); - assertEquals( - "compiler:compile", executionPlan.get(2).getMojoDescriptor().getFullGoalName()); - assertEquals( - "it:generate-metadata", executionPlan.get(3).getMojoDescriptor().getFullGoalName()); - assertEquals( - "resources:testResources", - executionPlan.get(4).getMojoDescriptor().getFullGoalName()); - assertEquals( - "compiler:testCompile", executionPlan.get(5).getMojoDescriptor().getFullGoalName()); - assertEquals( - "it:generate-test-metadata", - executionPlan.get(6).getMojoDescriptor().getFullGoalName()); - assertEquals("surefire:test", executionPlan.get(7).getMojoDescriptor().getFullGoalName()); - assertEquals("jar:jar", executionPlan.get(8).getMojoDescriptor().getFullGoalName()); - assertEquals("install:install", executionPlan.get(9).getMojoDescriptor().getFullGoalName()); + assertListEquals( + List.of( + "clean:clean", + "resources:resources", + "compiler:compile", + "it:generate-metadata", + "resources:testResources", + "compiler:testCompile", + "it:generate-test-metadata", + "surefire:test", + "jar:jar", + "install:install"), + executionPlan.stream() + .map(plan -> plan.getMojoDescriptor().getFullGoalName()) + .toList()); } // We need to take in multiple lifecycles @@ -226,31 +221,29 @@ class LifecycleExecutorTest extends AbstractCoreMavenComponentTestCase { // [16] install:install // - assertEquals(16, executions.size()); - - assertEquals("clean:clean", executions.get(0).getMojoDescriptor().getFullGoalName()); - assertEquals("it:xpp3-writer", executions.get(1).getMojoDescriptor().getFullGoalName()); - assertEquals("it:java", executions.get(2).getMojoDescriptor().getFullGoalName()); - assertEquals("it:xpp3-reader", executions.get(3).getMojoDescriptor().getFullGoalName()); - assertEquals("it:xpp3-writer", executions.get(4).getMojoDescriptor().getFullGoalName()); - assertEquals("it:java", executions.get(5).getMojoDescriptor().getFullGoalName()); - assertEquals("it:xpp3-reader", executions.get(6).getMojoDescriptor().getFullGoalName()); - assertEquals( - "resources:resources", executions.get(7).getMojoDescriptor().getFullGoalName()); - assertEquals("compiler:compile", executions.get(8).getMojoDescriptor().getFullGoalName()); - assertEquals("plugin:descriptor", executions.get(9).getMojoDescriptor().getFullGoalName()); - assertEquals( - "resources:testResources", - executions.get(10).getMojoDescriptor().getFullGoalName()); - assertEquals( - "compiler:testCompile", executions.get(11).getMojoDescriptor().getFullGoalName()); - assertEquals("surefire:test", executions.get(12).getMojoDescriptor().getFullGoalName()); - assertEquals("jar:jar", executions.get(13).getMojoDescriptor().getFullGoalName()); - assertEquals( - "plugin:addPluginArtifactMetadata", - executions.get(14).getMojoDescriptor().getFullGoalName()); - assertEquals("install:install", executions.get(15).getMojoDescriptor().getFullGoalName()); - + assertListEquals( + List.of( + "clean:clean", + "it:xpp3-writer", + "it:java", + "it:xpp3-reader", + "it:xpp3-writer", + "it:java", + "it:xpp3-reader", + "resources:resources", + "compiler:compile", + "plugin:descriptor", + "resources:testResources", + "compiler:testCompile", + "surefire:test", + "jar:jar", + "plugin:addPluginArtifactMetadata", + "install:install"), + executions.stream() + .map(execution -> execution.getMojoDescriptor().getFullGoalName()) + .toList()); + + // Keep the separate configuration checks assertEquals( "src/main/mdo/remote-resources.mdo", new MojoExecutionXPathContainer(executions.get(1)).getValue("configuration/models[1]/model")); @@ -278,24 +271,19 @@ class LifecycleExecutorTest extends AbstractCoreMavenComponentTestCase { // [07] surefire:test // [08] jar:jar // - assertEquals(8, executionPlan.size()); - - assertEquals( - "resources:resources", executionPlan.get(0).getMojoDescriptor().getFullGoalName()); - assertEquals( - "compiler:compile", executionPlan.get(1).getMojoDescriptor().getFullGoalName()); - assertEquals( - "it:generate-metadata", executionPlan.get(2).getMojoDescriptor().getFullGoalName()); - assertEquals( - "resources:testResources", - executionPlan.get(3).getMojoDescriptor().getFullGoalName()); - assertEquals( - "compiler:testCompile", executionPlan.get(4).getMojoDescriptor().getFullGoalName()); - assertEquals( - "it:generate-test-metadata", - executionPlan.get(5).getMojoDescriptor().getFullGoalName()); - assertEquals("surefire:test", executionPlan.get(6).getMojoDescriptor().getFullGoalName()); - assertEquals("jar:jar", executionPlan.get(7).getMojoDescriptor().getFullGoalName()); + assertListEquals( + List.of( + "resources:resources", + "compiler:compile", + "it:generate-metadata", + "resources:testResources", + "compiler:testCompile", + "it:generate-test-metadata", + "surefire:test", + "jar:jar"), + executionPlan.stream() + .map(plan -> plan.getMojoDescriptor().getFullGoalName()) + .toList()); } @Test @@ -516,18 +504,14 @@ class LifecycleExecutorTest extends AbstractCoreMavenComponentTestCase { "afterProjectExecutionSuccess project-basic" // ); - assertEventLog(expectedLog, log); + assertListEquals(expectedLog, log); } - private static void assertEventLog(List<String> expectedList, List<String> actualList) { + private static void assertListEquals(List<String> expectedList, List<String> actualList) { assertEquals(toString(expectedList), toString(actualList)); } private static String toString(List<String> lines) { - StringBuilder sb = new StringBuilder(); - for (String line : lines) { - sb.append(line).append('\n'); - } - return sb.toString(); + return String.join("\n", lines); } } diff --git a/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng8244PhaseAllTest.java b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng8244PhaseAllTest.java new file mode 100644 index 0000000000..99e1980249 --- /dev/null +++ b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng8244PhaseAllTest.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.it; + +import java.io.File; + +import org.junit.jupiter.api.Test; + +/** + * This is a test set for <a href="https://issues.apache.org/jira/browse/MNG-8244">MNG-8244</a>. + */ +class MavenITmng8244PhaseAllTest extends AbstractMavenIntegrationTestCase { + + MavenITmng8244PhaseAllTest() { + super("[4.0.0-rc-2,)"); + } + + /** + * Verify phase after:all phase is called + */ + @Test + void testPhaseAllWihConcurrentBuilder() throws Exception { + File testDir = extractResources("/mng-8244-phase-all"); + + Verifier verifier = newVerifier(testDir.getAbsolutePath()); + verifier.setLogFileName("build-concurrent.txt"); + verifier.addCliArguments("-b", "concurrent", "build"); + verifier.execute(); + + verifier.verifyTextInLog("Hallo 'before:all' phase."); + verifier.verifyTextInLog("Hallo 'after:all' phase."); + } + + /** + * Verify phase after:all phase is called + */ + @Test + void testPhaseAllWithLegacyBuilder() throws Exception { + File testDir = extractResources("/mng-8244-phase-all"); + + Verifier verifier = newVerifier(testDir.getAbsolutePath()); + verifier.setLogFileName("build-legacy.txt"); + verifier.addCliArguments("build"); + verifier.execute(); + + verifier.verifyTextInLog("Hallo 'before:all' phase."); + verifier.verifyTextInLog("Hallo 'after:all' phase."); + } +} diff --git a/its/core-it-suite/src/test/java/org/apache/maven/it/TestSuiteOrdering.java b/its/core-it-suite/src/test/java/org/apache/maven/it/TestSuiteOrdering.java index ac5b592a86..5a5a4c149a 100644 --- a/its/core-it-suite/src/test/java/org/apache/maven/it/TestSuiteOrdering.java +++ b/its/core-it-suite/src/test/java/org/apache/maven/it/TestSuiteOrdering.java @@ -100,6 +100,7 @@ public class TestSuiteOrdering implements ClassOrderer { * the tests are to finishing. Newer tests are also more likely to fail, so this is * a fail fast technique as well. */ + suite.addTestSuite(MavenITmng8244PhaseAllTest.class); suite.addTestSuite(MavenITmng8421MavenEncryptionTest.class); suite.addTestSuite(MavenITmng8400CanonicalMavenHomeTest.class); suite.addTestSuite(MavenITmng8385PropertyContributoSPITest.class); diff --git a/its/core-it-suite/src/test/resources/mng-8244-phase-all/pom.xml b/its/core-it-suite/src/test/resources/mng-8244-phase-all/pom.xml new file mode 100644 index 0000000000..35250bb229 --- /dev/null +++ b/its/core-it-suite/src/test/resources/mng-8244-phase-all/pom.xml @@ -0,0 +1,117 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" root="true" xsi:schemaLocation="http://maven.apache.org/POM/4.1.0 https://maven.apache.org/xsd/maven-4.1.0.xsd"> + + <groupId>org.apache.maven.its</groupId> + <artifactId>mng-8244</artifactId> + <version>1.0.0-SNAPSHOT</version> + + <build> + <plugins> + <plugin> + <groupId>com.soebes.maven.plugins</groupId> + <artifactId>echo-maven-plugin</artifactId> + <version>0.5.0</version> + <executions> + <execution> + <id>before-clean</id> + <goals> + <goal>echo</goal> + </goals> + <phase>before:clean</phase> + <configuration> + <echos> + <echo>Hallo 'before:clean' phase.</echo> + </echos> + </configuration> + </execution> + <execution> + <id>after-clean</id> + <goals> + <goal>echo</goal> + </goals> + <phase>after:clean</phase> + <configuration> + <echos> + <echo>Hallo 'after:clean' phase.</echo> + </echos> + </configuration> + </execution> + <execution> + <id>before-build</id> + <goals> + <goal>echo</goal> + </goals> + <phase>before:build</phase> + <configuration> + <echos> + <echo>Hallo 'before:build' phase.</echo> + </echos> + </configuration> + </execution> + <execution> + <id>build</id> + <goals> + <goal>echo</goal> + </goals> + <phase>build</phase> + <configuration> + <echos> + <echo>Hallo 'build' phase.</echo> + </echos> + </configuration> + </execution> + <execution> + <id>after-build</id> + <goals> + <goal>echo</goal> + </goals> + <phase>after:build</phase> + <configuration> + <echos> + <echo>Hallo 'after:build' phase.</echo> + </echos> + </configuration> + </execution> + <execution> + <id>before-all</id> + <goals> + <goal>echo</goal> + </goals> + <phase>before:all</phase> + <configuration> + <echos> + <echo>Hallo 'before:all' phase.</echo> + </echos> + </configuration> + </execution> + <execution> + <id>all</id> + <goals> + <goal>echo</goal> + </goals> + <phase>all</phase> + <configuration> + <echos> + <echo>Hallo 'all' phase.</echo> + </echos> + </configuration> + </execution> + <execution> + <id>after-all</id> + <goals> + <goal>echo</goal> + </goals> + <phase>after:all</phase> + <configuration> + <echos> + <echo>Hallo 'after:all' phase.</echo> + </echos> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + + </build> + +</project>