[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 @@ package org.apache.maven.lifecycle;
*/
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.util.StringUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Objects;
import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.inject.Named;
@ -46,30 +44,39 @@ import javax.inject.Singleton;
@Singleton
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")
@Inject
private Map<String, Lifecycle> lifecycles;
private final Map<String, Lifecycle> lifecyclesMap;
@Inject
private Logger logger;
private final Logger logger;
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.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 class DefaultLifecycles
// 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.
HashMap<String, Lifecycle> phaseToLifecycleMap = new HashMap<>();
Map<String, Lifecycle> phaseToLifecycleMap = new HashMap<>();
for ( Lifecycle lifecycle : getLifeCycles() )
{
@ -113,36 +120,32 @@ public class DefaultLifecycles
public List<Lifecycle> getLifeCycles()
{
// ensure canonical order of standard lifecycles
Map<String, Lifecycle> lifecycles = new LinkedHashMap<>( this.lifecycles );
LinkedHashSet<String> lifecycleNames = new LinkedHashSet<>( Arrays.asList( STANDARD_LIFECYCLES ) );
lifecycleNames.addAll( lifecycles.keySet() );
ArrayList<Lifecycle> result = new ArrayList<>();
for ( String name : lifecycleNames )
List<String> lifecycleIds = Arrays.asList( STANDARD_LIFECYCLES );
Comparator<String> comparator = ( l, r ) ->
{
Lifecycle lifecycle = lifecycles.get( name );
if ( lifecycle.getId() == null )
if ( lifecycleIds.contains( l ) )
{
throw new NullPointerException( "A lifecycle must have an id." );
return lifecycleIds.indexOf( l ) - lifecycleIds.indexOf( r );
}
result.add( lifecycle );
}
return result;
else
{
return Integer.MAX_VALUE;
}
};
// 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()
{
Set<String> phases = new LinkedHashSet<>();
for ( Lifecycle lifecycle : getLifeCycles() )
{
phases.addAll( lifecycle.getPhases() );
}
return StringUtils.join( phases.iterator(), ", " );
return getLifeCycles().stream()
.flatMap( l -> l.getPhases().stream() )
.collect( Collectors.joining( ", " ) );
}
}

View File

@ -111,6 +111,26 @@ under the License.
</configuration>
</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>
<role>org.sonatype.plexus.components.sec.dispatcher.SecDispatcher</role>
<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
* 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
* 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.PlexusConstants;
import org.codehaus.plexus.PlexusTestCase;
import org.codehaus.plexus.component.annotations.Requirement;
import java.util.List;
/**
* @author Kristian Rosenvold
*/
@ -32,12 +42,11 @@ public class DefaultLifecyclesTest
private DefaultLifecycles defaultLifeCycles;
@Override
protected void customizeContainerConfiguration(
ContainerConfiguration configuration)
protected void customizeContainerConfiguration( ContainerConfiguration configuration )
{
super.customizeContainerConfiguration(configuration);
configuration.setAutoWiring(true);
configuration.setClassPathScanning(PlexusConstants.SCANNING_INDEX);
super.customizeContainerConfiguration( configuration );
configuration.setAutoWiring( true );
configuration.setClassPathScanning( PlexusConstants.SCANNING_INDEX );
}
protected void setUp()
@ -55,15 +64,66 @@ public class DefaultLifecyclesTest
super.tearDown();
}
public void testLifecycle()
throws Exception
public void testDefaultLifecycles()
{
final List<Lifecycle> cycles = defaultLifeCycles.getLifeCycles();
assertNotNull( cycles );
final Lifecycle lifecycle = cycles.get( 0 );
assertEquals( "default", lifecycle.getId() );
assertEquals( 23, lifecycle.getPhases().size() );
final List<Lifecycle> lifecycles = defaultLifeCycles.getLifeCycles();
assertThat( lifecycles, hasSize( 4 ) );
assertThat( DefaultLifecycles.STANDARD_LIFECYCLES, arrayWithSize( 4 ) );
}
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 @@ package org.apache.maven.lifecycle;
* the License.
*/
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
@ -287,7 +290,7 @@ public class LifecycleExecutorTest
List<Plugin> plugins =
new ArrayList<>( lifecycleExecutor.getPluginsBoundByDefaultToAllLifecycles( "jar" ) );
assertEquals( 8, plugins.size() );
assertThat( plugins.toString(), plugins, hasSize( 9 ) );
}
public void testPluginConfigurationCreation()
@ -395,30 +398,29 @@ public class LifecycleExecutorTest
final MavenSession session = createMavenSession( pom );
session.setProjectDependencyGraph( new ProjectDependencyGraph()
{
@Override
public List<MavenProject> getUpstreamProjects( MavenProject project, boolean transitive )
{
return Collections.emptyList();
}
@Override
public List<MavenProject> getAllProjects()
{
return session.getAllProjects();
}
@Override
public List<MavenProject> getSortedProjects()
{
return Collections.singletonList( session.getCurrentProject() );
}
@Override
public List<MavenProject> getDownstreamProjects( MavenProject project, boolean transitive )
{
return Collections.emptyList();
}
public java.util.List<MavenProject> getAllSortedProjects()
{
return Collections.emptyList();
}
} );
final List<String> log = new ArrayList<>();

View File

@ -47,7 +47,9 @@ public class DefaultLifecyclesStub
List<String> stubSiteCycle =
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<>();
for ( String s : DefaultLifecycles.STANDARD_LIFECYCLES )

View File

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