[MNG-5359] Declared execution in PluginMgmt gets bound to lifecycle (regression)
Project: http://git-wip-us.apache.org/repos/asf/maven/repo Commit: http://git-wip-us.apache.org/repos/asf/maven/commit/aacac72a Tree: http://git-wip-us.apache.org/repos/asf/maven/tree/aacac72a Diff: http://git-wip-us.apache.org/repos/asf/maven/diff/aacac72a Branch: refs/heads/MNG-5359 Commit: aacac72aa8308c853e5c3987cdcee65968481d23 Parents: 114ef6c Author: Christian Schulte <schu...@apache.org> Authored: Sun Dec 20 19:32:57 2015 +0100 Committer: Christian Schulte <schu...@apache.org> Committed: Wed Mar 8 17:58:04 2017 +0100 ---------------------------------------------------------------------- .../project/EmptyLifecyclePluginAnalyzer.java | 27 ++- .../project/AbstractMavenProjectTestCase.xml | 2 +- .../lifecycle/DefaultLifecycleExecutor.java | 22 +- .../lifecycle/LifeCyclePluginAnalyzer.java | 32 --- .../maven/lifecycle/LifecycleExecutor.java | 20 +- .../LifecycleMappingNotFoundException.java | 45 ++++ .../lifecycle/LifecyclePluginAnalyzer.java | 59 ++++++ .../DefaultLifecyclePluginAnalyzer.java | 207 ++++++++++++++----- .../DefaultLifecycleBindingsInjector.java | 40 ++-- .../lifecycle/EmptyLifecyclePluginAnalyzer.java | 25 ++- .../LifecycleExecutorSubModulesTest.java | 4 +- .../stub/LifeCyclePluginAnalyzerStub.java | 74 ------- .../stub/LifecyclePluginAnalyzerStub.java | 96 +++++++++ .../project/AbstractMavenProjectTestCase.xml | 2 +- .../maven/project/PomConstructionTest.xml | 2 +- 15 files changed, 451 insertions(+), 206 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/maven/blob/aacac72a/maven-compat/src/test/java/org/apache/maven/project/EmptyLifecyclePluginAnalyzer.java ---------------------------------------------------------------------- diff --git a/maven-compat/src/test/java/org/apache/maven/project/EmptyLifecyclePluginAnalyzer.java b/maven-compat/src/test/java/org/apache/maven/project/EmptyLifecyclePluginAnalyzer.java index 672e07b..2e0d7ea 100644 --- a/maven-compat/src/test/java/org/apache/maven/project/EmptyLifecyclePluginAnalyzer.java +++ b/maven-compat/src/test/java/org/apache/maven/project/EmptyLifecyclePluginAnalyzer.java @@ -23,7 +23,9 @@ import java.util.Collections; import java.util.LinkedHashSet; import java.util.Set; -import org.apache.maven.lifecycle.LifeCyclePluginAnalyzer; +import org.apache.maven.lifecycle.LifecyclePluginAnalyzer; +import org.apache.maven.model.Build; +import org.apache.maven.model.Model; import org.apache.maven.model.Plugin; import org.apache.maven.model.PluginExecution; @@ -31,8 +33,9 @@ import org.apache.maven.model.PluginExecution; * @author Benjamin Bentmann */ public class EmptyLifecyclePluginAnalyzer - implements LifeCyclePluginAnalyzer + implements LifecyclePluginAnalyzer { + public Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging ) { Set<Plugin> plugins; @@ -57,6 +60,26 @@ public class EmptyLifecyclePluginAnalyzer return plugins; } + @Override + public Model getLifecycleModel( final Model model ) + { + if ( model == null ) + { + throw new NullPointerException( "model" ); + } + + final Model lifecycleModel = new Model(); + lifecycleModel.setBuild( new Build() ); + lifecycleModel.getBuild().setPluginManagement( model.getBuild() != null + ? model.getBuild().getPluginManagement() + : null ); + + lifecycleModel.getBuild().getPlugins(). + addAll( this.getPluginsBoundByDefaultToAllLifecycles( model.getPackaging() ) ); + + return lifecycleModel; + } + private Plugin newPlugin( String artifactId, String... goals ) { Plugin plugin = new Plugin(); http://git-wip-us.apache.org/repos/asf/maven/blob/aacac72a/maven-compat/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml ---------------------------------------------------------------------- diff --git a/maven-compat/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml b/maven-compat/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml index bcc291e..7e02f5e 100644 --- a/maven-compat/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml +++ b/maven-compat/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml @@ -2,7 +2,7 @@ <plexus> <components> <component> - <role>org.apache.maven.lifecycle.LifeCyclePluginAnalyzer</role> + <role>org.apache.maven.lifecycle.LifecyclePluginAnalyzer</role> <implementation>org.apache.maven.project.EmptyLifecyclePluginAnalyzer</implementation> </component> </components> http://git-wip-us.apache.org/repos/asf/maven/blob/aacac72a/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java ---------------------------------------------------------------------- diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java b/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java index dae1894..0311f35 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java @@ -62,7 +62,7 @@ public class DefaultLifecycleExecutor { @Requirement - private LifeCyclePluginAnalyzer lifeCyclePluginAnalyzer; + private LifecyclePluginAnalyzer lifecyclePluginAnalyzer; @Requirement private DefaultLifecycles defaultLifeCycles; @@ -88,21 +88,15 @@ public class DefaultLifecycleExecutor @Requirement private MojoDescriptorCreator mojoDescriptorCreator; - // These methods deal with construction intact Plugin object that look like they come from a standard - // <plugin/> block in a Maven POM. We have to do some wiggling to pull the sources of information - // together and this really shows the problem of constructing a sensible default configuration but - // it's all encapsulated here so it appears normalized to the POM builder. - - // We are going to take the project packaging and find all plugin in the default lifecycle and create - // fully populated Plugin objects, including executions with goals and default configuration taken - // from the plugin.xml inside a plugin. - // - // TODO This whole method could probably removed by injecting lifeCyclePluginAnalyzer straight into client site. - // TODO But for some reason the whole plexus appcontext refuses to start when I try this. - + /** + * @deprecated As of Maven 3.5, please use + * {@link LifecyclePluginAnalyzer#getLifecycleModel(org.apache.maven.model.Model)}. + */ + @Deprecated public Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging ) + throws LifecycleMappingNotFoundException { - return lifeCyclePluginAnalyzer.getPluginsBoundByDefaultToAllLifecycles( packaging ); + return lifecyclePluginAnalyzer.getPluginsBoundByDefaultToAllLifecycles( packaging ); } // USED BY MAVEN HELP PLUGIN http://git-wip-us.apache.org/repos/asf/maven/blob/aacac72a/maven-core/src/main/java/org/apache/maven/lifecycle/LifeCyclePluginAnalyzer.java ---------------------------------------------------------------------- diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/LifeCyclePluginAnalyzer.java b/maven-core/src/main/java/org/apache/maven/lifecycle/LifeCyclePluginAnalyzer.java deleted file mode 100644 index ed07c1d..0000000 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/LifeCyclePluginAnalyzer.java +++ /dev/null @@ -1,32 +0,0 @@ -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.Set; -import org.apache.maven.model.Plugin; - -/** - * @since 3.0 - * @author Kristian Rosenvold - */ -public interface LifeCyclePluginAnalyzer -{ - Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging ); -} http://git-wip-us.apache.org/repos/asf/maven/blob/aacac72a/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutor.java ---------------------------------------------------------------------- diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutor.java b/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutor.java index 04c602c..e462f8c 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutor.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutor.java @@ -38,7 +38,7 @@ import java.util.Set; /** * A facade that provides lifecycle services to components outside Maven core. * - * @author Jason van Zyl + * @author Jason van Zyl */ public interface LifecycleExecutor { @@ -47,21 +47,13 @@ public interface LifecycleExecutor @Deprecated String ROLE = LifecycleExecutor.class.getName(); - // For a given project packaging find all the plugins that are bound to any registered - // lifecycles. The project builder needs to now what default plugin information needs to be - // merged into POM being built. Once the POM builder has this plugin information, versions can be assigned - // by the POM builder because they will have to be defined in plugin management. Once this is setComplete then it - // can be passed back so that the default configuration information can be populated. - // - // We need to know the specific version so that we can lookup the right version of the plugin descriptor - // which tells us what the default configuration is. - // - /** - * @return The plugins bound to the lifecycles of the specified packaging or {@code null} if the packaging is - * unknown. + * @deprecated As of Maven 3.5, please use + * {@link LifecyclePluginAnalyzer#getLifecycleModel(org.apache.maven.model.Model)}. */ - Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging ); + @Deprecated + Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging ) + throws LifecycleMappingNotFoundException; MavenExecutionPlan calculateExecutionPlan( MavenSession session, String... tasks ) throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, http://git-wip-us.apache.org/repos/asf/maven/blob/aacac72a/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleMappingNotFoundException.java ---------------------------------------------------------------------- diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleMappingNotFoundException.java b/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleMappingNotFoundException.java new file mode 100644 index 0000000..73aaf30 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleMappingNotFoundException.java @@ -0,0 +1,45 @@ +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. + */ + +/** + * Signals a failure to locate a lifecycle mapping. + * + * @author Christian Schulte + * + * @since 3.5 + */ +public final class LifecycleMappingNotFoundException extends Exception +{ + + private String packaging; + + public LifecycleMappingNotFoundException( final String packaging ) + { + super( String.format( "No lifecycle mapping found for packaging '%s'.", packaging ) ); + this.packaging = packaging; + } + + public String getPackaging() + { + return this.packaging; + } + +} http://git-wip-us.apache.org/repos/asf/maven/blob/aacac72a/maven-core/src/main/java/org/apache/maven/lifecycle/LifecyclePluginAnalyzer.java ---------------------------------------------------------------------- diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/LifecyclePluginAnalyzer.java b/maven-core/src/main/java/org/apache/maven/lifecycle/LifecyclePluginAnalyzer.java new file mode 100644 index 0000000..814b5e6 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/LifecyclePluginAnalyzer.java @@ -0,0 +1,59 @@ +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.Set; +import org.apache.maven.model.Model; +import org.apache.maven.model.Plugin; + +/** + * @since 3.0 + * @author Kristian Rosenvold + */ +public interface LifecyclePluginAnalyzer +{ + + /** + * @deprecated As of Maven 3.5, replaced by method {@link #getLifecycleModel(org.apache.maven.model.Model)}. + */ + @Deprecated + Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging ) + throws LifecycleMappingNotFoundException; + + /** + * Gets the lifecycle {@code Model} for a given {@code Model}. + * <p> + * The lifecycle model for a given model is the list of default build plugins plus lifecycle plugin execution + * management. + * </p> + * + * @param model The {@code Model} to get the lifecycle {@code Model} for. + * + * @return The lifecycle {@code Model} for {@code model}. + * + * @throws NullPointerException if {@code model} is {@code null}. + * @throws LifecycleMappingNotFoundException if {@code model} declares an unsupported packaging. + * + * @since 3.5 + */ + Model getLifecycleModel( Model model ) + throws LifecycleMappingNotFoundException; + +} http://git-wip-us.apache.org/repos/asf/maven/blob/aacac72a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecyclePluginAnalyzer.java ---------------------------------------------------------------------- diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecyclePluginAnalyzer.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecyclePluginAnalyzer.java index a72ce8e..b4f981d 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecyclePluginAnalyzer.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecyclePluginAnalyzer.java @@ -19,40 +19,43 @@ package org.apache.maven.lifecycle.internal; * under the License. */ +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; import org.apache.maven.lifecycle.DefaultLifecycles; -import org.apache.maven.lifecycle.LifeCyclePluginAnalyzer; +import org.apache.maven.lifecycle.LifecyclePluginAnalyzer; import org.apache.maven.lifecycle.Lifecycle; +import org.apache.maven.lifecycle.LifecycleMappingNotFoundException; import org.apache.maven.lifecycle.mapping.LifecycleMapping; import org.apache.maven.lifecycle.mapping.LifecycleMojo; import org.apache.maven.lifecycle.mapping.LifecyclePhase; +import org.apache.maven.model.Build; +import org.apache.maven.model.Model; import org.apache.maven.model.Plugin; import org.apache.maven.model.PluginExecution; +import org.apache.maven.model.PluginManagement; import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.util.StringUtils; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - /** * @since 3.0 * @author Benjamin Bentmann * @author Jason van Zyl * @author jdcasey * @author Kristian Rosenvold (extracted class only) - * <p/> - * NOTE: This class is not part of any public api and can be changed or deleted without prior notice. + * <p/> + * NOTE: This class is not part of any public api and can be changed or deleted without prior notice. */ -@Component( role = LifeCyclePluginAnalyzer.class ) +@Component( role = LifecyclePluginAnalyzer.class ) public class DefaultLifecyclePluginAnalyzer - implements LifeCyclePluginAnalyzer + implements LifecyclePluginAnalyzer { @Requirement( role = LifecycleMapping.class ) @@ -68,64 +71,117 @@ public class DefaultLifecyclePluginAnalyzer { } + // ----------------------------------------------------------------------------------------------------------------- + // Comment regarding these methods moved here from LifecycleExecuter: + // ----------------------------------------------------------------------------------------------------------------- + // For a given project packaging find all the plugins that are bound to any registered + // lifecycles. The project builder needs to now what default plugin information needs to be + // merged into POM being built. Once the POM builder has this plugin information, versions can be assigned + // by the POM builder because they will have to be defined in plugin management. Once this is setComplete then it + // can be passed back so that the default configuration information can be populated. + // + // We need to know the specific version so that we can lookup the right version of the plugin descriptor + // which tells us what the default configuration is. + // ----------------------------------------------------------------------------------------------------------------- + // Comment regarding these methods moved here from DefaultLifecycleExecutor: + // ----------------------------------------------------------------------------------------------------------------- // These methods deal with construction intact Plugin object that look like they come from a standard // <plugin/> block in a Maven POM. We have to do some wiggling to pull the sources of information // together and this really shows the problem of constructing a sensible default configuration but // it's all encapsulated here so it appears normalized to the POM builder. - // We are going to take the project packaging and find all plugin in the default lifecycle and create // fully populated Plugin objects, including executions with goals and default configuration taken // from the plugin.xml inside a plugin. - // - + @Override + @Deprecated public Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging ) + throws LifecycleMappingNotFoundException { + if ( packaging == null ) + { + throw new NullPointerException( "packaging" ); + } + + final Model model = new Model(); + model.setPackaging( packaging ); + + final Set<Plugin> plugins = new HashSet<>( this.getLifecycleModel( model ).getBuild().getPlugins() ); + return Collections.unmodifiableSet( plugins ); + } + + @Override + public Model getLifecycleModel( final Model model ) + throws LifecycleMappingNotFoundException + { + if ( model == null ) + { + throw new NullPointerException( "model" ); + } + + final PluginManagement pluginManagement = + model.getBuild() != null && model.getBuild().getPluginManagement() != null + ? model.getBuild().getPluginManagement().clone() + : null; + + final Model lifecycleModel = new Model(); + lifecycleModel.setBuild( new Build() ); + lifecycleModel.getBuild().setPluginManagement( pluginManagement != null + ? pluginManagement.clone() + : new PluginManagement() ); + + for ( final Plugin managedPlugin : lifecycleModel.getBuild().getPluginManagement().getPlugins() ) + { + managedPlugin.getExecutions().clear(); + } + if ( logger.isDebugEnabled() ) { - logger.debug( "Looking up lifecyle mappings for packaging " + packaging + " from " - + Thread.currentThread().getContextClassLoader() ); + logger.debug( "Looking up lifecyle mappings for packaging " + model.getPackaging() + " from " + + Thread.currentThread().getContextClassLoader() ); + } - LifecycleMapping lifecycleMappingForPackaging = lifecycleMappings.get( packaging ); + final LifecycleMapping lifecycleMappingForPackaging = this.lifecycleMappings.get( model.getPackaging() ); if ( lifecycleMappingForPackaging == null ) { - return null; + throw new LifecycleMappingNotFoundException( model.getPackaging() ); } - Map<Plugin, Plugin> plugins = new LinkedHashMap<>(); + final Map<Plugin, Plugin> plugins = new LinkedHashMap<>(); for ( Lifecycle lifecycle : getOrderedLifecycles() ) { - org.apache.maven.lifecycle.mapping.Lifecycle lifecycleConfiguration = + final org.apache.maven.lifecycle.mapping.Lifecycle lifecycleConfiguration = lifecycleMappingForPackaging.getLifecycles().get( lifecycle.getId() ); - Map<String, LifecyclePhase> phaseToGoalMapping = null; - - if ( lifecycleConfiguration != null ) - { - phaseToGoalMapping = lifecycleConfiguration.getLifecyclePhases(); - } - else if ( lifecycle.getDefaultLifecyclePhases() != null ) - { - phaseToGoalMapping = lifecycle.getDefaultLifecyclePhases(); - } + final Map<String, LifecyclePhase> phaseToGoalMapping = + lifecycleConfiguration != null + ? lifecycleConfiguration.getLifecyclePhases() + : lifecycle.getDefaultLifecyclePhases() != null + ? lifecycle.getDefaultLifecyclePhases() + : null; if ( phaseToGoalMapping != null ) { - for ( Map.Entry<String, LifecyclePhase> goalsForLifecyclePhase : phaseToGoalMapping.entrySet() ) + for ( final Map.Entry<String, LifecyclePhase> goalsForLifecyclePhase : phaseToGoalMapping.entrySet() ) { - String phase = goalsForLifecyclePhase.getKey(); - LifecyclePhase goals = goalsForLifecyclePhase.getValue(); + final String phase = goalsForLifecyclePhase.getKey(); + final LifecyclePhase goals = goalsForLifecyclePhase.getValue(); + if ( goals != null ) { - parseLifecyclePhaseDefinitions( plugins, phase, goals ); + parseLifecyclePhaseDefinitions( plugins, phase, goals, lifecycle, lifecycleModel, + pluginManagement ); + } } } } - return plugins.keySet(); + lifecycleModel.getBuild().getPlugins().addAll( plugins.keySet() ); + + return lifecycleModel; } private List<Lifecycle> getOrderedLifecycles() @@ -137,6 +193,7 @@ public class DefaultLifecyclePluginAnalyzer Collections.sort( lifecycles, new Comparator<Lifecycle>() { + @Override public int compare( Lifecycle l1, Lifecycle l2 ) { return l1.getId().compareTo( l2.getId() ); @@ -147,30 +204,32 @@ public class DefaultLifecyclePluginAnalyzer return lifecycles; } - private void parseLifecyclePhaseDefinitions( Map<Plugin, Plugin> plugins, String phase, LifecyclePhase goals ) + private void parseLifecyclePhaseDefinitions( Map<Plugin, Plugin> plugins, String phase, LifecyclePhase goals, + final Lifecycle lifecycle, final Model lifecycleModel, + final PluginManagement pluginManagement ) { List<LifecycleMojo> mojos = goals.getMojos(); + if ( mojos != null ) { - for ( int i = 0; i < mojos.size(); i++ ) { LifecycleMojo mojo = mojos.get( i ); - + GoalSpec gs = parseGoalSpec( mojo.getGoal() ); - + if ( gs == null ) { logger.warn( "Ignored invalid goal specification '" + mojo.getGoal() - + "' from lifecycle mapping for phase " + phase ); + + "' from lifecycle mapping for phase '" + phase + "'" ); continue; } - + Plugin plugin = new Plugin(); plugin.setGroupId( gs.groupId ); plugin.setArtifactId( gs.artifactId ); plugin.setVersion( gs.version ); - + Plugin existing = plugins.get( plugin ); if ( existing != null ) { @@ -184,16 +243,48 @@ public class DefaultLifecyclePluginAnalyzer { plugins.put( plugin, plugin ); } - + PluginExecution execution = new PluginExecution(); execution.setId( getExecutionId( plugin, gs.goal ) ); execution.setPhase( phase ); execution.setPriority( i - mojos.size() ); execution.getGoals().add( gs.goal ); execution.setConfiguration( mojo.getConfiguration() ); - + plugin.setDependencies( mojo.getDependencies() ); plugin.getExecutions().add( execution ); + + if ( pluginManagement != null ) + { + final Plugin managedPlugin = this.getManagedPlugin( pluginManagement, plugin ); + + if ( managedPlugin != null ) + { + final List<PluginExecution> defaultExecutions = + new ArrayList<>( managedPlugin.getExecutions().size() ); + + for ( final PluginExecution pluginExecution : managedPlugin.getExecutions() ) + { + // What if the plugin's default phase (== null) is not from the lifecyle? + if ( pluginExecution.getPhase() == null + || lifecycle.getPhases().contains( pluginExecution.getPhase() ) ) + { + defaultExecutions.add( pluginExecution ); + } + } + + final Plugin defaultManagedPlugin = + this.getManagedPlugin( lifecycleModel.getBuild().getPluginManagement(), + managedPlugin ); + + for ( final PluginExecution pluginExecution : defaultExecutions ) + { + defaultManagedPlugin.addExecution( pluginExecution ); + } + + managedPlugin.getExecutions().removeAll( defaultExecutions ); + } + } } } } @@ -247,6 +338,28 @@ public class DefaultLifecyclePluginAnalyzer return id; } + private Plugin getManagedPlugin( final PluginManagement pluginManagement, final Plugin plugin ) + { + Plugin managedPlugin = null; + final String key = plugin.getKey(); + + if ( pluginManagement != null ) + { + for ( int i = 0, s0 = pluginManagement.getPlugins().size(); i < s0; i++ ) + { + final Plugin current = pluginManagement.getPlugins().get( i ); + + if ( current.getKey().equals( key ) ) + { + managedPlugin = current; + break; + } + } + } + + return managedPlugin; + } + static class GoalSpec { http://git-wip-us.apache.org/repos/asf/maven/blob/aacac72a/maven-core/src/main/java/org/apache/maven/model/plugin/DefaultLifecycleBindingsInjector.java ---------------------------------------------------------------------- diff --git a/maven-core/src/main/java/org/apache/maven/model/plugin/DefaultLifecycleBindingsInjector.java b/maven-core/src/main/java/org/apache/maven/model/plugin/DefaultLifecycleBindingsInjector.java index 1401e30..aa491e7 100644 --- a/maven-core/src/main/java/org/apache/maven/model/plugin/DefaultLifecycleBindingsInjector.java +++ b/maven-core/src/main/java/org/apache/maven/model/plugin/DefaultLifecycleBindingsInjector.java @@ -20,13 +20,12 @@ package org.apache.maven.model.plugin; */ import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; - -import org.apache.maven.lifecycle.LifeCyclePluginAnalyzer; +import org.apache.maven.lifecycle.LifecycleMappingNotFoundException; +import org.apache.maven.lifecycle.LifecyclePluginAnalyzer; import org.apache.maven.model.Build; import org.apache.maven.model.Model; import org.apache.maven.model.Plugin; @@ -34,9 +33,9 @@ import org.apache.maven.model.PluginContainer; import org.apache.maven.model.PluginExecution; import org.apache.maven.model.PluginManagement; import org.apache.maven.model.building.ModelBuildingRequest; -import org.apache.maven.model.building.ModelProblemCollector; import org.apache.maven.model.building.ModelProblem.Severity; import org.apache.maven.model.building.ModelProblem.Version; +import org.apache.maven.model.building.ModelProblemCollector; import org.apache.maven.model.building.ModelProblemCollectorRequest; import org.apache.maven.model.merge.MavenModelMerger; import org.codehaus.plexus.component.annotations.Component; @@ -55,27 +54,34 @@ public class DefaultLifecycleBindingsInjector private LifecycleBindingsMerger merger = new LifecycleBindingsMerger(); @Requirement - private LifeCyclePluginAnalyzer lifecycle; + private LifecyclePluginAnalyzer lifecyclePluginAnalyzer; + @Override public void injectLifecycleBindings( Model model, ModelBuildingRequest request, ModelProblemCollector problems ) { - String packaging = model.getPackaging(); + try + { + final Model lifecycleModel = this.lifecyclePluginAnalyzer.getLifecycleModel( model ); - Collection<Plugin> defaultPlugins = lifecycle.getPluginsBoundByDefaultToAllLifecycles( packaging ); + if ( model.getBuild() == null ) + { + model.setBuild( new Build() ); + } - if ( defaultPlugins == null ) - { - problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ) - .setMessage( "Unknown packaging: " + packaging ) - .setLocation( model.getLocation( "packaging" ) ) ); + final PluginManagement pluginManagement = model.getBuild().getPluginManagement(); + + model.getBuild().setPluginManagement( lifecycleModel.getBuild().getPluginManagement() ); + + merger.merge( model, lifecycleModel ); + + model.getBuild().setPluginManagement( pluginManagement ); } - else if ( !defaultPlugins.isEmpty() ) + catch ( final LifecycleMappingNotFoundException e ) { - Model lifecycleModel = new Model(); - lifecycleModel.setBuild( new Build() ); - lifecycleModel.getBuild().getPlugins().addAll( defaultPlugins ); + problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ) + .setException( e ) + .setLocation( model.getLocation( "packaging" ) ) ); - merger.merge( model, lifecycleModel ); } } http://git-wip-us.apache.org/repos/asf/maven/blob/aacac72a/maven-core/src/test/java/org/apache/maven/lifecycle/EmptyLifecyclePluginAnalyzer.java ---------------------------------------------------------------------- diff --git a/maven-core/src/test/java/org/apache/maven/lifecycle/EmptyLifecyclePluginAnalyzer.java b/maven-core/src/test/java/org/apache/maven/lifecycle/EmptyLifecyclePluginAnalyzer.java index a812c26..21791da 100644 --- a/maven-core/src/test/java/org/apache/maven/lifecycle/EmptyLifecyclePluginAnalyzer.java +++ b/maven-core/src/test/java/org/apache/maven/lifecycle/EmptyLifecyclePluginAnalyzer.java @@ -23,6 +23,8 @@ import java.util.Collections; import java.util.LinkedHashSet; import java.util.Set; +import org.apache.maven.model.Build; +import org.apache.maven.model.Model; import org.apache.maven.model.Plugin; import org.apache.maven.model.PluginExecution; @@ -30,8 +32,9 @@ import org.apache.maven.model.PluginExecution; * @author Benjamin Bentmann */ public class EmptyLifecyclePluginAnalyzer - implements LifeCyclePluginAnalyzer + implements LifecyclePluginAnalyzer { + public Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging ) { Set<Plugin> plugins; @@ -56,6 +59,26 @@ public class EmptyLifecyclePluginAnalyzer return plugins; } + @Override + public Model getLifecycleModel( final Model model ) + { + if ( model == null ) + { + throw new NullPointerException( "model" ); + } + + final Model lifecycleModel = new Model(); + lifecycleModel.setBuild( new Build() ); + lifecycleModel.getBuild().setPluginManagement( model.getBuild() != null + ? model.getBuild().getPluginManagement() + : null ); + + lifecycleModel.getBuild().getPlugins(). + addAll( this.getPluginsBoundByDefaultToAllLifecycles( model.getPackaging() ) ); + + return lifecycleModel; + } + private Plugin newPlugin( String artifactId, String... goals ) { Plugin plugin = new Plugin(); http://git-wip-us.apache.org/repos/asf/maven/blob/aacac72a/maven-core/src/test/java/org/apache/maven/lifecycle/LifecycleExecutorSubModulesTest.java ---------------------------------------------------------------------- diff --git a/maven-core/src/test/java/org/apache/maven/lifecycle/LifecycleExecutorSubModulesTest.java b/maven-core/src/test/java/org/apache/maven/lifecycle/LifecycleExecutorSubModulesTest.java index df585fb..3bd6e5c 100644 --- a/maven-core/src/test/java/org/apache/maven/lifecycle/LifecycleExecutorSubModulesTest.java +++ b/maven-core/src/test/java/org/apache/maven/lifecycle/LifecycleExecutorSubModulesTest.java @@ -50,7 +50,7 @@ public class LifecycleExecutorSubModulesTest private LifecycleExecutionPlanCalculator lifeCycleExecutionPlanCalculator; @Requirement - private LifeCyclePluginAnalyzer lifeCyclePluginAnalyzer; + private LifecyclePluginAnalyzer lifeCyclePluginAnalyzer; @Requirement private LifecycleTaskSegmentCalculator lifeCycleTaskSegmentCalculator; @@ -65,7 +65,7 @@ public class LifecycleExecutorSubModulesTest lifeCycleBuilder = lookup( LifecycleModuleBuilder.class ); lifeCycleDependencyResolver = lookup( LifecycleDependencyResolver.class ); lifeCycleExecutionPlanCalculator = lookup( LifecycleExecutionPlanCalculator.class ); - lifeCyclePluginAnalyzer = lookup( LifeCyclePluginAnalyzer.class ); + lifeCyclePluginAnalyzer = lookup( LifecyclePluginAnalyzer.class ); lifeCycleTaskSegmentCalculator = lookup( LifecycleTaskSegmentCalculator.class ); lookup( ExceptionHandler.class ); } http://git-wip-us.apache.org/repos/asf/maven/blob/aacac72a/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LifeCyclePluginAnalyzerStub.java ---------------------------------------------------------------------- diff --git a/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LifeCyclePluginAnalyzerStub.java b/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LifeCyclePluginAnalyzerStub.java deleted file mode 100644 index b067e24..0000000 --- a/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LifeCyclePluginAnalyzerStub.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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.lifecycle.internal.stub; - -import org.apache.maven.lifecycle.LifeCyclePluginAnalyzer; -import org.apache.maven.model.Plugin; -import org.apache.maven.model.PluginExecution; - -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.Set; - -/** - * @author Kristian Rosenvold - */ -public class LifeCyclePluginAnalyzerStub - implements LifeCyclePluginAnalyzer -{ - public Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging ) - { - Set<Plugin> plugins; - - // NOTE: The upper-case packaging name is intentional, that's a special hinting mode used for certain tests - if ( "JAR".equals( packaging ) ) - { - plugins = new LinkedHashSet<>(); - - plugins.add( newPlugin( "maven-compiler-plugin", "compile", "testCompile" ) ); - plugins.add( newPlugin( "maven-resources-plugin", "resources", "testResources" ) ); - plugins.add( newPlugin( "maven-surefire-plugin", "test" ) ); - plugins.add( newPlugin( "maven-jar-plugin", "jar" ) ); - plugins.add( newPlugin( "maven-install-plugin", "install" ) ); - plugins.add( newPlugin( "maven-deploy-plugin", "deploy" ) ); - } - else - { - plugins = Collections.emptySet(); - } - - return plugins; - } - - private Plugin newPlugin( String artifactId, String... goals ) - { - Plugin plugin = new Plugin(); - - plugin.setGroupId( "org.apache.maven.plugins" ); - plugin.setArtifactId( artifactId ); - - for ( String goal : goals ) - { - PluginExecution pluginExecution = new PluginExecution(); - pluginExecution.setId( "default-" + goal ); - pluginExecution.addGoal( goal ); - plugin.addExecution( pluginExecution ); - } - - return plugin; - } - -} http://git-wip-us.apache.org/repos/asf/maven/blob/aacac72a/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LifecyclePluginAnalyzerStub.java ---------------------------------------------------------------------- diff --git a/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LifecyclePluginAnalyzerStub.java b/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LifecyclePluginAnalyzerStub.java new file mode 100644 index 0000000..5a1d9db --- /dev/null +++ b/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LifecyclePluginAnalyzerStub.java @@ -0,0 +1,96 @@ +/* + * 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.lifecycle.internal.stub; + +import org.apache.maven.lifecycle.LifecyclePluginAnalyzer; +import org.apache.maven.model.Model; +import org.apache.maven.model.Plugin; +import org.apache.maven.model.PluginExecution; + +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Set; +import org.apache.maven.model.Build; + +/** + * @author Kristian Rosenvold + */ +public class LifecyclePluginAnalyzerStub + implements LifecyclePluginAnalyzer +{ + + public Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging ) + { + Set<Plugin> plugins; + + // NOTE: The upper-case packaging name is intentional, that's a special hinting mode used for certain tests + if ( "JAR".equals( packaging ) ) + { + plugins = new LinkedHashSet<>(); + + plugins.add( newPlugin( "maven-compiler-plugin", "compile", "testCompile" ) ); + plugins.add( newPlugin( "maven-resources-plugin", "resources", "testResources" ) ); + plugins.add( newPlugin( "maven-surefire-plugin", "test" ) ); + plugins.add( newPlugin( "maven-jar-plugin", "jar" ) ); + plugins.add( newPlugin( "maven-install-plugin", "install" ) ); + plugins.add( newPlugin( "maven-deploy-plugin", "deploy" ) ); + } + else + { + plugins = Collections.emptySet(); + } + + return plugins; + } + + @Override + public Model getLifecycleModel( final Model model ) + { + if ( model == null ) + { + throw new NullPointerException( "model" ); + } + + final Model lifecycleModel = new Model(); + lifecycleModel.setBuild( new Build() ); + lifecycleModel.getBuild().setPluginManagement( model.getBuild() != null + ? model.getBuild().getPluginManagement() + : null ); + + lifecycleModel.getBuild().getPlugins(). + addAll( this.getPluginsBoundByDefaultToAllLifecycles( model.getPackaging() ) ); + + return lifecycleModel; + } + + private Plugin newPlugin( String artifactId, String... goals ) + { + Plugin plugin = new Plugin(); + + plugin.setGroupId( "org.apache.maven.plugins" ); + plugin.setArtifactId( artifactId ); + + for ( String goal : goals ) + { + PluginExecution pluginExecution = new PluginExecution(); + pluginExecution.setId( "default-" + goal ); + pluginExecution.addGoal( goal ); + plugin.addExecution( pluginExecution ); + } + + return plugin; + } + +} http://git-wip-us.apache.org/repos/asf/maven/blob/aacac72a/maven-core/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml ---------------------------------------------------------------------- diff --git a/maven-core/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml b/maven-core/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml index e052489..d48de04 100644 --- a/maven-core/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml +++ b/maven-core/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml @@ -2,7 +2,7 @@ <plexus> <components> <component> - <role>org.apache.maven.lifecycle.LifeCyclePluginAnalyzer</role> + <role>org.apache.maven.lifecycle.LifecyclePluginAnalyzer</role> <implementation>org.apache.maven.lifecycle.EmptyLifecyclePluginAnalyzer</implementation> </component> </components> http://git-wip-us.apache.org/repos/asf/maven/blob/aacac72a/maven-core/src/test/resources/org/apache/maven/project/PomConstructionTest.xml ---------------------------------------------------------------------- diff --git a/maven-core/src/test/resources/org/apache/maven/project/PomConstructionTest.xml b/maven-core/src/test/resources/org/apache/maven/project/PomConstructionTest.xml index e3c3ab3..40b5f93 100644 --- a/maven-core/src/test/resources/org/apache/maven/project/PomConstructionTest.xml +++ b/maven-core/src/test/resources/org/apache/maven/project/PomConstructionTest.xml @@ -2,7 +2,7 @@ <plexus> <components> <component> - <role>org.apache.maven.lifecycle.LifeCyclePluginAnalyzer</role> + <role>org.apache.maven.lifecycle.LifecyclePluginAnalyzer</role> <implementation>org.apache.maven.lifecycle.EmptyLifecyclePluginAnalyzer</implementation> </component> <component>