From 1e217703a8f6d6378e8a92c57878f53368b289af Mon Sep 17 00:00:00 2001 From: rfscholte Date: Sat, 20 Jun 2020 22:39:29 +0200 Subject: [PATCH] [MNG-6863] Support --also-make flag in combination with --resume-from. Author: Martin Kanters --- .../maven/graph/DefaultGraphBuilder.java | 183 ++++++------------ .../maven/graph/DefaultGraphBuilderTest.java | 11 +- 2 files changed, 69 insertions(+), 125 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/graph/DefaultGraphBuilder.java b/maven-core/src/main/java/org/apache/maven/graph/DefaultGraphBuilder.java index 07cb80ee6f..164c3dcd0e 100644 --- a/maven-core/src/main/java/org/apache/maven/graph/DefaultGraphBuilder.java +++ b/maven-core/src/main/java/org/apache/maven/graph/DefaultGraphBuilder.java @@ -25,10 +25,12 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; import javax.inject.Inject; import javax.inject.Named; @@ -59,6 +61,8 @@ import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.util.StringUtils; import org.codehaus.plexus.util.dag.CycleDetectedException; +import static java.util.Comparator.comparing; + /** * Builds the {@link ProjectDependencyGraph inter-dependencies graph} between projects in the reactor. */ @@ -149,43 +153,27 @@ public class DefaultGraphBuilder if ( !request.getSelectedProjects().isEmpty() ) { - result = new ArrayList<>( projects.size() ); + File reactorDirectory = getReactorDirectory( request ); - File reactorDirectory = null; - if ( request.getBaseDirectory() != null ) - { - reactorDirectory = new File( request.getBaseDirectory() ); - } - - Collection selectedProjects = new LinkedHashSet<>( projects.size() ); + Collection selectedProjects = new LinkedHashSet<>( request.getSelectedProjects().size(), 1 ); for ( String selector : request.getSelectedProjects() ) { - MavenProject selectedProject = null; - - for ( MavenProject project : projects ) - { - if ( isMatchingProject( project, selector, reactorDirectory ) ) - { - selectedProject = project; - break; - } - } - - if ( selectedProject != null ) - { - selectedProjects.add( selectedProject ); - } - else - { - throw new MavenExecutionException( "Could not find the selected project in the reactor: " - + selector, request.getPom() ); - } + MavenProject selectedProject = projects.stream() + .filter( project -> isMatchingProject( project, selector, reactorDirectory ) ) + .findFirst() + .orElseThrow( () -> new MavenExecutionException( + "Could not find the selected project in the reactor: " + selector, request.getPom() ) ); + selectedProjects.add( selectedProject ); } - result.addAll( selectedProjects ); + result = new ArrayList<>( selectedProjects ); result = includeAlsoMakeTransitively( result, request, graph ); + + // Order the new list in the original order + List sortedProjects = graph.getSortedProjects(); + result.sort( comparing( sortedProjects::indexOf ) ); } return result; @@ -199,38 +187,20 @@ public class DefaultGraphBuilder if ( StringUtils.isNotEmpty( request.getResumeFrom() ) ) { - File reactorDirectory = null; - if ( request.getBaseDirectory() != null ) - { - reactorDirectory = new File( request.getBaseDirectory() ); - } + File reactorDirectory = getReactorDirectory( request ); String selector = request.getResumeFrom(); - result = new ArrayList<>( projects.size() ); + MavenProject resumingFromProject = projects.stream() + .filter( project -> isMatchingProject( project, selector, reactorDirectory ) ) + .findFirst() + .orElseThrow( () -> new MavenExecutionException( + "Could not find project to resume reactor build from: " + selector + " vs " + + formatProjects( projects ), request.getPom() ) ); + int resumeFromProjectIndex = projects.indexOf( resumingFromProject ); + List retainingProjects = result.subList( resumeFromProjectIndex, projects.size() ); - boolean resumed = false; - - for ( MavenProject project : projects ) - { - if ( !resumed && isMatchingProject( project, selector, reactorDirectory ) ) - { - resumed = true; - } - - if ( resumed ) - { - result.add( project ); - } - } - - if ( !resumed ) - { - throw new MavenExecutionException( "Could not find project to resume reactor build from: " + selector - + " vs " + formatProjects( projects ), request.getPom() ); - } - - result = includeAlsoMakeTransitively( result, request, graph ); + result = includeAlsoMakeTransitively( retainingProjects, request, graph ); } return result; @@ -243,46 +213,18 @@ public class DefaultGraphBuilder if ( !request.getExcludedProjects().isEmpty() ) { - File reactorDirectory = null; + File reactorDirectory = getReactorDirectory( request ); - if ( request.getBaseDirectory() != null ) - { - reactorDirectory = new File( request.getBaseDirectory() ); - } - - Collection excludedProjects = new LinkedHashSet<>( projects.size() ); + result = new ArrayList<>( projects ); for ( String selector : request.getExcludedProjects() ) { - MavenProject excludedProject = null; - - for ( MavenProject project : projects ) - { - if ( isMatchingProject( project, selector, reactorDirectory ) ) - { - excludedProject = project; - break; - } - } - - if ( excludedProject != null ) - { - excludedProjects.add( excludedProject ); - } - else - { - throw new MavenExecutionException( "Could not find the selected project in the reactor: " - + selector, request.getPom() ); - } - } - - result = new ArrayList<>( projects.size() ); - for ( MavenProject project : projects ) - { - if ( !excludedProjects.contains( project ) ) - { - result.add( project ); - } + MavenProject excludedProject = projects.stream() + .filter( project -> isMatchingProject( project, selector, reactorDirectory ) ) + .findFirst() + .orElseThrow( () -> new MavenExecutionException( "Could not find the selected project in " + + "the reactor: " + selector, request.getPom() ) ); + result.remove( excludedProject ); } } @@ -293,54 +235,41 @@ public class DefaultGraphBuilder ProjectDependencyGraph graph ) throws MavenExecutionException { - List result; + List result = projects; - boolean makeUpstream = false; - boolean makeDownstream = false; + String makeBehavior = request.getMakeBehavior(); + boolean makeBoth = MavenExecutionRequest.REACTOR_MAKE_BOTH.equals( makeBehavior ); - if ( MavenExecutionRequest.REACTOR_MAKE_UPSTREAM.equals( request.getMakeBehavior() ) ) + boolean makeUpstream = makeBoth || MavenExecutionRequest.REACTOR_MAKE_UPSTREAM.equals( makeBehavior ); + boolean makeDownstream = makeBoth || MavenExecutionRequest.REACTOR_MAKE_DOWNSTREAM.equals( makeBehavior ); + + if ( StringUtils.isNotEmpty( makeBehavior ) && !makeUpstream && !makeDownstream ) { - 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(), + throw new MavenExecutionException( "Invalid reactor make behavior: " + makeBehavior, request.getPom() ); } if ( makeUpstream || makeDownstream ) { + Set projectsSet = new HashSet<>( projects ); - for ( MavenProject project : new ArrayList<>( projects ) ) + for ( MavenProject project : projects ) { if ( makeUpstream ) { - projects.addAll( graph.getUpstreamProjects( project, true ) ); + projectsSet.addAll( graph.getUpstreamProjects( project, true ) ); } if ( makeDownstream ) { - projects.addAll( graph.getDownstreamProjects( project, true ) ); + projectsSet.addAll( graph.getDownstreamProjects( project, true ) ); } } - } - result = new ArrayList<>( projects.size() ); + result = new ArrayList<>( projectsSet ); - for ( MavenProject project : graph.getSortedProjects() ) - { - if ( projects.contains( project ) ) - { - result.add( project ); - } + // Order the new list in the original order + List sortedProjects = graph.getSortedProjects(); + result.sort( comparing( sortedProjects::indexOf ) ); } return result; @@ -412,6 +341,16 @@ public class DefaultGraphBuilder return false; } + private File getReactorDirectory( MavenExecutionRequest request ) + { + if ( request.getBaseDirectory() != null ) + { + return new File( request.getBaseDirectory() ); + } + + return null; + } + // //////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Project collection diff --git a/maven-core/src/test/java/org/apache/maven/graph/DefaultGraphBuilderTest.java b/maven-core/src/test/java/org/apache/maven/graph/DefaultGraphBuilderTest.java index 5fdd73e684..0c545a8312 100644 --- a/maven-core/src/test/java/org/apache/maven/graph/DefaultGraphBuilderTest.java +++ b/maven-core/src/test/java/org/apache/maven/graph/DefaultGraphBuilderTest.java @@ -140,9 +140,14 @@ public class DefaultGraphBuilderTest scenario( "Exclude the project we are resuming from (as proposed in MNG-6676)" ) .resumeFrom( MODULE_B ) .excludedProjects( singletonList( MODULE_B ) ) - .expectResult( singletonList( MODULE_C ) ) - - + .expectResult( singletonList( MODULE_C ) ), + scenario( "Selected projects in wrong order are resumed correctly in order" ) + .selectedProjects( asList( MODULE_C, MODULE_B, MODULE_A ) ) + .resumeFrom( MODULE_B ) + .expectResult( asList( MODULE_B, MODULE_C ) ), + scenario( "Duplicate projects are filtered out" ) + .selectedProjects( asList( MODULE_A, MODULE_A ) ) + .expectResult( singletonList( MODULE_A ) ) ); }