[MNG-4633] Reactor artifact resolution in weave mode

Resolves artifacts from within reactor build.
No longer requires artifacts to be present in local repository before building weave mode ;)

git-svn-id: https://svn.apache.org/repos/asf/maven/maven-3/trunk@935334 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Kristian Rosenvold 2010-04-18 11:36:37 +00:00
parent e3c7c2633d
commit 69c68d06c5
12 changed files with 377 additions and 213 deletions

View File

@ -63,18 +63,31 @@ public class DefaultProjectDependenciesResolver
Collection<String> scopesToResolve, MavenSession session ) Collection<String> scopesToResolve, MavenSession session )
throws ArtifactResolutionException, ArtifactNotFoundException throws ArtifactResolutionException, ArtifactNotFoundException
{ {
return resolve( Collections.singleton( project ), scopesToCollect, scopesToResolve, session ); Set<MavenProject> mavenProjects = Collections.singleton( project );
return resolveImpl( mavenProjects, scopesToCollect, scopesToResolve, session,
getIgnorableArtifacts( mavenProjects ) );
} }
public Set<Artifact> resolve( Collection<? extends MavenProject> projects, Collection<String> scopesToResolve, public Set<Artifact> resolve( Collection<? extends MavenProject> projects, Collection<String> scopesToResolve,
MavenSession session ) MavenSession session )
throws ArtifactResolutionException, ArtifactNotFoundException throws ArtifactResolutionException, ArtifactNotFoundException
{ {
return resolve( projects, null, scopesToResolve, session ); return resolveImpl( projects, null, scopesToResolve, session, getIgnorableArtifacts( projects ) );
} }
public Set<Artifact> resolve( Collection<? extends MavenProject> projects, Collection<String> scopesToCollect, public Set<Artifact> resolve( MavenProject project, Collection<String> scopesToCollect,
Collection<String> scopesToResolve, MavenSession session ) Collection<String> scopesToResolve, MavenSession session,
Set<Artifact> ignoreableArtifacts )
throws ArtifactResolutionException, ArtifactNotFoundException
{
return resolveImpl( Collections.singleton( project ), scopesToCollect, scopesToResolve, session,
getIgnorableArtifacts( ignoreableArtifacts ) );
}
private Set<Artifact> resolveImpl( Collection<? extends MavenProject> projects, Collection<String> scopesToCollect,
Collection<String> scopesToResolve, MavenSession session,
Set<String> projectIds )
throws ArtifactResolutionException, ArtifactNotFoundException throws ArtifactResolutionException, ArtifactNotFoundException
{ {
Set<Artifact> resolved = new LinkedHashSet<Artifact>(); Set<Artifact> resolved = new LinkedHashSet<Artifact>();
@ -84,8 +97,8 @@ public class DefaultProjectDependenciesResolver
return resolved; return resolved;
} }
if ( ( scopesToCollect == null || scopesToCollect.isEmpty() ) if ( ( scopesToCollect == null || scopesToCollect.isEmpty() ) &&
&& ( scopesToResolve == null || scopesToResolve.isEmpty() ) ) ( scopesToResolve == null || scopesToResolve.isEmpty() ) )
{ {
return resolved; return resolved;
} }
@ -126,22 +139,16 @@ public class DefaultProjectDependenciesResolver
CumulativeScopeArtifactFilter collectionScopeFilter = new CumulativeScopeArtifactFilter( scopesToCollect ); CumulativeScopeArtifactFilter collectionScopeFilter = new CumulativeScopeArtifactFilter( scopesToCollect );
collectionScopeFilter = new CumulativeScopeArtifactFilter( collectionScopeFilter, resolutionScopeFilter ); collectionScopeFilter = new CumulativeScopeArtifactFilter( collectionScopeFilter, resolutionScopeFilter );
ArtifactResolutionRequest request = new ArtifactResolutionRequest() ArtifactResolutionRequest request =
.setResolveRoot( false ) new ArtifactResolutionRequest().setResolveRoot( false ).setResolveTransitively( true ).setCollectionFilter(
.setResolveTransitively( true ) collectionScopeFilter ).setResolutionFilter( resolutionScopeFilter ).setLocalRepository(
.setCollectionFilter( collectionScopeFilter ) session.getLocalRepository() ).setOffline( session.isOffline() ).setForceUpdate(
.setResolutionFilter( resolutionScopeFilter ) session.getRequest().isUpdateSnapshots() ).setCache( session.getRepositoryCache() );
.setLocalRepository( session.getLocalRepository() )
.setOffline( session.isOffline() )
.setForceUpdate( session.getRequest().isUpdateSnapshots() )
.setCache( session.getRepositoryCache() );
request.setTransferListener( session.getRequest().getTransferListener() ); request.setTransferListener( session.getRequest().getTransferListener() );
request.setServers( session.getRequest().getServers() ); request.setServers( session.getRequest().getServers() );
request.setMirrors( session.getRequest().getMirrors() ); request.setMirrors( session.getRequest().getMirrors() );
request.setProxies( session.getRequest().getProxies() ); request.setProxies( session.getRequest().getProxies() );
Set<String> projectIds = null;
for ( MavenProject project : projects ) for ( MavenProject project : projects )
{ {
request.setArtifact( new ProjectArtifact( project ) ); request.setArtifact( new ProjectArtifact( project ) );
@ -157,16 +164,6 @@ public class DefaultProjectDependenciesResolver
} }
catch ( MultipleArtifactsNotFoundException e ) catch ( MultipleArtifactsNotFoundException e )
{ {
if ( projectIds == null )
{
projectIds = new HashSet<String>( projects.size() * 2 );
for ( MavenProject p : projects )
{
String key = ArtifactUtils.key( p.getGroupId(), p.getArtifactId(), p.getVersion() );
projectIds.add( key );
}
}
Collection<Artifact> missing = new HashSet<Artifact>( e.getMissingArtifacts() ); Collection<Artifact> missing = new HashSet<Artifact>( e.getMissingArtifacts() );
@ -191,4 +188,29 @@ public class DefaultProjectDependenciesResolver
return resolved; return resolved;
} }
private Set<String> getIgnorableArtifacts( Collection<? extends MavenProject> projects )
{
Set<String> projectIds = new HashSet<String>( projects.size() * 2 );
for ( MavenProject p : projects )
{
String key = ArtifactUtils.key( p.getGroupId(), p.getArtifactId(), p.getVersion() );
projectIds.add( key );
}
return projectIds;
}
private Set<String> getIgnorableArtifacts( Iterable<Artifact> artifactIterable )
{
Set<String> projectIds = new HashSet<String>();
for ( Artifact artifact : artifactIterable )
{
String key = ArtifactUtils.key( artifact );
projectIds.add( key );
}
return projectIds;
}
} }

