You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by if...@apache.org on 2014/02/10 04:10:47 UTC

git commit: MNG-5581 Introduced LifecycleMappingDelegate extension point

Updated Branches:
  refs/heads/master 1d84cbeff -> f8afa711d


MNG-5581 Introduced LifecycleMappingDelegate extension point

LifecycleMappingDelegate allows extension points provide custom
lifecycle mapping logic. The main usecase is to allow lifecycle
that reuse plugin configuration from default lifecycle. For
example "test-only" lifecycle will only run mojos bound to
tests phase of default lifecycle and nothing else.

Signed-off-by: Igor Fedorenko <if...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/maven/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven/commit/f8afa711
Tree: http://git-wip-us.apache.org/repos/asf/maven/tree/f8afa711
Diff: http://git-wip-us.apache.org/repos/asf/maven/diff/f8afa711

Branch: refs/heads/master
Commit: f8afa711df2aeab23d2d08214ba100ee704d23ba
Parents: 1d84cbe
Author: Igor Fedorenko <if...@apache.org>
Authored: Wed Jan 15 10:33:53 2014 -0500
Committer: Igor Fedorenko <if...@apache.org>
Committed: Sun Feb 9 22:09:34 2014 -0500

----------------------------------------------------------------------
 .../lifecycle/LifecycleMappingDelegate.java     |  53 +++++++
 ...DefaultLifecycleExecutionPlanCalculator.java | 107 ++-----------
 .../DefaultLifecycleMappingDelegate.java        | 158 +++++++++++++++++++
 3 files changed, 227 insertions(+), 91 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven/blob/f8afa711/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleMappingDelegate.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleMappingDelegate.java b/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleMappingDelegate.java
new file mode 100644
index 0000000..9076d13
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleMappingDelegate.java
@@ -0,0 +1,53 @@
+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 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.
+ */
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.internal.DefaultLifecycleMappingDelegate;
+import org.apache.maven.plugin.InvalidPluginDescriptorException;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.plugin.MojoNotFoundException;
+import org.apache.maven.plugin.PluginDescriptorParsingException;
+import org.apache.maven.plugin.PluginNotFoundException;
+import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.project.MavenProject;
+
+/**
+ * Lifecycle mapping delegate component interface. Calculates project build execution plan given {@link Lifecycle} and
+ * lifecycle phase. Standard lifecycles use plugin execution {@code <phase>} or mojo default lifecycle phase to
+ * calculate the execution plan, but custom lifecycles can use alternative mapping strategies.
+ * <p>
+ * Implementations of this interface must be annotated with either {@code @Named("lifecycle-id")} or equivalent plexus
+ * {@code @Component} annotations.
+ * 
+ * @since 3.2.0
+ * @see DefaultLifecycleMappingDelegate
+ * @author ifedorenko
+ */
+public interface LifecycleMappingDelegate
+{
+    Map<String, List<MojoExecution>> calculateLifecycleMappings( MavenSession session, MavenProject project,
+                                                                 Lifecycle lifecycle, String lifecyclePhase )
+        throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+        MojoNotFoundException, InvalidPluginDescriptorException;
+}

http://git-wip-us.apache.org/repos/asf/maven/blob/f8afa711/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java
index a04024d..5602a09 100644
--- a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java
+++ b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java
@@ -21,17 +21,17 @@ package org.apache.maven.lifecycle.internal;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
-import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.TreeMap;
 
 import org.apache.maven.execution.MavenSession;
 import org.apache.maven.lifecycle.DefaultLifecycles;
 import org.apache.maven.lifecycle.Lifecycle;
+import org.apache.maven.lifecycle.LifecycleMappingDelegate;
 import org.apache.maven.lifecycle.LifecycleNotFoundException;
 import org.apache.maven.lifecycle.LifecyclePhaseNotFoundException;
 import org.apache.maven.lifecycle.MavenExecutionPlan;
@@ -86,6 +86,12 @@ public class DefaultLifecycleExecutionPlanCalculator
     @Requirement
     private LifecyclePluginResolver lifecyclePluginResolver;
 
+    @Requirement( hint = DefaultLifecycleMappingDelegate.HINT )
+    private LifecycleMappingDelegate standardDelegate;
+
+    @Requirement
+    private Map<String, LifecycleMappingDelegate> delegates;
+
     @SuppressWarnings( { "UnusedDeclaration" } )
     public DefaultLifecycleExecutionPlanCalculator()
     {
@@ -225,102 +231,21 @@ public class DefaultLifecycleExecutionPlanCalculator
                 + defaultLifeCycles.getLifecyclePhaseList() + ".", lifecyclePhase );
         }
 
