[MNG-6917] Introduce wrapper lifecycle

This commit is contained in:
rfscholte 2020-06-22 20:26:56 +02:00
parent b373bb06e8
commit 881274914a
6 changed files with 154 additions and 63 deletions

View File

@ -20,16 +20,14 @@
*/ */
import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.util.StringUtils;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Objects;
import java.util.stream.Collectors;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
@ -46,30 +44,39 @@
@Singleton @Singleton
public class DefaultLifecycles public class DefaultLifecycles
{ {
public static final String[] STANDARD_LIFECYCLES = { "default", "clean", "site" }; public static final String[] STANDARD_LIFECYCLES = { "default", "clean", "site", "wrapper" };
// @Configuration(source="org/apache/maven/lifecycle/lifecycles.xml") // @Configuration(source="org/apache/maven/lifecycle/lifecycles.xml")
@Inject private final Map<String, Lifecycle> lifecyclesMap;
private Map<String, Lifecycle> lifecycles;
@Inject private final Logger logger;
private Logger logger;
public DefaultLifecycles() public DefaultLifecycles()
{ {
this.lifecyclesMap = null;
this.logger = null;
} }
public DefaultLifecycles( Map<String, Lifecycle> lifecycles, Logger logger ) @Inject
public DefaultLifecycles( Map<String, Lifecycle> lifecyclesMap, Logger logger )
{ {
this.lifecycles = new LinkedHashMap<>(); // Must keep the lifecyclesMap as is.
// During initialization it only contains the default lifecycles.
// However, extensions might add custom lifecycles later on.
this.lifecyclesMap = lifecyclesMap;
this.logger = logger; this.logger = logger;
this.lifecycles = lifecycles;
} }
public Lifecycle get( String key ) /**
* Get lifecycle based on phase
*
* @param phase
* @return
*/
public Lifecycle get( String phase )
{ {
return getPhaseToLifecycleMap().get( key ); return getPhaseToLifecycleMap().get( phase );
} }
/** /**
@ -83,7 +90,7 @@ public Map<String, Lifecycle> getPhaseToLifecycleMap()
// If people are going to make their own lifecycles then we need to tell people how to namespace them correctly // If people are going to make their own lifecycles then we need to tell people how to namespace them correctly
// so that they don't interfere with internally defined lifecycles. // so that they don't interfere with internally defined lifecycles.
HashMap<String, Lifecycle> phaseToLifecycleMap = new HashMap<>(); Map<String, Lifecycle> phaseToLifecycleMap = new HashMap<>();
for ( Lifecycle lifecycle : getLifeCycles() ) for ( Lifecycle lifecycle : getLifeCycles() )
{ {
@ -113,36 +120,32 @@ public Map<String, Lifecycle> getPhaseToLifecycleMap()
public List<Lifecycle> getLifeCycles() public List<Lifecycle> getLifeCycles()
{ {
// ensure canonical order of standard lifecycles List<String> lifecycleIds = Arrays.asList( STANDARD_LIFECYCLES );
Map<String, Lifecycle> lifecycles = new LinkedHashMap<>( this.lifecycles );
LinkedHashSet<String> lifecycleNames = new LinkedHashSet<>( Arrays.asList( STANDARD_LIFECYCLES ) ); Comparator<String> comparator = ( l, r ) ->
lifecycleNames.addAll( lifecycles.keySet() );
ArrayList<Lifecycle> result = new ArrayList<>();
for ( String name : lifecycleNames )
{ {
Lifecycle lifecycle = lifecycles.get( name ); if ( lifecycleIds.contains( l ) )
if ( lifecycle.getId() == null )
{ {
throw new NullPointerException( "A lifecycle must have an id." ); return lifecycleIds.indexOf( l ) - lifecycleIds.indexOf( r );
} }
result.add( lifecycle ); else
} {
return Integer.MAX_VALUE;
}
};
return result; // ensure canonical order of standard lifecycles
return lifecyclesMap.values().stream()
.peek( l -> Objects.requireNonNull( l.getId(), "A lifecycle must have an id." ) )
.sorted( Comparator.comparing( Lifecycle::getId, comparator ) )
.collect( Collectors.toList() );
} }
public String getLifecyclePhaseList() public String getLifecyclePhaseList()
{ {
Set<String> phases = new LinkedHashSet<>(); return getLifeCycles().stream()
.flatMap( l -> l.getPhases().stream() )
for ( Lifecycle lifecycle : getLifeCycles() ) .collect( Collectors.joining( ", " ) );
{
phases.addAll( lifecycle.getPhases() );
}
return StringUtils.join( phases.iterator(), ", " );
} }
} }

View File

@ -111,6 +111,26 @@ under the License.
</configuration> </configuration>
</component> </component>
<!-- 'wrapper' lifecycle, with default bindings -->
<component>
<role>org.apache.maven.lifecycle.Lifecycle</role>
<implementation>org.apache.maven.lifecycle.Lifecycle</implementation>
<role-hint>wrapper</role-hint>
<configuration>
<id>wrapper</id>
<!-- START SNIPPET: wrapper -->
<phases>
<phase>wrapper</phase>
</phases>
<default-phases>
<wrapper>
org.apache.maven.plugins:maven-wrapper-plugin:3.0.1:wrapper
</wrapper>
</default-phases>
<!-- END SNIPPET: wrapper -->
</configuration>
</component>
<component> <component>
<role>org.sonatype.plexus.components.sec.dispatcher.SecDispatcher</role> <role>org.sonatype.plexus.components.sec.dispatcher.SecDispatcher</role>
<role-hint>maven</role-hint> <role-hint>maven</role-hint>

View File

@ -1,3 +1,5 @@
package org.apache.maven.lifecycle;
/* /*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license * 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 * agreements. See the NOTICE file distributed with this work for additional information regarding
@ -12,15 +14,23 @@
* or implied. See the License for the specific language governing permissions and limitations under * or implied. See the License for the specific language governing permissions and limitations under
* the License. * the License.
*/ */
package org.apache.maven.lifecycle;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.arrayWithSize;
import static org.hamcrest.Matchers.hasSize;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.codehaus.plexus.ContainerConfiguration; import org.codehaus.plexus.ContainerConfiguration;
import org.codehaus.plexus.PlexusConstants; import org.codehaus.plexus.PlexusConstants;
import org.codehaus.plexus.PlexusTestCase; import org.codehaus.plexus.PlexusTestCase;
import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.component.annotations.Requirement;
import java.util.List;
/** /**
* @author Kristian Rosenvold * @author Kristian Rosenvold
*/ */
@ -32,12 +42,11 @@ public class DefaultLifecyclesTest
private DefaultLifecycles defaultLifeCycles; private DefaultLifecycles defaultLifeCycles;
@Override @Override
protected void customizeContainerConfiguration( protected void customizeContainerConfiguration( ContainerConfiguration configuration )
ContainerConfiguration configuration)
{ {
super.customizeContainerConfiguration(configuration); super.customizeContainerConfiguration( configuration );
configuration.setAutoWiring(true); configuration.setAutoWiring( true );
configuration.setClassPathScanning(PlexusConstants.SCANNING_INDEX); configuration.setClassPathScanning( PlexusConstants.SCANNING_INDEX );
} }
protected void setUp() protected void setUp()
@ -55,15 +64,66 @@ protected void tearDown()
super.tearDown(); super.tearDown();
} }
public void testLifecycle() public void testDefaultLifecycles()
throws Exception
{ {
final List<Lifecycle> cycles = defaultLifeCycles.getLifeCycles(); final List<Lifecycle> lifecycles = defaultLifeCycles.getLifeCycles();
assertNotNull( cycles ); assertThat( lifecycles, hasSize( 4 ) );
final Lifecycle lifecycle = cycles.get( 0 ); assertThat( DefaultLifecycles.STANDARD_LIFECYCLES, arrayWithSize( 4 ) );
assertEquals( "default", lifecycle.getId() );
assertEquals( 23, lifecycle.getPhases().size() );
} }
public void testDefaultLifecycle()
{
final Lifecycle lifecycle = getLifeCycleById( "default" );
assertThat( lifecycle.getId(), is( "default" ) );
assertThat( lifecycle.getPhases(), hasSize( 23 ) );
}
public void testCleanLifecycle()
{
final Lifecycle lifecycle = getLifeCycleById( "clean" );
assertThat( lifecycle.getId(), is( "clean" ) );
assertThat( lifecycle.getPhases(), hasSize( 3 ) );
}
public void testSiteLifecycle()
{
final Lifecycle lifecycle = getLifeCycleById( "site" );
assertThat( lifecycle.getId(), is( "site" ) );
assertThat( lifecycle.getPhases(), hasSize( 4 ) );
}
public void testWrapperLifecycle()
{
final Lifecycle lifecycle = getLifeCycleById( "wrapper" );
assertThat( lifecycle.getId(), is( "wrapper" ) );
assertThat( lifecycle.getPhases(), hasSize( 1 ) );
}
public void testCustomLifecycle()
{
List<Lifecycle> myLifecycles = new ArrayList<>();
Lifecycle myLifecycle = new Lifecycle( "etl",
Arrays.asList( "extract", "transform", "load" ),
Collections.emptyMap() );
myLifecycles.add( myLifecycle );
myLifecycles.addAll( defaultLifeCycles.getLifeCycles() );
DefaultLifecycles dl = new DefaultLifecycles( myLifecycles.stream()
.collect( Collectors.toMap( l -> l.getId(), l -> l ) ),
null );
assertThat( dl.getLifeCycles().get( 0 ).getId(), is( "default" ) );
assertThat( dl.getLifeCycles().get( 1 ).getId(), is( "clean" ) );
assertThat( dl.getLifeCycles().get( 2 ).getId(), is( "site" ) );
assertThat( dl.getLifeCycles().get( 3 ).getId(), is( "wrapper" ) );
assertThat( dl.getLifeCycles().get( 4 ).getId(), is( "etl" ) );
}
private Lifecycle getLifeCycleById( String id )
{
return defaultLifeCycles.getLifeCycles().stream()
.filter( l -> id.equals( l.getId() ) )
.findFirst()
.orElseThrow( IllegalArgumentException::new );
}
} }