View File

@ -55,6 +55,22 @@ public interface ProjectDependenciesResolver
Collection<String> scopesToResolve, MavenSession session ) Collection<String> scopesToResolve, MavenSession session )
throws ArtifactResolutionException, ArtifactNotFoundException; throws ArtifactResolutionException, ArtifactNotFoundException;
/**
* Resolves the transitive dependencies of the specified project.
*
* @param project The project whose dependencies should be resolved, must not be {@code null}.
* @param scopesToCollect The dependency scopes that should be collected, may be {@code null}.
* @param scopesToResolve The dependency scopes that should be collected and also resolved, may be {@code null}.
* @param session The current build session, must not be {@code null}.
* @param ignoreableArtifacts Artifacts that need not be resolved
* @return The transitive dependencies of the specified project that match the requested scopes, never {@code null}.
*/
public Set<Artifact> resolve( MavenProject project, Collection<String> scopesToCollect,
Collection<String> scopesToResolve, MavenSession session,
Set<Artifact> ignoreableArtifacts )
throws ArtifactResolutionException, ArtifactNotFoundException;
/** /**
* Resolves the transitive dependencies of the specified projects. Note that dependencies which can't be resolved * Resolves the transitive dependencies of the specified projects. Note that dependencies which can't be resolved
* from any repository but are present among the set of specified projects will not cause an exception. Instead, * from any repository but are present among the set of specified projects will not cause an exception. Instead,

View File

@ -14,11 +14,15 @@
*/ */
package org.apache.maven.lifecycle.internal; package org.apache.maven.lifecycle.internal;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.execution.BuildFailure; import org.apache.maven.execution.BuildFailure;
import org.apache.maven.execution.ExecutionEvent; import org.apache.maven.execution.ExecutionEvent;
import org.apache.maven.execution.MavenExecutionRequest; import org.apache.maven.execution.MavenExecutionRequest;
import org.apache.maven.execution.MavenSession; import org.apache.maven.execution.MavenSession;
import org.apache.maven.lifecycle.*; import org.apache.maven.lifecycle.LifecycleExecutionException;
import org.apache.maven.lifecycle.LifecycleNotFoundException;
import org.apache.maven.lifecycle.LifecyclePhaseNotFoundException;
import org.apache.maven.lifecycle.MavenExecutionPlan;
import org.apache.maven.plugin.*; import org.apache.maven.plugin.*;
import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException; import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
import org.apache.maven.plugin.version.PluginVersionResolutionException; import org.apache.maven.plugin.version.PluginVersionResolutionException;
@ -27,6 +31,8 @@ import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.component.annotations.Requirement;
import java.util.Set;
/** /**
* Common code that is shared by the LifecycleModuleBuilder and the LifeCycleWeaveBuilder * Common code that is shared by the LifecycleModuleBuilder and the LifeCycleWeaveBuilder
* *
@ -63,7 +69,8 @@ public class BuilderCommon
this.lifecycleDependencyResolver = lifecycleDependencyResolver; this.lifecycleDependencyResolver = lifecycleDependencyResolver;
} }
public MavenExecutionPlan resolveBuildPlan( MavenSession session, MavenProject project, TaskSegment taskSegment ) public MavenExecutionPlan resolveBuildPlan( MavenSession session, MavenProject project, TaskSegment taskSegment,
Set<Artifact> projectArtifacts )
throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException, throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException,
PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException, PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException,
NoPluginFoundForPrefixException, LifecycleNotFoundException, PluginVersionResolutionException, NoPluginFoundForPrefixException, LifecycleNotFoundException, PluginVersionResolutionException,
@ -78,7 +85,8 @@ public class BuilderCommon
// this later by looking at the build plan. Would be better to just batch download everything required // this later by looking at the build plan. Would be better to just batch download everything required
// by the reactor. // by the reactor.
lifecycleDependencyResolver.resolveDependencies( taskSegment.isAggregating(), project, session, executionPlan ); lifecycleDependencyResolver.resolveDependencies( taskSegment.isAggregating(), project, session, executionPlan,
projectArtifacts );
return executionPlan; return executionPlan;
} }

View File

@ -62,11 +62,12 @@ public class LifecycleDependencyResolver
} }
public void resolveDependencies( boolean aggregating, MavenProject currentProject, public void resolveDependencies( boolean aggregating, MavenProject currentProject,
MavenSession sessionForThisModule, MavenExecutionPlan executionPlan ) MavenSession sessionForThisModule, MavenExecutionPlan executionPlan,
Set<Artifact> projectArtifacts )
throws LifecycleExecutionException throws LifecycleExecutionException
{ {
List<MavenProject> projectsToResolve = getProjects( currentProject, sessionForThisModule, aggregating ); List<MavenProject> projectsToResolve = getProjects( currentProject, sessionForThisModule, aggregating );
resolveDependencies( aggregating, sessionForThisModule, executionPlan, projectsToResolve ); resolveDependencies( aggregating, sessionForThisModule, executionPlan, projectsToResolve, projectArtifacts );
} }
public static List<MavenProject> getProjects( MavenProject project, MavenSession session, boolean aggregator ) public static List<MavenProject> getProjects( MavenProject project, MavenSession session, boolean aggregator )
@ -89,7 +90,7 @@ public class LifecycleDependencyResolver
{ {
resolveProjectDependencies( dependenctContext.getLastProject(), dependenctContext.getScopesToCollect(), resolveProjectDependencies( dependenctContext.getLastProject(), dependenctContext.getScopesToCollect(),
dependenctContext.getScopesToResolve(), session, dependenctContext.getScopesToResolve(), session,
dependenctContext.isAggregating() ); dependenctContext.isAggregating(), new HashSet<Artifact>() );
} }
dependenctContext.setLastProject( session.getCurrentProject() ); dependenctContext.setLastProject( session.getCurrentProject() );
@ -97,30 +98,25 @@ public class LifecycleDependencyResolver
} }
private void resolveDependencies( boolean aggregating, MavenSession session, MavenExecutionPlan executionPlan, private void resolveDependencies( boolean aggregating, MavenSession session, MavenExecutionPlan executionPlan,
List<MavenProject> projectsToResolve ) List<MavenProject> projectsToResolve, Set<Artifact> projectArtifacts )
throws LifecycleExecutionException throws LifecycleExecutionException
{ {
for ( MavenProject project : projectsToResolve ) for ( MavenProject project : projectsToResolve )
{
resolveDependencies( project, aggregating, session, executionPlan );
}
}
private void resolveDependencies( MavenProject project, boolean aggregating, MavenSession session,
MavenExecutionPlan executionPlan )
throws LifecycleExecutionException
{ {
resolveProjectDependencies( project, executionPlan.getRequiredCollectionScopes(), resolveProjectDependencies( project, executionPlan.getRequiredCollectionScopes(),
executionPlan.getRequiredResolutionScopes(), session, aggregating ); executionPlan.getRequiredResolutionScopes(), session, aggregating,
projectArtifacts );
}
} }
private void resolveProjectDependencies( MavenProject project, Collection<String> scopesToCollect, private void resolveProjectDependencies( MavenProject project, Collection<String> scopesToCollect,
Collection<String> scopesToResolve, MavenSession session, Collection<String> scopesToResolve, MavenSession session,
boolean aggregating ) boolean aggregating, Set<Artifact> projectArtifacts )
throws LifecycleExecutionException throws LifecycleExecutionException
{ {
Set<Artifact> artifacts = Set<Artifact> artifacts =
getProjectDependencies( project, scopesToCollect, scopesToResolve, session, aggregating ); getProjectDependencies( project, scopesToCollect, scopesToResolve, session, aggregating,
projectArtifacts );
updateProjectArtifacts( project, artifacts ); updateProjectArtifacts( project, artifacts );
} }
@ -136,7 +132,7 @@ public class LifecycleDependencyResolver
private Set<Artifact> getProjectDependencies( MavenProject project, Collection<String> scopesToCollect, private Set<Artifact> getProjectDependencies( MavenProject project, Collection<String> scopesToCollect,
Collection<String> scopesToResolve, MavenSession session, Collection<String> scopesToResolve, MavenSession session,
boolean aggregating ) boolean aggregating, Set<Artifact> projectArtifacts )
throws LifecycleExecutionException throws LifecycleExecutionException
{ {
Set<Artifact> artifacts; Set<Artifact> artifacts;
@ -144,7 +140,8 @@ public class LifecycleDependencyResolver
{ {
try try
{ {
artifacts = projectDependenciesResolver.resolve( project, scopesToCollect, scopesToResolve, session ); artifacts = projectDependenciesResolver.resolve( project , scopesToCollect,
scopesToResolve, session, projectArtifacts );
} }
catch ( MultipleArtifactsNotFoundException e ) catch ( MultipleArtifactsNotFoundException e )
{ {
@ -153,6 +150,32 @@ public class LifecycleDependencyResolver
* plugins that require dependency resolution although they usually run in phases of the build where project * plugins that require dependency resolution although they usually run in phases of the build where project
* artifacts haven't been assembled yet. The prime example of this is "mvn release:prepare". * artifacts haven't been assembled yet. The prime example of this is "mvn release:prepare".
*/ */
artifacts = handleException( session, aggregating, e );
}
return artifacts;
}
catch ( ArtifactResolutionException e )
{
throw new LifecycleExecutionException( null, project, e );
}
catch ( ArtifactNotFoundException e )
{
throw new LifecycleExecutionException( null, project, e );
}
}
private Set<Artifact> handleException( MavenSession session, boolean aggregating,
MultipleArtifactsNotFoundException e )
throws MultipleArtifactsNotFoundException
{
Set<Artifact> artifacts;/*
* MNG-2277, the check below compensates for our bad plugin support where we ended up with aggregator
* plugins that require dependency resolution although they usually run in phases of the build where project
* artifacts haven't been assembled yet. The prime example of this is "mvn release:prepare".
*/
if ( aggregating && areAllArtifactsInReactor( session.getProjects(), e.getMissingArtifacts() ) ) if ( aggregating && areAllArtifactsInReactor( session.getProjects(), e.getMissingArtifacts() ) )
{ {
logger.warn( "The following artifacts could not be resolved at this point of the build" + logger.warn( "The following artifacts could not be resolved at this point of the build" +
@ -171,21 +194,8 @@ public class LifecycleDependencyResolver
{ {
throw e; throw e;
} }
}
return artifacts; return artifacts;
} }
catch ( ArtifactResolutionException e )
{
throw new LifecycleExecutionException( null, project, e );
}
catch ( ArtifactNotFoundException e )
{
throw new LifecycleExecutionException( null, project, e );
}
}
private Set<Artifact> getDependencyArtifacts( MavenProject project, Set<Artifact> artifacts ) private Set<Artifact> getDependencyArtifacts( MavenProject project, Set<Artifact> artifacts )
{ {

View File

@ -86,27 +86,61 @@ public class LifecycleExecutionPlanCalculatorImpl
Set<String> requiredDependencyResolutionScopes = new TreeSet<String>(); Set<String> requiredDependencyResolutionScopes = new TreeSet<String>();
Set<String> requiredDependencyCollectionScopes = new TreeSet<String>(); Set<String> requiredDependencyCollectionScopes = new TreeSet<String>();
final List<MojoExecution> executions = lifecyclePluginResolver.resolveMissingPluginVersions( project, session );
calculateExecutionPlan( session, project, tasks, requiredDependencyResolutionScopes,
requiredDependencyCollectionScopes ); final List<MojoExecution> executions = calculateMojoExecutions( session, project, tasks );
setupMojoExections( session, project, requiredDependencyResolutionScopes, requiredDependencyCollectionScopes,
executions );
final List<ExecutionPlanItem> planItem = defaultLifeCycles.createExecutionPlanItem( project, executions ); final List<ExecutionPlanItem> planItem = defaultLifeCycles.createExecutionPlanItem( project, executions );
return new MavenExecutionPlan( requiredDependencyResolutionScopes, requiredDependencyCollectionScopes, return new MavenExecutionPlan( requiredDependencyResolutionScopes, requiredDependencyCollectionScopes, planItem,
planItem, defaultLifeCycles ); defaultLifeCycles );
} }
public List<MojoExecution> calculateExecutionPlan( MavenSession session, MavenProject project, List<Object> tasks, private void setupMojoExections( MavenSession session, MavenProject project,
Set<String> requiredDependencyResolutionScopes, Set<String> requiredDependencyResolutionScopes,
Set<String> requiredDependencyCollectionScopes ) Set<String> requiredDependencyCollectionScopes,
throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException, List<MojoExecution> mojoExecutions )
PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException, throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
NoPluginFoundForPrefixException, LifecycleNotFoundException, PluginVersionResolutionException MojoNotFoundException, InvalidPluginDescriptorException, NoPluginFoundForPrefixException,
LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException
{ {
lifecyclePluginResolver.resolveMissingPluginVersions( project, session ); for ( MojoExecution mojoExecution : mojoExecutions )
{
MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
List<MojoExecution> mojoExecutions = new ArrayList<MojoExecution>(); if ( mojoDescriptor == null )
{
mojoDescriptor = pluginManager.getMojoDescriptor( mojoExecution.getPlugin(), mojoExecution.getGoal(),
DefaultRepositoryRequest.getRepositoryRequest(
session, project ) );
mojoExecution.setMojoDescriptor( mojoDescriptor );
}
populateMojoExecutionConfiguration( project, mojoExecution,
MojoExecution.Source.CLI.equals( mojoExecution.getSource() ) );
finalizeMojoConfiguration( mojoExecution );
calculateForkedExecutions( mojoExecution, session, project, new HashSet<MojoDescriptor>() );
collectDependencyRequirements( requiredDependencyResolutionScopes, requiredDependencyCollectionScopes,
mojoExecution );
}
}
private List<MojoExecution> calculateMojoExecutions( MavenSession session, MavenProject project,
List<Object> tasks )
throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
PluginVersionResolutionException, LifecyclePhaseNotFoundException
{
final List<MojoExecution> mojoExecutions = new ArrayList<MojoExecution>();
for ( Object task : tasks ) for ( Object task : tasks )
{ {
@ -138,31 +172,6 @@ public class LifecycleExecutionPlanCalculatorImpl
throw new IllegalStateException( "unexpected task " + task ); throw new IllegalStateException( "unexpected task " + task );
} }
} }
for ( MojoExecution mojoExecution : mojoExecutions )
{
MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
if ( mojoDescriptor == null )
{
mojoDescriptor = pluginManager.getMojoDescriptor( mojoExecution.getPlugin(), mojoExecution.getGoal(),
DefaultRepositoryRequest.getRepositoryRequest(
session, project ) );
mojoExecution.setMojoDescriptor( mojoDescriptor );
}
populateMojoExecutionConfiguration( project, mojoExecution,
MojoExecution.Source.CLI.equals( mojoExecution.getSource() ) );
finalizeMojoConfiguration( mojoExecution );
calculateForkedExecutions( mojoExecution, session, project, new HashSet<MojoDescriptor>() );
collectDependencyRequirements( requiredDependencyResolutionScopes, requiredDependencyCollectionScopes,
mojoExecution );
}
return mojoExecutions; return mojoExecutions;
} }

