Index: src/main/java/org/apache/maven/lifecycle/Lifecycle.java =================================================================== --- src/main/java/org/apache/maven/lifecycle/Lifecycle.java (revision 439967) +++ src/main/java/org/apache/maven/lifecycle/Lifecycle.java (working copy) @@ -17,6 +17,7 @@ */ import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -93,6 +94,10 @@ public Map getDefaultPhases() { - return defaultPhases; + if ( defaultPhases == null ) + { + defaultPhases = new HashMap(); + } + return this.defaultPhases; } } Index: src/main/java/org/apache/maven/lifecycle/LifecycleExecutor2.java =================================================================== --- src/main/java/org/apache/maven/lifecycle/LifecycleExecutor2.java (revision 0) +++ src/main/java/org/apache/maven/lifecycle/LifecycleExecutor2.java (revision 0) @@ -0,0 +1,33 @@ +package org.apache.maven.lifecycle; + +/* + * Copyright 2001-2005 The Apache Software Foundation. + * + * Licensed 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 org.apache.maven.BuildFailureException; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.execution.ReactorManager; +import org.apache.maven.monitor.event.EventDispatcher; + +/** + */ +public interface LifecycleExecutor2 extends LifecycleExecutor +{ + String ROLE = LifecycleExecutor2.class.getName(); + + void executeSuperInit( MavenSession session, ReactorManager rm, EventDispatcher dispatcher ) + throws LifecycleExecutionException, BuildFailureException; + +} Property changes on: src/main/java/org/apache/maven/lifecycle/LifecycleExecutor2.java ___________________________________________________________________ Name: svn:executable + * Index: src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java =================================================================== --- src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java (revision 439967) +++ src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java (working copy) @@ -78,8 +78,10 @@ */ public class DefaultLifecycleExecutor extends AbstractLogEnabled - implements LifecycleExecutor + implements LifecycleExecutor2 { + private boolean extensionsFound = false; + // ---------------------------------------------------------------------- // Components // ---------------------------------------------------------------------- @@ -114,9 +116,7 @@ // TODO: This is dangerous, particularly when it's just a collection of loose-leaf projects being built // within the same reactor (using an inclusion pattern to gather them up)... MavenProject rootProject = rm.getTopLevelProject(); - List goals = session.getGoals(); - if ( goals.isEmpty() && rootProject != null ) { String goal = rootProject.getDefaultGoal(); @@ -126,19 +126,36 @@ goals = Collections.singletonList( goal ); } } + executeInternal( goals, session, rm, dispatcher ); + } + + public void executeSuperInit( MavenSession session, ReactorManager rm, EventDispatcher dispatcher ) + throws BuildFailureException, LifecycleExecutionException + { + List goals = goals = Collections.singletonList( "super-init" ); + executeInternal( goals, session, rm, dispatcher ); + } - if ( goals.isEmpty() ) + private void executeInternal( List goals, MavenSession session, ReactorManager rm, EventDispatcher dispatcher ) + throws BuildFailureException, LifecycleExecutionException + { + if ( goals == null || goals.isEmpty() ) { throw new BuildFailureException( "You must specify at least one goal. Try 'install'" ); } + + MavenProject rootProject = rm.getTopLevelProject(); + List taskSegments = segmentTaskListByAggregationNeeds( goals, session, rootProject ); - List taskSegments = segmentTaskListByAggregationNeeds( goals, session, rootProject ); - - // TODO: probably don't want to do all this up front - findExtensions( session ); - + if ( !extensionsFound ) + { + // TODO: probably don't want to do all this up front + findExtensions( session ); + extensionsFound = true; + } + executeTaskSegments( taskSegments, rm, session, rootProject, dispatcher ); - } + } private void findExtensions( MavenSession session ) throws LifecycleExecutionException Index: src/main/java/org/apache/maven/execution/ReactorManager.java =================================================================== --- src/main/java/org/apache/maven/execution/ReactorManager.java (revision 439967) +++ src/main/java/org/apache/maven/execution/ReactorManager.java (working copy) @@ -46,14 +46,14 @@ private String failureBehavior = FAIL_FAST; - private final ProjectSorter sorter; + private ProjectSorter sorter; private Map buildSuccessesByProject = new HashMap(); public ReactorManager( List projects ) throws CycleDetectedException, DuplicateProjectException { - this.sorter = new ProjectSorter( projects ); + sortProjects( projects ); } public Map getPluginContext( PluginDescriptor plugin, MavenProject project ) @@ -189,4 +189,10 @@ { return buildFailuresByProject.size() + buildSuccessesByProject.size() > 1; } + + public void sortProjects( List projects ) + throws CycleDetectedException, DuplicateProjectException + { + sorter = new ProjectSorter( projects ); + } } Index: src/main/java/org/apache/maven/DefaultMaven.java =================================================================== --- src/main/java/org/apache/maven/DefaultMaven.java (revision 439967) +++ src/main/java/org/apache/maven/DefaultMaven.java (working copy) @@ -30,6 +30,9 @@ import org.apache.maven.execution.RuntimeInformation; import org.apache.maven.lifecycle.LifecycleExecutionException; import org.apache.maven.lifecycle.LifecycleExecutor; +import org.apache.maven.lifecycle.LifecycleExecutor2; +import org.apache.maven.model.Plugin; +import org.apache.maven.model.PluginExecution; import org.apache.maven.model.Profile; import org.apache.maven.monitor.event.DefaultEventDispatcher; import org.apache.maven.monitor.event.DefaultEventMonitor; @@ -375,6 +378,41 @@ throw new BuildFailureException( e.getMessage(), e ); } + MavenSession session = createSession( request, rm, dispatcher ); + + session.setUsingPOMsFromFilesystem( foundProjects ); + + if ( lifecycleExecutor instanceof LifecycleExecutor2 && isSuperInitExecutionRequired( rm ) ) + { + getLogger().info( "Executing super-init phase for projects ... " ); + ((LifecycleExecutor2) lifecycleExecutor).executeSuperInit( session, rm, dispatcher ); + if ( rm.hasBuildFailures() ) + { + if ( !ReactorManager.FAIL_NEVER.equals( rm.getFailureBehavior() ) ) + { + return rm; + } + else + { + getLogger().info( " + Ignoring failures" ); + } + } + try + { + rm.sortProjects( rm.getSortedProjects() ); + + } + catch ( CycleDetectedException e ) + { + throw new BuildFailureException( + "The projects in the reactor contain a cyclic reference: " + e.getMessage(), e ); + } + catch ( DuplicateProjectException e ) + { + throw new BuildFailureException( e.getMessage(), e ); + } + } + if ( rm.hasMultipleProjects() ) { getLogger().info( "Reactor build order: " ); @@ -386,14 +424,31 @@ } } - MavenSession session = createSession( request, rm, dispatcher ); - - session.setUsingPOMsFromFilesystem( foundProjects ); - lifecycleExecutor.execute( session, rm, dispatcher ); return rm; } + + private boolean isSuperInitExecutionRequired( ReactorManager rm ) + { + for ( Iterator i = rm.getSortedProjects().iterator(); i.hasNext(); ) + { + MavenProject mavenProject = (MavenProject) i.next(); + for ( Iterator j = mavenProject.getBuildPlugins().iterator(); j.hasNext(); ) + { + Plugin plugin = (Plugin) j.next(); + for ( Iterator k = plugin.getExecutions().iterator(); k.hasNext(); ) + { + PluginExecution pluginExecution = (PluginExecution) k.next(); + if ( "super-init".equals(pluginExecution.getPhase()) ) + { + return true; + } + } + } + } + return false; + } private MavenProject getSuperProject( MavenExecutionRequest request ) throws MavenExecutionException Index: src/main/resources/META-INF/plexus/components.xml =================================================================== --- src/main/resources/META-INF/plexus/components.xml (revision 439967) +++ src/main/resources/META-INF/plexus/components.xml (working copy) @@ -208,6 +208,12 @@ + super-init + + super-init + + + default