View File

@ -15,6 +15,9 @@
* the License. * the License.
*/ */
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -287,7 +290,7 @@ public void testLifecyclePluginsRetrievalForDefaultLifecycle()
List<Plugin> plugins = List<Plugin> plugins =
new ArrayList<>( lifecycleExecutor.getPluginsBoundByDefaultToAllLifecycles( "jar" ) ); new ArrayList<>( lifecycleExecutor.getPluginsBoundByDefaultToAllLifecycles( "jar" ) );
assertEquals( 8, plugins.size() ); assertThat( plugins.toString(), plugins, hasSize( 9 ) );
} }
public void testPluginConfigurationCreation() public void testPluginConfigurationCreation()
@ -395,30 +398,29 @@ public void testExecutionListeners()
final MavenSession session = createMavenSession( pom ); final MavenSession session = createMavenSession( pom );
session.setProjectDependencyGraph( new ProjectDependencyGraph() session.setProjectDependencyGraph( new ProjectDependencyGraph()
{ {
@Override
public List<MavenProject> getUpstreamProjects( MavenProject project, boolean transitive ) public List<MavenProject> getUpstreamProjects( MavenProject project, boolean transitive )
{ {
return Collections.emptyList(); return Collections.emptyList();
} }
@Override
public List<MavenProject> getAllProjects() public List<MavenProject> getAllProjects()
{ {
return session.getAllProjects(); return session.getAllProjects();
} }
@Override
public List<MavenProject> getSortedProjects() public List<MavenProject> getSortedProjects()
{ {
return Collections.singletonList( session.getCurrentProject() ); return Collections.singletonList( session.getCurrentProject() );
} }
@Override
public List<MavenProject> getDownstreamProjects( MavenProject project, boolean transitive ) public List<MavenProject> getDownstreamProjects( MavenProject project, boolean transitive )
{ {
return Collections.emptyList(); return Collections.emptyList();
} }
public java.util.List<MavenProject> getAllSortedProjects()
{
return Collections.emptyList();
}
} ); } );
final List<String> log = new ArrayList<>(); final List<String> log = new ArrayList<>();