-        /*
-         * Initialize mapping from lifecycle phase to bound mojos. The key set of this map denotes the phases the caller
-         * is interested in, i.e. all phases up to and including the specified phase.
-         */
-
-        Map<String, Map<Integer, List<MojoExecution>>> mappings =
-            new LinkedHashMap<String, Map<Integer, List<MojoExecution>>>();
-
-        for ( String phase : lifecycle.getPhases() )
-        {
-            Map<Integer, List<MojoExecution>> phaseBindings = new TreeMap<Integer, List<MojoExecution>>();
-
-            mappings.put( phase, phaseBindings );
-
-            if ( phase.equals( lifecyclePhase ) )
-            {
-                break;
-            }
-        }
-
-        /*
-         * Grab plugin executions that are bound to the selected lifecycle phases from project. The effective model of
-         * the project already contains the plugin executions induced by the project's packaging type. Remember, all
-         * phases of interest and only those are in the lifecyle mapping, if a phase has no value in the map, we are not
-         * interested in any of the executions bound to it.
-         */
-
-        for ( Plugin plugin : project.getBuild().getPlugins() )
+        LifecycleMappingDelegate delegate;
+        if ( Arrays.binarySearch( DefaultLifecycles.STANDARD_LIFECYCLES, lifecycle.getId() ) >= 0 )
         {
-            for ( PluginExecution execution : plugin.getExecutions() )
-            {
-                // if the phase is specified then I don't have to go fetch the plugin yet and pull it down
-                // to examine the phase it is associated to.
-                if ( execution.getPhase() != null )
-                {
-                    Map<Integer, List<MojoExecution>> phaseBindings = mappings.get( execution.getPhase() );
-                    if ( phaseBindings != null )
-                    {
-                        for ( String goal : execution.getGoals() )
-                        {
-                            MojoExecution mojoExecution = new MojoExecution( plugin, goal, execution.getId() );
-                            mojoExecution.setLifecyclePhase( execution.getPhase() );
-                            addMojoExecution( phaseBindings, mojoExecution, execution.getPriority() );
-                        }
-                    }
-                }
-                // if not then i need to grab the mojo descriptor and look at the phase that is specified
-                else
-                {
-                    for ( String goal : execution.getGoals() )
-                    {
-                        MojoDescriptor mojoDescriptor =
-                            pluginManager.getMojoDescriptor( plugin, goal, project.getRemotePluginRepositories(),
-                                                             session.getRepositorySession() );
-
-                        Map<Integer, List<MojoExecution>> phaseBindings = mappings.get( mojoDescriptor.getPhase() );
-                        if ( phaseBindings != null )
-                        {
-                            MojoExecution mojoExecution = new MojoExecution( mojoDescriptor, execution.getId() );
-                            mojoExecution.setLifecyclePhase( mojoDescriptor.getPhase() );
-                            addMojoExecution( phaseBindings, mojoExecution, execution.getPriority() );
-                        }
-                    }
-                }
-            }
+            delegate = standardDelegate;
         }