View File

@ -15,6 +15,7 @@
package org.apache.maven.lifecycle.internal; package org.apache.maven.lifecycle.internal;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.execution.BuildSuccess; import org.apache.maven.execution.BuildSuccess;
import org.apache.maven.execution.ExecutionEvent; import org.apache.maven.execution.ExecutionEvent;
import org.apache.maven.execution.MavenSession; import org.apache.maven.execution.MavenSession;
@ -23,6 +24,8 @@ import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.component.annotations.Requirement;
import java.util.HashSet;
/** /**
* Builds one or more lifecycles for a full module * Builds one or more lifecycles for a full module
* *
@ -72,7 +75,8 @@ public class LifecycleModuleBuilder
eventCatapult.fire( ExecutionEvent.Type.ProjectStarted, session, null ); eventCatapult.fire( ExecutionEvent.Type.ProjectStarted, session, null );
BuilderCommon.attachToThread( currentProject ); BuilderCommon.attachToThread( currentProject );
MavenExecutionPlan executionPlan = builderCommon.resolveBuildPlan( session, currentProject, taskSegment ); MavenExecutionPlan executionPlan =
builderCommon.resolveBuildPlan( session, currentProject, taskSegment, new HashSet<Artifact>() );
DependencyContext dependencyContext = new DependencyContext( executionPlan, isAggregating ); DependencyContext dependencyContext = new DependencyContext( executionPlan, isAggregating );
mojoExecutor.execute( session, executionPlan.getMojoExecutions(), reactorContext.getProjectIndex(), mojoExecutor.execute( session, executionPlan.getMojoExecutions(), reactorContext.getProjectIndex(),

View File

@ -29,8 +29,8 @@ import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.logging.Logger;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -72,14 +72,10 @@ public class LifecycleWeaveBuilder
@Requirement @Requirement
private Logger logger; private Logger logger;
@Requirement
private LifecycleDependencyResolver lifecycleDependencyResolver;
@Requirement @Requirement
private ExecutionEventCatapult eventCatapult; private ExecutionEventCatapult eventCatapult;
private final Map<MavenProject, MavenExecutionPlan> executionPlans = private Map<MavenProject, MavenExecutionPlan> executionPlans = new HashMap<MavenProject, MavenExecutionPlan>( );
Collections.synchronizedMap( new HashMap<MavenProject, MavenExecutionPlan>() );
@SuppressWarnings({"UnusedDeclaration"}) @SuppressWarnings({"UnusedDeclaration"})
@ -88,7 +84,6 @@ public class LifecycleWeaveBuilder
} }
public LifecycleWeaveBuilder(MojoExecutor mojoExecutor, BuilderCommon builderCommon, Logger logger, public LifecycleWeaveBuilder(MojoExecutor mojoExecutor, BuilderCommon builderCommon, Logger logger,
LifecycleDependencyResolver lifecycleDependencyResolver,
ExecutionEventCatapult eventCatapult) ExecutionEventCatapult eventCatapult)
{ {
this.mojoExecutor = mojoExecutor; this.mojoExecutor = mojoExecutor;
@ -111,13 +106,31 @@ public class LifecycleWeaveBuilder
{ {
ProjectBuildList segmentChunks = projectBuilds.getByTaskSegment( taskSegment ); ProjectBuildList segmentChunks = projectBuilds.getByTaskSegment( taskSegment );
ThreadOutputMuxer muxer = null; // new ThreadOutputMuxer( segmentChunks, System.out ); ThreadOutputMuxer muxer = null; // new ThreadOutputMuxer( segmentChunks, System.out );
Set<String> projectArtifacts = new HashSet<String>();
Set<Artifact> projectArtifactsA = new HashSet<Artifact>();
for (ProjectSegment segmentChunk : segmentChunks) {
Artifact artifact = segmentChunk.getProject().getArtifact();
if (artifact != null) {
projectArtifacts.add( ArtifactUtils.key(artifact));
projectArtifactsA.add( artifact);
}
}
for ( ProjectSegment projectBuild : segmentChunks ) for ( ProjectSegment projectBuild : segmentChunks )
{ {
try try
{ {
MavenExecutionPlan executionPlan = MavenExecutionPlan executionPlan =
builderCommon.resolveBuildPlan( projectBuild.getSession(), projectBuild.getProject(), builderCommon.resolveBuildPlan( projectBuild.getSession(), projectBuild.getProject(),
projectBuild.getTaskSegment() ); projectBuild.getTaskSegment(), projectArtifactsA );
for (Artifact dependency : projectBuild.getProject().getDependencyArtifacts()) {
String s = ArtifactUtils.key(dependency);
if ( projectArtifacts.contains(s)){
dependency.setFile( null);
dependency.setResolved( false);
dependency.setRepository( null);
}
}
executionPlans.put( projectBuild.getProject(), executionPlan ); executionPlans.put( projectBuild.getProject(), executionPlan );
DependencyContext dependencyContext = DependencyContext dependencyContext =
new DependencyContext( executionPlan, projectBuild.getTaskSegment().isAggregating() ); new DependencyContext( executionPlan, projectBuild.getTaskSegment().isAggregating() );
@ -182,8 +195,7 @@ public class LifecycleWeaveBuilder
try try
{ {
while ( current != null && !reactorBuildStatus.isHalted() && while (current != null && !reactorBuildStatus.isHaltedOrBlacklisted( projectBuild.getProject() ))
!reactorBuildStatus.isBlackListed( projectBuild.getProject() ) )
{ {
PhaseRecorder phaseRecorder = new PhaseRecorder( projectBuild.getProject() ); PhaseRecorder phaseRecorder = new PhaseRecorder( projectBuild.getProject() );
@ -191,19 +203,7 @@ public class LifecycleWeaveBuilder
concurrentBuildLogger.createBuildLogItem( projectBuild.getProject(), current ); concurrentBuildLogger.createBuildLogItem( projectBuild.getProject(), current );
final Schedule schedule = current.getSchedule(); final Schedule schedule = current.getSchedule();
if ( schedule != null && schedule.isMojoSynchronized() ) buildExecutionPlanItem(current, phaseRecorder, schedule, reactorContext, projectBuild, dependencyContext);
{
synchronized ( current.getPlugin() )
{
buildExecutionPlanItem( reactorContext, current, projectBuild, dependencyContext,
phaseRecorder );
}
}
else
{
buildExecutionPlanItem( reactorContext, current, projectBuild, dependencyContext,
phaseRecorder );
}
current.setComplete(); current.setComplete();
builtLogItem.setComplete(); builtLogItem.setComplete();
@ -212,62 +212,12 @@ public class LifecycleWeaveBuilder
if ( nextPlanItem != null ) if ( nextPlanItem != null )
{ {
boolean mustReResolved = false;
final Schedule scheduleOfNext = nextPlanItem.getSchedule(); final Schedule scheduleOfNext = nextPlanItem.getSchedule();
if ( scheduleOfNext == null || !scheduleOfNext.isParallel() ) if ( scheduleOfNext == null || !scheduleOfNext.isParallel() )
{ {
for ( MavenProject upstreamProject : projectBuild.getImmediateUpstreamProjects() ) waitForAppropriateUpstreamExecutionsToFinish(builtLogItem, nextPlanItem, projectBuild);
{
final MavenExecutionPlan upstreamPlan = executionPlans.get( upstreamProject );
final String nextPhase = nextPlanItem.getLifecyclePhase();
final ExecutionPlanItem inSchedule = upstreamPlan.findLastInPhase( nextPhase );
if ( inSchedule != null )
{
if ( upstreamPhaseModifiesArtifactResolutionState( inSchedule ) )
{
String key = ArtifactUtils.key( upstreamProject.getGroupId(),
upstreamProject.getArtifactId(),
upstreamProject.getVersion() );
final Set<Artifact> deps =
projectBuild.getProject().getDependencyArtifacts();
for ( Artifact dep : deps )
{
String depKey =
ArtifactUtils.key( dep.getGroupId(), dep.getArtifactId(),
dep.getVersion() );
if ( key.equals( depKey ) )
{
dep.setResolved( false );
mustReResolved = true;
}
}
}
long startWait = System.currentTimeMillis();
inSchedule.waitUntilDone();
builtLogItem.addWait( upstreamProject, inSchedule, startWait );
}
else if ( !upstreamPlan.containsPhase( nextPhase ) )
{
// Still a bit of a kludge; if we cannot connect in a sensible way to
// the upstream build plan we just revert to waiting for it all to
// complete. Real problem is per-mojo phase->lifecycle mapping
builtLogItem.addDependency( upstreamProject, "No phase tracking possible " );
upstreamPlan.waitUntilAllDone();
}
else
{
builtLogItem.addDependency( upstreamProject, "No schedule" );
}
}
}
if ( mustReResolved )
{
lifecycleDependencyResolver.resolveDependencies( false, projectBuild.getProject(),
projectBuild.getSession(),
executionPlan );
} }
reResolveReactorDependencies(nextPlanItem, projectBuild);
} }
current = nextPlanItem; current = nextPlanItem;
} }
@ -293,14 +243,138 @@ public class LifecycleWeaveBuilder
} }
return null; return null;
} }
}; };
} }
private boolean upstreamPhaseModifiesArtifactResolutionState( ExecutionPlanItem inSchedule ) private void reResolveReactorDependencies(ExecutionPlanItem nextPlanItem, ProjectSegment projectBuild) {
if ( requiresReResolutionOfUpstreamReactorArtifacts( nextPlanItem ) )
{ {
final String phase = inSchedule.getLifecyclePhase(); reresolveUpstreamProjectArtifacts(projectBuild);
return "install".equals( phase ) || "compile".equals( phase ) || "test-compile".equals( phase );
} }
else if (requiresReResolutionOfUpstreamTestScopedReactorArtifacts( nextPlanItem))
{
reresolveUpstreamTestScopedArtifacts( projectBuild);
}
}
private void waitForAppropriateUpstreamExecutionsToFinish(BuildLogItem builtLogItem, ExecutionPlanItem nextPlanItem, ProjectSegment projectBuild) throws InterruptedException {
for ( MavenProject upstreamProject : projectBuild.getImmediateUpstreamProjects() )
{
final MavenExecutionPlan upstreamPlan = executionPlans.get( upstreamProject );
final String nextPhase = nextPlanItem.getLifecyclePhase();
final ExecutionPlanItem inSchedule = upstreamPlan.findLastInPhase( nextPhase );
if ( inSchedule != null )
{
long startWait = System.currentTimeMillis();
inSchedule.waitUntilDone();
builtLogItem.addWait( upstreamProject, inSchedule, startWait );
}
else if ( !upstreamPlan.containsPhase( nextPhase ) )
{
// Still a bit of a kludge; if we cannot connect in a sensible way to
// the upstream build plan we just revert to waiting for it all to
// complete. Real problem is per-mojo phase->lifecycle mapping
builtLogItem.addDependency( upstreamProject, "No phase tracking possible " );
upstreamPlan.waitUntilAllDone();
}
else
{
builtLogItem.addDependency( upstreamProject, "No schedule" );
}
}
}
private void reresolveUpstreamProjectArtifacts(ProjectSegment projectBuild) {
for ( MavenProject upstreamProject : projectBuild.getTransitiveUpstreamProjects() ){
Artifact upStreamArtifact = upstreamProject.getArtifact();
Artifact dependencyArtifact = findDependency(projectBuild.getProject(), upStreamArtifact);
if (dependencyArtifact != null){
dependencyArtifact.setFile( upStreamArtifact.getFile());
dependencyArtifact.setResolved( true );
dependencyArtifact.setRepository( upStreamArtifact.getRepository());
}
}
}
private void reresolveUpstreamTestScopedArtifacts(ProjectSegment projectBuild) {
for ( MavenProject upstreamProject : projectBuild.getTransitiveUpstreamProjects() ){
Artifact upStreamArtifact = findTestScopedArtifact(upstreamProject);
Artifact dependencyArtifact = findDependency(projectBuild.getProject(), upStreamArtifact);
if (dependencyArtifact != null){
dependencyArtifact.setFile( upStreamArtifact.getFile());
dependencyArtifact.setResolved( upStreamArtifact.isResolved());
dependencyArtifact.setRepository( upStreamArtifact.getRepository());
}
}
}
private Artifact findTestScopedArtifact(MavenProject upstreamProject) {
if ( upstreamProject == null){
return null;
}
List<Artifact> artifactList = upstreamProject.getAttachedArtifacts();
for (Artifact artifact : artifactList) {
if (Artifact.SCOPE_TEST.equals( artifact.getScope())){
return artifact;
}
}
return null;
}
private static Artifact findDependency(MavenProject project, Artifact upStreamArtifact) {
if (upStreamArtifact == null){
return null;
}
String key = ArtifactUtils.key( upStreamArtifact.getGroupId(),
upStreamArtifact.getArtifactId(),
upStreamArtifact.getVersion() );
final Set<Artifact> deps = project.getDependencyArtifacts();
for ( Artifact dep : deps )
{
String depKey = ArtifactUtils.key(dep.getGroupId(), dep.getArtifactId(), dep.getVersion());
if ( key.equals( depKey ) )
{
return dep;
}
}
return null;
}
private boolean requiresReResolutionOfUpstreamReactorArtifacts( ExecutionPlanItem nextExecutionPlanItem )
{
final String phase = nextExecutionPlanItem.getLifecyclePhase();
return "package".equals(phase) || "install".equals( phase ) || "compile".equals( phase );
}
private boolean requiresReResolutionOfUpstreamTestScopedReactorArtifacts( ExecutionPlanItem nextExecutionPlanItem )
{
final String phase = nextExecutionPlanItem.getLifecyclePhase();
return "package".equals(phase) || "install".equals( phase ) || "compile".equals( phase ) || "test-compile".equals( phase );
}
private void buildExecutionPlanItem(ExecutionPlanItem current, PhaseRecorder phaseRecorder, Schedule schedule, ReactorContext reactorContext, ProjectSegment projectBuild, DependencyContext dependencyContext) throws LifecycleExecutionException {
if ( schedule != null && schedule.isMojoSynchronized() )
{
synchronized ( current.getPlugin() )
{
buildExecutionPlanItem( reactorContext, current, projectBuild, dependencyContext,
phaseRecorder );
}
}
else
{
buildExecutionPlanItem( reactorContext, current, projectBuild, dependencyContext,
phaseRecorder );
}
}
private void buildExecutionPlanItem( ReactorContext reactorContext, ExecutionPlanItem node, private void buildExecutionPlanItem( ReactorContext reactorContext, ExecutionPlanItem node,
ProjectSegment projectBuild, DependencyContext dependencyContext, ProjectSegment projectBuild, DependencyContext dependencyContext,

View File

@ -53,12 +53,18 @@ public final class ProjectSegment
private final MavenSession session; private final MavenSession session;
private final List<MavenProject> nonTransitiveUpstreamProjects;
private final List<MavenProject> transitiveUpstreamProjects;
public ProjectSegment( MavenProject project, TaskSegment taskSegment, MavenSession copiedSession ) public ProjectSegment( MavenProject project, TaskSegment taskSegment, MavenSession copiedSession )
{ {
this.project = project; this.project = project;
this.taskSegment = taskSegment; this.taskSegment = taskSegment;
this.session = copiedSession; this.session = copiedSession;
final ProjectDependencyGraph dependencyGraph = getSession().getProjectDependencyGraph();
nonTransitiveUpstreamProjects = dependencyGraph.getUpstreamProjects( getProject(), false );
transitiveUpstreamProjects = dependencyGraph.getUpstreamProjects( getProject(), true );
} }
public MavenSession getSession() public MavenSession getSession()
@ -78,8 +84,12 @@ public final class ProjectSegment
public List<MavenProject> getImmediateUpstreamProjects() public List<MavenProject> getImmediateUpstreamProjects()
{ {
final ProjectDependencyGraph dependencyGraph = getSession().getProjectDependencyGraph(); return nonTransitiveUpstreamProjects;
return dependencyGraph.getUpstreamProjects( getProject(), false ); }
public List<MavenProject> getTransitiveUpstreamProjects()
{
return transitiveUpstreamProjects;
} }
@Override @Override

View File

@ -16,6 +16,7 @@
package org.apache.maven.lifecycle.internal; package org.apache.maven.lifecycle.internal;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.execution.MavenSession; import org.apache.maven.execution.MavenSession;
import org.apache.maven.lifecycle.MavenExecutionPlan; import org.apache.maven.lifecycle.MavenExecutionPlan;
import org.apache.maven.lifecycle.internal.stub.LifecycleExecutionPlanCalculatorStub; import org.apache.maven.lifecycle.internal.stub.LifecycleExecutionPlanCalculatorStub;
@ -23,6 +24,8 @@ import org.apache.maven.lifecycle.internal.stub.LoggerStub;
import org.apache.maven.lifecycle.internal.stub.ProjectDependenciesResolverStub; import org.apache.maven.lifecycle.internal.stub.ProjectDependenciesResolverStub;
import org.apache.maven.lifecycle.internal.stub.ProjectDependencyGraphStub; import org.apache.maven.lifecycle.internal.stub.ProjectDependencyGraphStub;
import java.util.HashSet;
/** /**
* @author Kristian Rosenvold * @author Kristian Rosenvold
*/ */
@ -40,7 +43,8 @@ public class BuilderCommonTest
final BuilderCommon builderCommon = getBuilderCommon(); final BuilderCommon builderCommon = getBuilderCommon();
final MavenExecutionPlan plan = final MavenExecutionPlan plan =
builderCommon.resolveBuildPlan( session1, ProjectDependencyGraphStub.A, taskSegment1 ); builderCommon.resolveBuildPlan( session1, ProjectDependencyGraphStub.A, taskSegment1,
new HashSet<Artifact>() );
assertEquals( LifecycleExecutionPlanCalculatorStub.getProjectAExceutionPlan().size(), plan.size() ); assertEquals( LifecycleExecutionPlanCalculatorStub.getProjectAExceutionPlan().size(), plan.size() );
} }

