mirror of https://github.com/apache/maven.git
[MNG-2576] Make Like Reactor Mode
git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@794043 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
433d4bf3b8
commit
df47b11957
|
@ -22,6 +22,7 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
@ -36,6 +37,7 @@ import org.apache.maven.execution.DuplicateProjectException;
|
|||
import org.apache.maven.execution.MavenExecutionRequest;
|
||||
import org.apache.maven.execution.MavenExecutionResult;
|
||||
import org.apache.maven.execution.MavenSession;
|
||||
import org.apache.maven.execution.ProjectDependencyGraph;
|
||||
import org.apache.maven.execution.ProjectSorter;
|
||||
import org.apache.maven.lifecycle.LifecycleExecutor;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
|
@ -140,14 +142,14 @@ public class DefaultMaven
|
|||
}
|
||||
|
||||
try
|
||||
{
|
||||
{
|
||||
ProjectSorter projectSorter = new ProjectSorter( session.getProjects() );
|
||||
|
||||
projects = projectSorter.getSortedProjects();
|
||||
ProjectDependencyGraph projectDependencyGraph = createDependencyGraph( projectSorter, request );
|
||||
|
||||
session.setProjects( projects );
|
||||
session.setProjects( projectDependencyGraph.getSortedProjects() );
|
||||
|
||||
session.setProjectDependencyGraph( new DefaultProjectDependencyGraph( projectSorter ) );
|
||||
session.setProjectDependencyGraph( projectDependencyGraph );
|
||||
}
|
||||
catch ( CycleDetectedException e )
|
||||
{
|
||||
|
@ -161,6 +163,10 @@ public class DefaultMaven
|
|||
{
|
||||
return processResult( result, e );
|
||||
}
|
||||
catch ( MavenExecutionException e )
|
||||
{
|
||||
return processResult( result, e );
|
||||
}
|
||||
|
||||
// Desired order of precedence for local artifact repositories
|
||||
//
|
||||
|
@ -293,6 +299,8 @@ public class DefaultMaven
|
|||
for ( File file : files )
|
||||
{
|
||||
MavenProject project = projectBuilder.build( file, request.getProjectBuildingRequest() );
|
||||
|
||||
projects.add( project );
|
||||
|
||||
if ( ( project.getModules() != null ) && !project.getModules().isEmpty() && request.isRecursive() )
|
||||
{
|
||||
|
@ -340,8 +348,6 @@ public class DefaultMaven
|
|||
|
||||
collectProjects( projects, moduleFiles, request );
|
||||
}
|
||||
|
||||
projects.add( project );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -368,4 +374,90 @@ public class DefaultMaven
|
|||
return logger;
|
||||
}
|
||||
|
||||
private ProjectDependencyGraph createDependencyGraph( ProjectSorter sorter, MavenExecutionRequest request )
|
||||
throws MavenExecutionException
|
||||
{
|
||||
ProjectDependencyGraph graph = new DefaultProjectDependencyGraph( sorter );
|
||||
|
||||
if ( !request.getSelectedProjects().isEmpty() )
|
||||
{
|
||||
File reactorDirectory = request.getPom().getParentFile().getAbsoluteFile();
|
||||
|
||||
Map<File, MavenProject> projectsByFile = new HashMap<File, MavenProject>();
|
||||
|
||||
for ( MavenProject project : sorter.getSortedProjects() )
|
||||
{
|
||||
projectsByFile.put( project.getFile(), project );
|
||||
}
|
||||
|
||||
List<MavenProject> selectedProjects = new ArrayList<MavenProject>( request.getSelectedProjects().size() );
|
||||
|
||||
for ( String selectedProject : request.getSelectedProjects() )
|
||||
{
|
||||
File pomFile = new File( reactorDirectory, selectedProject );
|
||||
|
||||
if ( pomFile.isDirectory() )
|
||||
{
|
||||
pomFile = new File( pomFile, Maven.POMv4 );
|
||||
}
|
||||
|
||||
MavenProject project = projectsByFile.get( pomFile );
|
||||
|
||||
if ( project != null )
|
||||
{
|
||||
selectedProjects.add( project );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new MavenExecutionException( "Could not find project in reactor: " + selectedProject,
|
||||
request.getPom() );
|
||||
}
|
||||
}
|
||||
|
||||
boolean makeUpstream = false;
|
||||
boolean makeDownstream = false;
|
||||
if ( MavenExecutionRequest.REACTOR_MAKE_UPSTREAM.equals( request.getMakeBehavior() ) )
|
||||
{
|
||||
makeUpstream = true;
|
||||
}
|
||||
else if ( MavenExecutionRequest.REACTOR_MAKE_DOWNSTREAM.equals( request.getMakeBehavior() ) )
|
||||
{
|
||||
makeDownstream = true;
|
||||
}
|
||||
else if ( MavenExecutionRequest.REACTOR_MAKE_BOTH.equals( request.getMakeBehavior() ) )
|
||||
{
|
||||
makeUpstream = true;
|
||||
makeDownstream = true;
|
||||
}
|
||||
else if ( StringUtils.isNotEmpty( request.getMakeBehavior() ) )
|
||||
{
|
||||
throw new MavenExecutionException( "Invalid reactor make behavior: " + request.getMakeBehavior(),
|
||||
request.getPom() );
|
||||
}
|
||||
|
||||
Collection<MavenProject> makeProjects = new LinkedHashSet<MavenProject>( selectedProjects );
|
||||
|
||||
if ( makeUpstream || makeDownstream )
|
||||
{
|
||||
for ( MavenProject selectedProject : selectedProjects )
|
||||
{
|
||||
if ( makeUpstream )
|
||||
{
|
||||
makeProjects.addAll( graph.getUpstreamProjects( selectedProject, true ) );
|
||||
}
|
||||
if ( makeDownstream )
|
||||
{
|
||||
makeProjects.addAll( graph.getDownstreamProjects( selectedProject, true ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: process resume from
|
||||
|
||||
graph = new FilteredProjectDependencyGraph( graph, makeProjects );
|
||||
}
|
||||
|
||||
return graph;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -70,17 +70,7 @@ class DefaultProjectDependencyGraph
|
|||
|
||||
getDownstreamProjects( ProjectSorter.getId( project ), projectIds, transitive );
|
||||
|
||||
List<MavenProject> projects = new ArrayList<MavenProject>();
|
||||
|
||||
for ( MavenProject p : sorter.getSortedProjects() )
|
||||
{
|
||||
if ( projectIds.contains( ProjectSorter.getId( p ) ) )
|
||||
{
|
||||
projects.add( p );
|
||||
}
|
||||
}
|
||||
|
||||
return projects;
|
||||
return getProjects( projectIds );
|
||||
}
|
||||
|
||||
private void getDownstreamProjects( String projectId, Collection<String> projectIds, boolean transitive )
|
||||
|
@ -96,6 +86,48 @@ class DefaultProjectDependencyGraph
|
|||
}
|
||||
}
|
||||
|
||||
public List<MavenProject> getUpstreamProjects( MavenProject project, boolean transitive )
|
||||
{
|
||||
if ( project == null )
|
||||
{
|
||||
throw new IllegalArgumentException( "project missing" );
|
||||
}
|
||||
|
||||
Collection<String> projectIds = new HashSet<String>();
|
||||
|
||||
getUpstreamProjects( ProjectSorter.getId( project ), projectIds, transitive );
|
||||
|
||||
return getProjects( projectIds );
|
||||
}
|
||||
|
||||
private void getUpstreamProjects( String projectId, Collection<String> projectIds, boolean transitive )
|
||||
{
|
||||
for ( String id : sorter.getDependencies( projectId ) )
|
||||
{
|
||||
projectIds.add( id );
|
||||
|
||||
if ( transitive )
|
||||
{
|
||||
getUpstreamProjects( id, projectIds, transitive );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<MavenProject> getProjects( Collection<String> projectIds )
|
||||
{
|
||||
List<MavenProject> projects = new ArrayList<MavenProject>();
|
||||
|
||||
for ( MavenProject p : sorter.getSortedProjects() )
|
||||
{
|
||||
if ( projectIds.contains( ProjectSorter.getId( p ) ) )
|
||||
{
|
||||
projects.add( p );
|
||||
}
|
||||
}
|
||||
|
||||
return projects;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
package org.apache.maven;
|
||||
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.maven.execution.ProjectDependencyGraph;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
|
||||
/**
|
||||
* Provides a sub view of another dependency graph.
|
||||
*
|
||||
* @author Benjamin Bentmann
|
||||
*/
|
||||
class FilteredProjectDependencyGraph
|
||||
implements ProjectDependencyGraph
|
||||
{
|
||||
|
||||
private ProjectDependencyGraph projectDependencyGraph;
|
||||
|
||||
private Map<MavenProject, ?> whiteList;
|
||||
|
||||
private List<MavenProject> sortedProjects;
|
||||
|
||||
/**
|
||||
* Creates a new project dependency graph from the specified graph.
|
||||
*
|
||||
* @param projectDependencyGraph The project dependency graph to create a sub view from, must not be {@code null}.
|
||||
* @param whiteList The projects on which the dependency view should focus, must not be {@code null}.
|
||||
*/
|
||||
public FilteredProjectDependencyGraph( ProjectDependencyGraph projectDependencyGraph,
|
||||
Collection<? extends MavenProject> whiteList )
|
||||
{
|
||||
if ( projectDependencyGraph == null )
|
||||
{
|
||||
throw new IllegalArgumentException( "project dependency graph missing" );
|
||||
}
|
||||
|
||||
this.projectDependencyGraph = projectDependencyGraph;
|
||||
|
||||
this.whiteList = new IdentityHashMap<MavenProject, Object>();
|
||||
|
||||
for ( MavenProject project : whiteList )
|
||||
{
|
||||
this.whiteList.put( project, null );
|
||||
}
|
||||
}
|
||||
|
||||
public List<MavenProject> getSortedProjects()
|
||||
{
|
||||
if ( sortedProjects == null )
|
||||
{
|
||||
sortedProjects = applyFilter( projectDependencyGraph.getSortedProjects() );
|
||||
}
|
||||
|
||||
return new ArrayList<MavenProject>( sortedProjects );
|
||||
}
|
||||
|
||||
public List<MavenProject> getDownstreamProjects( MavenProject project, boolean transitive )
|
||||
{
|
||||
return applyFilter( projectDependencyGraph.getDownstreamProjects( project, transitive ) );
|
||||
}
|
||||
|
||||
public List<MavenProject> getUpstreamProjects( MavenProject project, boolean transitive )
|
||||
{
|
||||
return applyFilter( projectDependencyGraph.getUpstreamProjects( project, transitive ) );
|
||||
}
|
||||
|
||||
private List<MavenProject> applyFilter( Collection<? extends MavenProject> projects )
|
||||
{
|
||||
List<MavenProject> filtered = new ArrayList<MavenProject>( projects.size() );
|
||||
|
||||
for ( MavenProject project : projects )
|
||||
{
|
||||
if ( whiteList.containsKey( project ) )
|
||||
{
|
||||
filtered.add( project );
|
||||
}
|
||||
}
|
||||
|
||||
return filtered;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getSortedProjects().toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -85,6 +85,12 @@ public class DefaultMavenExecutionRequest
|
|||
|
||||
private String reactorFailureBehavior = REACTOR_FAIL_FAST;
|
||||
|
||||
private List<String> selectedProjects;
|
||||
|
||||
private String resumeFrom;
|
||||
|
||||
private String makeBehavior;
|
||||
|
||||
private Properties properties;
|
||||
|
||||
private Date startTime;
|
||||
|
@ -200,6 +206,26 @@ public class DefaultMavenExecutionRequest
|
|||
return reactorFailureBehavior;
|
||||
}
|
||||
|
||||
public List<String> getSelectedProjects()
|
||||
{
|
||||
if ( selectedProjects == null )
|
||||
{
|
||||
selectedProjects = new ArrayList<String>();
|
||||
}
|
||||
|
||||
return selectedProjects;
|
||||
}
|
||||
|
||||
public String getResumeFrom()
|
||||
{
|
||||
return resumeFrom;
|
||||
}
|
||||
|
||||
public String getMakeBehavior()
|
||||
{
|
||||
return makeBehavior;
|
||||
}
|
||||
|
||||
public Date getStartTime()
|
||||
{
|
||||
return startTime;
|
||||
|
@ -414,6 +440,34 @@ public class DefaultMavenExecutionRequest
|
|||
return this;
|
||||
}
|
||||
|
||||
public MavenExecutionRequest setSelectedProjects( List<String> selectedProjects )
|
||||
{
|
||||
if ( selectedProjects != null )
|
||||
{
|
||||
this.selectedProjects = new ArrayList<String>( selectedProjects );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.selectedProjects = null;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public MavenExecutionRequest setResumeFrom( String project )
|
||||
{
|
||||
this.resumeFrom = project;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public MavenExecutionRequest setMakeBehavior( String makeBehavior )
|
||||
{
|
||||
this.makeBehavior = makeBehavior;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public MavenExecutionRequest addActiveProfile( String profile )
|
||||
{
|
||||
if ( !getActiveProfiles().contains( profile ) )
|
||||
|
|
|
@ -64,6 +64,16 @@ public interface MavenExecutionRequest
|
|||
|
||||
static final String REACTOR_FAIL_NEVER = "FAIL_NEVER";
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Reactor Make Mode
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
static final String REACTOR_MAKE_UPSTREAM = "make-upstream";
|
||||
|
||||
static final String REACTOR_MAKE_DOWNSTREAM = "make-downstream";
|
||||
|
||||
static final String REACTOR_MAKE_BOTH = "make-both";
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Artifactr repository policies
|
||||
// ----------------------------------------------------------------------
|
||||
|
@ -97,6 +107,15 @@ public interface MavenExecutionRequest
|
|||
MavenExecutionRequest setReactorFailureBehavior( String failureBehavior );
|
||||
String getReactorFailureBehavior();
|
||||
|
||||
MavenExecutionRequest setSelectedProjects( List<String> projects );
|
||||
List<String> getSelectedProjects();
|
||||
|
||||
MavenExecutionRequest setResumeFrom( String project );
|
||||
String getResumeFrom();
|
||||
|
||||
MavenExecutionRequest setMakeBehavior( String makeBehavior );
|
||||
String getMakeBehavior();
|
||||
|
||||
// Recursive (really to just process the top-level POM)
|
||||
MavenExecutionRequest setRecursive( boolean recursive );
|
||||
boolean isRecursive();
|
||||
|
|
|
@ -40,7 +40,7 @@ public interface ProjectDependencyGraph
|
|||
List<MavenProject> getSortedProjects();
|
||||
|
||||
/**
|
||||
* Gets the downstream projects of the specified projects. A downstream project is a project that directly or
|
||||
* Gets the downstream projects of the specified project. A downstream project is a project that directly or
|
||||
* indirectly depends on the given project.
|
||||
*
|
||||
* @param project The project whose downstream projects should be retrieved, must not be {@code null}.
|
||||
|
@ -50,4 +50,15 @@ public interface ProjectDependencyGraph
|
|||
*/
|
||||
List<MavenProject> getDownstreamProjects( MavenProject project, boolean transitive );
|
||||
|
||||
/**
|
||||
* Gets the upstream projects of the specified project. An upstream project is a project that directly or indirectly
|
||||
* is a prerequisite of the given project.
|
||||
*
|
||||
* @param project The project whose upstream projects should be retrieved, must not be {@code null}.
|
||||
* @param transitive A flag whether to retrieve all direct and indirect upstream projects or just the immediate
|
||||
* upstream projects.
|
||||
* @return The upstream projects in the build order, never {@code null}.
|
||||
*/
|
||||
List<MavenProject> getUpstreamProjects( MavenProject project, boolean transitive );
|
||||
|
||||
}
|
||||
|
|
|
@ -193,6 +193,11 @@ public class ProjectSorter
|
|||
return dag.getParentLabels( id );
|
||||
}
|
||||
|
||||
public List<String> getDependencies( String id )
|
||||
{
|
||||
return dag.getChildLabels( id );
|
||||
}
|
||||
|
||||
public static String getId( MavenProject project )
|
||||
{
|
||||
return ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() );
|
||||
|
|
|
@ -84,6 +84,14 @@ public class CLIManager
|
|||
|
||||
public static final String FAIL_NEVER = "fn";
|
||||
|
||||
public static final String RESUME_FROM = "rf";
|
||||
|
||||
public static final String PROJECT_LIST = "pl";
|
||||
|
||||
public static final String ALSO_MAKE = "am";
|
||||
|
||||
public static final String ALSO_MAKE_DEPENDENTS = "amd";
|
||||
|
||||
public static final String LOG_FILE = "l";
|
||||
|
||||
private Options options;
|
||||
|
@ -117,6 +125,10 @@ public class CLIManager
|
|||
options.addOption( OptionBuilder.withLongOpt( "fail-fast" ).withDescription( "Stop at first failure in reactorized builds" ).create( FAIL_FAST ) );
|
||||
options.addOption( OptionBuilder.withLongOpt( "fail-at-end" ).withDescription( "Only fail the build afterwards; allow all non-impacted builds to continue" ).create( FAIL_AT_END ) );
|
||||
options.addOption( OptionBuilder.withLongOpt( "fail-never" ).withDescription( "NEVER fail the build, regardless of project result" ).create( FAIL_NEVER ) );
|
||||
options.addOption( OptionBuilder.withLongOpt( "resume-from" ).hasArg().withDescription( "Resume reactor from specified project" ).create( RESUME_FROM ) );
|
||||
options.addOption( OptionBuilder.withLongOpt( "projects" ).withDescription( "Build specified reactor projects instead of all projects" ).hasArg().create( PROJECT_LIST ) );
|
||||
options.addOption( OptionBuilder.withLongOpt( "also-make" ).withDescription( "If project list is specified, also build projects required by the list" ).create( ALSO_MAKE ) );
|
||||
options.addOption( OptionBuilder.withLongOpt( "also-make-dependents" ).withDescription( "If project list is specified, also build projects that depend on projects on the list" ).create( ALSO_MAKE_DEPENDENTS ) );
|
||||
options.addOption( OptionBuilder.withLongOpt( "log-file" ).hasArg().withDescription( "Log file to where all build output will go." ).create( LOG_FILE ) );
|
||||
options.addOption( OptionBuilder.withLongOpt( "show-version" ).withDescription( "Display version information WITHOUT stopping build" ).create( SHOW_VERSION ) );
|
||||
|
||||
|
@ -138,7 +150,7 @@ public class CLIManager
|
|||
|
||||
private String[] cleanArgs( String[] args )
|
||||
{
|
||||
List cleaned = new ArrayList();
|
||||
List<String> cleaned = new ArrayList<String>();
|
||||
|
||||
StringBuffer currentArg = null;
|
||||
|
||||
|
@ -226,7 +238,7 @@ public class CLIManager
|
|||
}
|
||||
else
|
||||
{
|
||||
cleanArgs = (String[]) cleaned.toArray( new String[cleanedSz] );
|
||||
cleanArgs = cleaned.toArray( new String[cleanedSz] );
|
||||
}
|
||||
|
||||
return cleanArgs;
|
||||
|
|
|
@ -22,6 +22,7 @@ package org.apache.maven.cli;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.StringTokenizer;
|
||||
|
@ -33,6 +34,7 @@ import org.apache.maven.MavenTransferListener;
|
|||
import org.apache.maven.embedder.MavenEmbedder;
|
||||
import org.apache.maven.execution.DefaultMavenExecutionRequest;
|
||||
import org.apache.maven.execution.MavenExecutionRequest;
|
||||
import org.codehaus.plexus.util.StringUtils;
|
||||
import org.codehaus.plexus.util.cli.CommandLineUtils;
|
||||
|
||||
public final class CLIRequestUtils
|
||||
|
@ -267,7 +269,34 @@ public final class CLIRequestUtils
|
|||
{
|
||||
request.setPom( pom );
|
||||
}
|
||||
|
||||
|
||||
if ( commandLine.hasOption( CLIManager.RESUME_FROM ) )
|
||||
{
|
||||
request.setResumeFrom( commandLine.getOptionValue( CLIManager.RESUME_FROM ) );
|
||||
}
|
||||
|
||||
if ( commandLine.hasOption( CLIManager.PROJECT_LIST ) )
|
||||
{
|
||||
String projectList = commandLine.getOptionValue( CLIManager.PROJECT_LIST );
|
||||
String[] projects = StringUtils.split( projectList, "," );
|
||||
request.setSelectedProjects( Arrays.asList( projects ) );
|
||||
}
|
||||
|
||||
if ( commandLine.hasOption( CLIManager.ALSO_MAKE ) && !commandLine.hasOption( CLIManager.ALSO_MAKE_DEPENDENTS ) )
|
||||
{
|
||||
request.setMakeBehavior( MavenExecutionRequest.REACTOR_MAKE_UPSTREAM );
|
||||
}
|
||||
else if ( !commandLine.hasOption( CLIManager.ALSO_MAKE )
|
||||
&& commandLine.hasOption( CLIManager.ALSO_MAKE_DEPENDENTS ) )
|
||||
{
|
||||
request.setMakeBehavior( MavenExecutionRequest.REACTOR_MAKE_DOWNSTREAM );
|
||||
}
|
||||
else if ( commandLine.hasOption( CLIManager.ALSO_MAKE )
|
||||
&& commandLine.hasOption( CLIManager.ALSO_MAKE_DEPENDENTS ) )
|
||||
{
|
||||
request.setMakeBehavior( MavenExecutionRequest.REACTOR_MAKE_BOTH );
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue