From 2b8143ef42d68d029b50b52b9ae35b0f32903da5 Mon Sep 17 00:00:00 2001 From: John Dennis Casey Date: Fri, 29 Jul 2005 03:47:07 +0000 Subject: [PATCH] Resolving: MNG-250 git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@226334 13f79535-47bb-0310-9956-ffa450edef68 --- .../java/org/apache/maven/DefaultMaven.java | 155 +++++------ .../lifecycle/DefaultLifecycleExecutor.java | 251 +++++++++++++++++- .../maven/lifecycle/LifecycleExecutor.java | 5 +- .../maven/plugin/DefaultPluginManager.java | 2 +- .../resources/META-INF/plexus/components.xml | 3 - 5 files changed, 311 insertions(+), 105 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/DefaultMaven.java b/maven-core/src/main/java/org/apache/maven/DefaultMaven.java index ae3be10fd2..515e13e0bd 100644 --- a/maven-core/src/main/java/org/apache/maven/DefaultMaven.java +++ b/maven-core/src/main/java/org/apache/maven/DefaultMaven.java @@ -125,11 +125,14 @@ public class DefaultMaven } EventDispatcher dispatcher = request.getEventDispatcher(); + String event = MavenEvents.REACTOR_EXECUTION; dispatcher.dispatchStart( event, request.getBaseDirectory() ); List projects; + + MavenProject topLevelProject; try { @@ -137,8 +140,14 @@ public class DefaultMaven projects = collectProjects( files, request.getLocalRepository(), request.isRecursive(), request.getSettings() ); - - projects = ProjectSorter.getSortedProjects( projects ); + + // the reasoning here is that the list is still unsorted according to dependency, so the first project + // SHOULD BE the top-level, or the one we want to start with if we're doing an aggregated build. + + // TODO: !![jc; 28-jul-2005] check this; if we're using '-r' and there are aggregator tasks, this will result in weirdness. + topLevelProject = (MavenProject) projects.get( 0 ); + + projects = ProjectSorter.getSortedProjects(projects); if ( projects.isEmpty() ) { @@ -152,10 +161,6 @@ public class DefaultMaven { throw new ReactorException( "Error processing projects for the reactor: ", e ); } - catch ( CycleDetectedException e ) - { - throw new ReactorException( "Error processing projects for the reactor: ", e ); - } catch ( ArtifactResolutionException e ) { dispatcher.dispatchError( event, request.getBaseDirectory(), e ); @@ -180,38 +185,73 @@ public class DefaultMaven return response; } + catch ( CycleDetectedException e ) + { + dispatcher.dispatchError( event, request.getBaseDirectory(), e ); + + MavenExecutionResponse response = new MavenExecutionResponse(); + response.setStart( new Date() ); + response.setFinish( new Date() ); + response.setException( e ); + logFailure( response, e, null ); + + return response; + } try { MavenSession session = createSession( request, projects ); - List goals = request.getGoals(); - - for ( Iterator iterator = projects.iterator(); iterator.hasNext(); ) + try { - MavenProject project = (MavenProject) iterator.next(); - - line(); - - getLogger().info( "Building " + project.getName() ); - - line(); - - try + MavenExecutionResponse response = lifecycleExecutor.execute( session, topLevelProject, dispatcher ); + + // TODO: is this perhaps more appropriate in the CLI? + if ( response.isExecutionFailure() ) { - MavenExecutionResponse response = processProject( session, goals, project, dispatcher ); - if ( response.isExecutionFailure() ) + dispatcher.dispatchError( event, request.getBaseDirectory(), response.getException() ); + + // TODO: yuck! Revisit when cleaning up the exception handling from the top down + Throwable exception = response.getException(); + + if ( exception instanceof MojoExecutionException ) { - dispatcher.dispatchError( event, request.getBaseDirectory(), response.getException() ); - - return response; + if ( exception.getCause() == null ) + { + MojoExecutionException e = (MojoExecutionException) exception; + + logFailure( response, e, e.getLongMessage() ); + } + else + { + // TODO: throw exceptions like this, so "failures" are just that + logError( response ); + } } + else if ( exception instanceof ArtifactResolutionException ) + { + logFailure( response, exception, null ); + } + else + { + // TODO: this should be a "FATAL" exception, reported to the + // developers - however currently a LOT of + // "user" errors fall through the cracks (like invalid POMs, as + // one example) + logError( response ); + } + + return response; } - catch ( LifecycleExecutionException e ) + else { - throw new ReactorException( "Error executing project within the reactor", e ); + logSuccess( response ); } } + catch ( LifecycleExecutionException e ) + { + throw new ReactorException( "Error executing project within the reactor", e ); + } dispatcher.dispatchEnd( event, request.getBaseDirectory() ); @@ -277,70 +317,6 @@ public class DefaultMaven return projects; } - private MavenExecutionResponse processProject( MavenSession session, List goals, MavenProject project, - EventDispatcher dispatcher ) - throws LifecycleExecutionException - { - // !! This is ripe for refactoring to an aspect. - // Event monitoring. - String event = MavenEvents.PROJECT_EXECUTION; - - dispatcher.dispatchStart( event, project.getId() ); - - MavenExecutionResponse response; - try - { - // Actual meat of the code. - response = lifecycleExecutor.execute( goals, session, project ); - - dispatcher.dispatchEnd( event, project.getId() ); - } - catch ( LifecycleExecutionException e ) - { - dispatcher.dispatchError( event, project.getId(), e ); - throw e; - } - // End event monitoring. - - // TODO: is this perhaps more appropriate in the CLI? - if ( response.isExecutionFailure() ) - { - // TODO: yuck! Revisit when cleaning up the exception handling from the top down - Throwable exception = response.getException(); - - if ( exception instanceof MojoExecutionException ) - { - if ( exception.getCause() == null ) - { - MojoExecutionException e = (MojoExecutionException) exception; - logFailure( response, e, e.getLongMessage() ); - } - else - { - // TODO: throw exceptions like this, so "failures" are just that - logError( response ); - } - } - else if ( exception instanceof ArtifactResolutionException ) - { - logFailure( response, exception, null ); - } - else - { - // TODO: this should be a "FATAL" exception, reported to the - // developers - however currently a LOT of - // "user" errors fall through the cracks (like invalid POMs, as - // one example) - logError( response ); - } - } - else - { - logSuccess( response ); - } - return response; - } - public MavenProject getProject( File pom, ArtifactRepository localRepository, Settings settings ) throws ProjectBuildingException, ArtifactResolutionException { @@ -691,6 +667,7 @@ public class DefaultMaven files = Collections.singletonList( projectFile ); } } + return files; } 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 6eb5838594..a21cad716b 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 @@ -30,6 +30,8 @@ import org.apache.maven.model.Goal; import org.apache.maven.model.Plugin; import org.apache.maven.model.PluginExecution; import org.apache.maven.model.PluginManagement; +import org.apache.maven.monitor.event.EventDispatcher; +import org.apache.maven.monitor.event.MavenEvents; import org.apache.maven.plugin.MojoExecution; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.PluginManager; @@ -40,7 +42,6 @@ import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.apache.maven.plugin.lifecycle.Execution; import org.apache.maven.plugin.lifecycle.Lifecycle; import org.apache.maven.plugin.lifecycle.Phase; -import org.apache.maven.plugin.mapping.MavenPluginMappingBuilder; import org.apache.maven.plugin.version.PluginVersionResolutionException; import org.apache.maven.project.MavenProject; import org.apache.maven.project.injection.ModelDefaultsInjector; @@ -77,8 +78,6 @@ public class DefaultLifecycleExecutor private ModelDefaultsInjector modelDefaultsInjector; - private MavenPluginMappingBuilder pluginMappingBuilder; - private PluginManager pluginManager; private ExtensionManager extensionManager; @@ -101,9 +100,11 @@ public class DefaultLifecycleExecutor * @param session * @param project */ - public MavenExecutionResponse execute( List tasks, MavenSession session, MavenProject project ) + public MavenExecutionResponse execute( MavenSession session, MavenProject project, EventDispatcher dispatcher ) throws LifecycleExecutionException { + List taskSegments = segmentTaskListByAggregationNeeds( session.getGoals(), session, project ); + MavenExecutionResponse response = new MavenExecutionResponse(); response.setStart( new Date() ); @@ -119,11 +120,7 @@ public class DefaultLifecycleExecutor Map handlers = findArtifactTypeHandlers( project, session.getSettings(), session.getLocalRepository() ); artifactHandlerManager.addHandlers( handlers ); - for ( Iterator i = tasks.iterator(); i.hasNext(); ) - { - String task = (String) i.next(); - executeGoal( task, session, project ); - } + executeTaskSegments( taskSegments, session, project, dispatcher ); } catch ( MojoExecutionException e ) { @@ -157,6 +154,178 @@ public class DefaultLifecycleExecutor return response; } + private void executeTaskSegments( List taskSegments, MavenSession session, MavenProject project, + EventDispatcher dispatcher ) + throws PluginNotFoundException, MojoExecutionException, ArtifactResolutionException, + LifecycleExecutionException + { + for ( Iterator it = taskSegments.iterator(); it.hasNext(); ) + { + TaskSegment segment = (TaskSegment) it.next(); + + if ( segment.aggregate() ) + { + line(); + + getLogger().info( "Building " + project.getName() ); + + getLogger().info( " " + segment ); + + line(); + + // !! This is ripe for refactoring to an aspect. + // Event monitoring. + String event = MavenEvents.PROJECT_EXECUTION; + + dispatcher.dispatchStart( event, project.getId() + " ( " + segment + " )" ); + + try + { + // only call once, with the top-level project (assumed to be provided as a parameter)... + for ( Iterator goalIterator = segment.getTasks().iterator(); goalIterator.hasNext(); ) + { + String task = (String) goalIterator.next(); + + executeGoal( task, session, project ); + } + + dispatcher.dispatchEnd( event, project.getId() + " ( " + segment + " )" ); + } + catch ( LifecycleExecutionException e ) + { + dispatcher.dispatchError( event, project.getId() + " ( " + segment + " )", e ); + + throw e; + } + } + else + { + List sortedProjects = session.getSortedProjects(); + + // iterate over projects, and execute on each... + for ( Iterator projectIterator = sortedProjects.iterator(); projectIterator.hasNext(); ) + { + MavenProject currentProject = (MavenProject) projectIterator.next(); + + line(); + + getLogger().info( "Building " + currentProject.getName() ); + + getLogger().info( " " + segment ); + + line(); + + // !! This is ripe for refactoring to an aspect. + // Event monitoring. + String event = MavenEvents.PROJECT_EXECUTION; + + dispatcher.dispatchStart( event, currentProject.getId() + " ( " + segment + " )" ); + + try + { + for ( Iterator goalIterator = segment.getTasks().iterator(); goalIterator.hasNext(); ) + { + String task = (String) goalIterator.next(); + + executeGoal( task, session, currentProject ); + } + + dispatcher.dispatchEnd( event, currentProject.getId() + " ( " + segment + " )" ); + } + catch ( LifecycleExecutionException e ) + { + dispatcher.dispatchError( event, currentProject.getId() + " ( " + segment + " )", e ); + + throw e; + } + } + } + } + } + + private List segmentTaskListByAggregationNeeds( List tasks, MavenSession session, MavenProject project ) + throws LifecycleExecutionException + { + List segments = new ArrayList(); + + TaskSegment currentSegment = null; + for ( Iterator it = tasks.iterator(); it.hasNext(); ) + { + String task = (String) it.next(); + + // if it's a phase, then we don't need to check whether it's an aggregator. + // simply add it to the current task partition. + if ( phases.contains( task ) ) + { + if ( currentSegment != null && currentSegment.aggregate() ) + { + segments.add( currentSegment ); + currentSegment = null; + } + + if ( currentSegment == null ) + { + currentSegment = new TaskSegment(); + } + + currentSegment.add( task ); + } + else + { + MojoDescriptor mojo = null; + try + { + mojo = getMojoDescriptor( task, session, project ); + } + catch ( LifecycleExecutionException e ) + { + getLogger().info( "Cannot find mojo descriptor for: \'" + task + "\' - Treating as non-aggregator." ); + getLogger().debug( "", e ); + } + catch ( ArtifactResolutionException e ) + { + getLogger().info( "Cannot find mojo descriptor for: \'" + task + "\' - Treating as non-aggregator." ); + getLogger().debug( "", e ); + } + + if ( mojo != null && mojo.isAggregator() ) + { + if ( currentSegment != null && !currentSegment.aggregate() ) + { + segments.add( currentSegment ); + currentSegment = null; + } + + if ( currentSegment == null ) + { + currentSegment = new TaskSegment( true ); + } + + currentSegment.add( task ); + } + else + { + if ( currentSegment != null && currentSegment.aggregate() ) + { + segments.add( currentSegment ); + currentSegment = null; + } + + if ( currentSegment == null ) + { + currentSegment = new TaskSegment(); + } + + currentSegment.add( task ); + } + } + } + + segments.add( currentSegment ); + + return segments; + } + private void executeGoal( String task, MavenSession session, MavenProject project ) throws LifecycleExecutionException, PluginNotFoundException, MojoExecutionException, ArtifactResolutionException { @@ -718,4 +887,68 @@ public class DefaultLifecycleExecutor project.addPlugin( plugin ); } } + + protected void line() + { + getLogger().info( "----------------------------------------------------------------------------" ); + } + + private static class TaskSegment + { + private boolean aggregate = false; + private List tasks = new ArrayList(); + + TaskSegment() + { + + } + + TaskSegment( boolean aggregate ) + { + this.aggregate = aggregate; + } + + public String toString() + { + StringBuffer message = new StringBuffer(); + + message.append( " task-segment: [" ); + + for ( Iterator it = tasks.iterator(); it.hasNext(); ) + { + String task = (String) it.next(); + + message.append( task ); + + if ( it.hasNext() ) + { + message.append( ", "); + } + } + + message.append( "]" ); + + if ( aggregate ) + { + message.append( " (aggregator-style)" ); + } + + return message.toString(); + } + + boolean aggregate() + { + return aggregate; + } + + void add( String task ) + { + tasks.add( task ); + } + + List getTasks() + { + return tasks; + } + } } 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 7c21d3750f..2d74c01f11 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 @@ -18,10 +18,9 @@ package org.apache.maven.lifecycle; import org.apache.maven.execution.MavenExecutionResponse; import org.apache.maven.execution.MavenSession; +import org.apache.maven.monitor.event.EventDispatcher; import org.apache.maven.project.MavenProject; -import java.util.List; - /** * @author Jason van Zyl * @version $Id$ @@ -30,7 +29,7 @@ public interface LifecycleExecutor { String ROLE = LifecycleExecutor.class.getName(); - MavenExecutionResponse execute( List tasks, MavenSession session, MavenProject project ) + MavenExecutionResponse execute( MavenSession session, MavenProject project, EventDispatcher dispatcher ) throws LifecycleExecutionException; } diff --git a/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java b/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java index 96cf7ab216..051da2a8c2 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java @@ -276,7 +276,7 @@ public class DefaultPluginManager throws ArtifactResolutionException, PlexusContainerException { artifactResolver.resolve( pluginArtifact, project.getPluginArtifactRepositories(), localRepository ); - + PlexusContainer child = container.createChildContainer( plugin.getKey(), Collections.singletonList( pluginArtifact.getFile() ), Collections.EMPTY_MAP, diff --git a/maven-core/src/main/resources/META-INF/plexus/components.xml b/maven-core/src/main/resources/META-INF/plexus/components.xml index 05dd6ed6c0..c95ff13b52 100644 --- a/maven-core/src/main/resources/META-INF/plexus/components.xml +++ b/maven-core/src/main/resources/META-INF/plexus/components.xml @@ -136,9 +136,6 @@ org.apache.maven.project.injection.ModelDefaultsInjector - - org.apache.maven.plugin.mapping.MavenPluginMappingBuilder - org.apache.maven.artifact.handler.manager.ArtifactHandlerManager