View File

@ -122,8 +122,7 @@ public class LifecycleWeaveBuilderTest
final LoggerStub loggerStub = new LoggerStub(); final LoggerStub loggerStub = new LoggerStub();
final LifecycleDependencyResolver lifecycleDependencyResolver = final LifecycleDependencyResolver lifecycleDependencyResolver =
new LifecycleDependencyResolver( new ProjectDependenciesResolverStub(), loggerStub ); new LifecycleDependencyResolver( new ProjectDependenciesResolverStub(), loggerStub );
return new LifecycleWeaveBuilder( mojoExecutor, builderCommon, loggerStub, lifecycleDependencyResolver, return new LifecycleWeaveBuilder( mojoExecutor, builderCommon, loggerStub, new ExecutionEventCatapultStub() );
new ExecutionEventCatapultStub() );
} }
private BuilderCommon getBuilderCommon() private BuilderCommon getBuilderCommon()

View File

@ -51,4 +51,12 @@ public class ProjectDependenciesResolverStub
{ {
return new HashSet<Artifact>(); return new HashSet<Artifact>();
} }
public Set<Artifact> resolve( MavenProject project, Collection<String> scopesToCollect,
Collection<String> scopesToResolve, MavenSession session,
Set<Artifact> ignoreableArtifacts )
throws ArtifactResolutionException, ArtifactNotFoundException
{
return new HashSet<Artifact>();
}
} }

View File

@ -190,10 +190,10 @@ public class ProjectDependencyGraphStub
public List<MavenProject> getUpstreamProjects( MavenProject project, boolean transitive ) public List<MavenProject> getUpstreamProjects( MavenProject project, boolean transitive )
{ {
if ( transitive ) /* if ( transitive )
{ {
throw new RuntimeException( "Not implemented yet" ); throw new RuntimeException( "Not implemented yet" );
} }*/
List<MavenProject> result = new ArrayList<MavenProject>(); List<MavenProject> result = new ArrayList<MavenProject>();
final List<Dependency> dependencies = getDependencies(); final List<Dependency> dependencies = getDependencies();
for ( Dependency dependency : dependencies ) for ( Dependency dependency : dependencies )