-
-        Map<String, List<MojoExecution>> lifecycleMappings = new LinkedHashMap<String, List<MojoExecution>>();
-
-        for ( Map.Entry<String, Map<Integer, List<MojoExecution>>> entry : mappings.entrySet() )
+        else
         {
-            List<MojoExecution> mojoExecutions = new ArrayList<MojoExecution>();
-
-            for ( List<MojoExecution> executions : entry.getValue().values() )
+            delegate = delegates.get( lifecycle.getId() );
+            if ( delegate == null )
             {
-                mojoExecutions.addAll( executions );
+                delegate = standardDelegate;
             }
-
-            lifecycleMappings.put( entry.getKey(), mojoExecutions );
-        }
-
-        return lifecycleMappings;
-    }
-
-    private void addMojoExecution( Map<Integer, List<MojoExecution>> phaseBindings, MojoExecution mojoExecution,
-                                   int priority )
-    {
-        List<MojoExecution> mojoExecutions = phaseBindings.get( priority );
-
-        if ( mojoExecutions == null )
-        {
-            mojoExecutions = new ArrayList<MojoExecution>();
-            phaseBindings.put( priority, mojoExecutions );
         }
 
-        mojoExecutions.add( mojoExecution );
+        return delegate.calculateLifecycleMappings( session, project, lifecycle, lifecyclePhase );
     }
 
     private void populateMojoExecutionConfiguration( MavenProject project, MojoExecution mojoExecution,

http://git-wip-us.apache.org/repos/asf/maven/blob/f8afa711/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleMappingDelegate.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleMappingDelegate.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleMappingDelegate.java
new file mode 100644
index 0000000..3024fe4
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleMappingDelegate.java
@@ -0,0 +1,158 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * 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.
+ */
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.Lifecycle;
+import org.apache.maven.lifecycle.LifecycleMappingDelegate;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginExecution;
+import org.apache.maven.plugin.BuildPluginManager;
+import org.apache.maven.plugin.InvalidPluginDescriptorException;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.plugin.MojoNotFoundException;
+import org.apache.maven.plugin.PluginDescriptorParsingException;
+import org.apache.maven.plugin.PluginNotFoundException;
+import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+@Component( role = LifecycleMappingDelegate.class, hint = DefaultLifecycleMappingDelegate.HINT )
+public class DefaultLifecycleMappingDelegate
+    implements LifecycleMappingDelegate
+{
+    public static final String HINT = "default";
+
+    @Requirement
+    private BuildPluginManager pluginManager;
+
+    public Map<String, List<MojoExecution>> calculateLifecycleMappings( MavenSession session, MavenProject project,
+                                                                        Lifecycle lifecycle, String lifecyclePhase )
+        throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+        MojoNotFoundException, InvalidPluginDescriptorException
+    {
+        /*
+         * Initialize mapping from lifecycle phase to bound mojos. The key set of this map denotes the phases the caller
+         * is interested in, i.e. all phases up to and including the specified phase.
+         */
+
+        Map<String, Map<Integer, List<MojoExecution>>> mappings =
+            new LinkedHashMap<String, Map<Integer, List<MojoExecution>>>();
+
+        for ( String phase : lifecycle.getPhases() )
+        {
+            Map<Integer, List<MojoExecution>> phaseBindings = new TreeMap<Integer, List<MojoExecution>>();
+
+            mappings.put( phase, phaseBindings );
+
+            if ( phase.equals( lifecyclePhase ) )
+            {
+                break;
+            }
+        }
+
+        /*
+         * Grab plugin executions that are bound to the selected lifecycle phases from project. The effective model of
+         * the project already contains the plugin executions induced by the project's packaging type. Remember, all
+         * phases of interest and only those are in the lifecyle mapping, if a phase has no value in the map, we are not
+         * interested in any of the executions bound to it.
+         */
+
+        for ( Plugin plugin : project.getBuild().getPlugins() )
+        {
+            for ( PluginExecution execution : plugin.getExecutions() )
+            {
+                // if the phase is specified then I don't have to go fetch the plugin yet and pull it down
+                // to examine the phase it is associated to.
+                if ( execution.getPhase() != null )
+                {
+                    Map<Integer, List<MojoExecution>> phaseBindings = mappings.get( execution.getPhase() );
+                    if ( phaseBindings != null )
+                    {
+                        for ( String goal : execution.getGoals() )
+                        {
+                            MojoExecution mojoExecution = new MojoExecution( plugin, goal, execution.getId() );
+                            mojoExecution.setLifecyclePhase( execution.getPhase() );
+                            addMojoExecution( phaseBindings, mojoExecution, execution.getPriority() );
+                        }
+                    }
+                }
+                // if not then i need to grab the mojo descriptor and look at the phase that is specified
+                else
+                {
+                    for ( String goal : execution.getGoals() )
+                    {
+                        MojoDescriptor mojoDescriptor =
+                            pluginManager.getMojoDescriptor( plugin, goal, project.getRemotePluginRepositories(),
+                                                             session.getRepositorySession() );
+
+                        Map<Integer, List<MojoExecution>> phaseBindings = mappings.get( mojoDescriptor.getPhase() );
+                        if ( phaseBindings != null )
+                        {
+                            MojoExecution mojoExecution = new MojoExecution( mojoDescriptor, execution.getId() );
+                            mojoExecution.setLifecyclePhase( mojoDescriptor.getPhase() );
+                            addMojoExecution( phaseBindings, mojoExecution, execution.getPriority() );
+                        }
+                    }
+                }
+            }
+        }
+
+        Map<String, List<MojoExecution>> lifecycleMappings = new LinkedHashMap<String, List<MojoExecution>>();
+
+        for ( Map.Entry<String, Map<Integer, List<MojoExecution>>> entry : mappings.entrySet() )
+        {
+            List<MojoExecution> mojoExecutions = new ArrayList<MojoExecution>();
+
+            for ( List<MojoExecution> executions : entry.getValue().values() )
+            {
+                mojoExecutions.addAll( executions );
+            }
+
+            lifecycleMappings.put( entry.getKey(), mojoExecutions );
+        }
+
+        return lifecycleMappings;
+
+    }
+
+    private void addMojoExecution( Map<Integer, List<MojoExecution>> phaseBindings, MojoExecution mojoExecution,
+                                   int priority )
+    {
+        List<MojoExecution> mojoExecutions = phaseBindings.get( priority );
+
+        if ( mojoExecutions == null )
+        {
+            mojoExecutions = new ArrayList<MojoExecution>();
+            phaseBindings.put( priority, mojoExecutions );
+        }
+
+        mojoExecutions.add( mojoExecution );
+    }
+
+}