View File

@ -47,7 +47,9 @@ public static DefaultLifecycles createDefaultLifecycles()
List<String> stubSiteCycle = List<String> stubSiteCycle =
Arrays.asList( PRE_SITE.getPhase(), SITE.getPhase(), POST_SITE.getPhase(), SITE_DEPLOY.getPhase() ); Arrays.asList( PRE_SITE.getPhase(), SITE.getPhase(), POST_SITE.getPhase(), SITE_DEPLOY.getPhase() );
Iterator<List<String>> lcs = Arrays.asList( stubDefaultCycle, stubCleanCycle, stubSiteCycle ).iterator(); List<String> stubWrapperCycle = Arrays.asList( WRAPPER.getPhase() );
Iterator<List<String>> lcs = Arrays.asList( stubDefaultCycle, stubCleanCycle, stubSiteCycle, stubWrapperCycle ).iterator();
Map<String, Lifecycle> lifeCycles = new HashMap<>(); Map<String, Lifecycle> lifeCycles = new HashMap<>();
for ( String s : DefaultLifecycles.STANDARD_LIFECYCLES ) for ( String s : DefaultLifecycles.STANDARD_LIFECYCLES )

View File

@ -90,6 +90,10 @@ public class LifecycleExecutionPlanCalculatorStub
public final static MojoDescriptor SITE_DEPLOY = createMojoDescriptor( "site-deploy" ); public final static MojoDescriptor SITE_DEPLOY = createMojoDescriptor( "site-deploy" );
// wrapper
public final static MojoDescriptor WRAPPER = createMojoDescriptor( "wrapper" );
/** /**
* @deprecated instead use {@link #getNumberOfExecutions(ProjectBuildList)} * @deprecated instead use {@link #getNumberOfExecutions(ProjectBuildList)}
*/ */