This is an automated email from the ASF dual-hosted git repository.

slachiewicz pushed a commit to branch maven-plugin-tools
in repository https://gitbox.apache.org/repos/asf/maven-invoker-plugin.git

commit 1c3ede303c30b9d258516e45dbc4089baba8fdda
Author: Slawomir Jaranowski <[email protected]>
AuthorDate: Thu Sep 16 19:19:51 2021 +0200

    [MINVOKER-271] fix detection of setup projects
    
    fix implementation according to documentations on params:
     - invokerTest
     - pomExcludes
     - setupIncludes
    
    Closes #68
---
 pom.xml                                            |  14 +-
 .../maven/plugins/invoker/AbstractInvokerMojo.java | 175 +++++++++------------
 src/main/mdo/invocation.mdo                        |  12 +-
 .../maven/plugins/invoker/InvokerMojoTest.java     | 114 ++++++++++++--
 .../maven/plugins/invoker/InvokerSessionTest.java  |   2 +-
 5 files changed, 189 insertions(+), 128 deletions(-)

diff --git a/pom.xml b/pom.xml
index a0ece81..866c7b4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -280,7 +280,19 @@ under the License.
       <version>${mavenVersion}</version>
       <scope>test</scope>
     </dependency>
-    
+    <dependency>
+      <groupId>org.assertj</groupId>
+      <artifactId>assertj-core</artifactId>
+      <version>3.20.2</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-simple</artifactId>
+      <version>1.7.32</version>
+      <scope>test</scope>
+    </dependency>
+
   </dependencies>
 
   <build>
diff --git 
a/src/main/java/org/apache/maven/plugins/invoker/AbstractInvokerMojo.java 
b/src/main/java/org/apache/maven/plugins/invoker/AbstractInvokerMojo.java
index 44d4a7e..fc2d7b8 100644
--- a/src/main/java/org/apache/maven/plugins/invoker/AbstractInvokerMojo.java
+++ b/src/main/java/org/apache/maven/plugins/invoker/AbstractInvokerMojo.java
@@ -89,6 +89,7 @@ import java.nio.file.Paths;
 import java.text.DecimalFormat;
 import java.text.DecimalFormatSymbols;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
@@ -741,7 +742,7 @@ public abstract class AbstractInvokerMojo
                     + "pom File parameter. Reason: " + e.getMessage(), e );
             }
 
-            buildJobs = Collections.singletonList( new BuildJob( 
pom.getName(), BuildJob.Type.NORMAL ) );
+            buildJobs = Collections.singletonList( new BuildJob( pom.getName() 
) );
         }
 
         if ( buildJobs.isEmpty() )
@@ -796,23 +797,13 @@ public abstract class AbstractInvokerMojo
         }
 
         // First run setup jobs.
-        List<BuildJob> setupBuildJobs = null;
-        try
-        {
-            setupBuildJobs = getSetupBuildJobsFromFolders();
-        }
-        catch ( IOException e )
-        {
-            getLog().error( "Failure during scanning of folders.", e );
-            // TODO: Check shouldn't we fail in case of problems?
-        }
+        List<BuildJob> setupBuildJobs = getSetupJobs( buildJobs );
 
         if ( !setupBuildJobs.isEmpty() )
         {
-            // Run setup jobs in single thread
-            // mode.
+            // Run setup jobs in single thread mode.
             //
-            // Some Idea about ordering?
+            // Jobs are ordered according to ordinal value from 
invoker.properties
             getLog().info( "Running " + setupBuildJobs.size() + " setup job"
                 + ( ( setupBuildJobs.size() < 2 ) ? "" : "s" ) + ":" );
             runBuilds( projectsDir, setupBuildJobs, 1 );
@@ -881,12 +872,18 @@ public abstract class AbstractInvokerMojo
         }
     }
 
+    private List<BuildJob> getSetupJobs( List<BuildJob> buildJobs )
+    {
+        return buildJobs.stream().
+                filter( buildJob -> buildJob.getType().equals( 
BuildJob.Type.SETUP ) ).
+                collect( Collectors.toList() );
+    }
+
     private List<BuildJob> getNonSetupJobs( List<BuildJob> buildJobs )
     {
         return buildJobs.stream().
                 filter( buildJob -> !buildJob.getType().equals( 
BuildJob.Type.SETUP ) ).
                 collect( Collectors.toList() );
-
     }
 
     private void handleScriptRunnerWithScriptClassPath()
@@ -2399,11 +2396,46 @@ public abstract class AbstractInvokerMojo
         }
     }
 
+    private List<String> calculateIncludes()
+    {
+        if ( invokerTest != null )
+        {
+            String[] testRegexes = StringUtils.split( invokerTest, "," );
+            return Arrays.stream( testRegexes )
+                    .map( String::trim )
+                    .filter( s -> !s.isEmpty() )
+                    .filter( s -> !s.startsWith( "!" ) )
+                    .collect( Collectors.toList() );
+        }
+        else
+        {
+            Set<String> uniqueIncludes = new HashSet<>();
+            uniqueIncludes.addAll( pomIncludes );
+            uniqueIncludes.addAll( setupIncludes );
+            return new ArrayList<>( uniqueIncludes );
+        }
+    }
+
     private List<String> calculateExcludes()
         throws IOException
     {
-        List<String> excludes =
-            ( pomExcludes != null ) ? new ArrayList<>( pomExcludes ) : new 
ArrayList<>();
+        List<String> excludes;
+
+        if ( invokerTest != null )
+        {
+            String[] testRegexes = StringUtils.split( invokerTest, "," );
+            excludes = Arrays.stream( testRegexes )
+                    .map( String::trim )
+                    .filter( s -> !s.isEmpty() )
+                    .filter( s -> s.startsWith( "!" ) )
+                    .map( s -> s.substring( 1 ) )
+                    .collect( Collectors.toList() );
+        }
+        else
+        {
+            excludes = pomExcludes != null ? new ArrayList<>( pomExcludes ) : 
new ArrayList<>();
+        }
+
         if ( this.settingsFile != null )
         {
             String exclude = relativizePath( this.settingsFile, 
projectsDirectory.getCanonicalPath() );
@@ -2417,25 +2449,6 @@ public abstract class AbstractInvokerMojo
 
     }
 
-    /**
-     * @return The list of setupUp jobs.
-     * @throws IOException
-     * @see {@link #setupIncludes}
-     */
-    private List<BuildJob> getSetupBuildJobsFromFolders()
-        throws IOException, MojoExecutionException
-    {
-        List<String> excludes = calculateExcludes();
-
-        List<BuildJob> setupPoms = scanProjectsDirectory( setupIncludes, 
excludes, BuildJob.Type.SETUP );
-        if ( getLog().isDebugEnabled() )
-        {
-            getLog().debug( "Setup projects: " + setupPoms );
-        }
-
-        return setupPoms;
-    }
-
     private static class OrdinalComparator implements Comparator<BuildJob>
     {
         private static final OrdinalComparator INSTANCE = new 
OrdinalComparator();
@@ -2456,62 +2469,35 @@ public abstract class AbstractInvokerMojo
     List<BuildJob> getBuildJobs()
         throws IOException, MojoExecutionException
     {
-        List<BuildJob> buildJobs;
 
-        if ( invokerTest == null )
-        {
-            List<String> excludes = calculateExcludes();
+        List<String> includes = calculateIncludes();
+        List<String> excludes = calculateExcludes();
+        List<BuildJob> buildJobsAll = scanProjectsDirectory( includes, 
excludes );
+        List<BuildJob> buildJobsSetup = scanProjectsDirectory( setupIncludes, 
excludes );
 
-            List<BuildJob> setupPoms = scanProjectsDirectory( setupIncludes, 
excludes, BuildJob.Type.SETUP );
-            if ( getLog().isDebugEnabled() )
-            {
-                getLog().debug( "Setup projects: " + 
Collections.singletonList( setupPoms ) );
-            }
+        List<String> setupProjects = buildJobsSetup.stream()
+                .map( BuildJob::getProject )
+                .collect( Collectors.toList() );
 
-            List<BuildJob> normalPoms = scanProjectsDirectory( pomIncludes, 
excludes, BuildJob.Type.NORMAL );
 
-            Map<String, BuildJob> uniquePoms = new LinkedHashMap<>();
-            for ( BuildJob setupPom : setupPoms )
-            {
-                uniquePoms.put( setupPom.getProject(), setupPom );
-            }
-            for ( BuildJob normalPom : normalPoms )
-            {
-                if ( !uniquePoms.containsKey( normalPom.getProject() ) )
-                {
-                    uniquePoms.put( normalPom.getProject(), normalPom );
-                }
-            }
-
-            buildJobs = new ArrayList<>( uniquePoms.values() );
-        }
-        else
+        for  ( BuildJob job : buildJobsAll )
         {
-            String[] testRegexes = StringUtils.split( invokerTest, "," );
-            List<String> includes = new ArrayList<>( testRegexes.length );
-            List<String> excludes = new ArrayList<>();
-
-            for ( String regex : testRegexes )
+            if ( setupProjects.contains( job.getProject() ) )
             {
-                // user just use -Dinvoker.test=MWAR191,MNG111 to use a 
directory thats the end is not pom.xml
-                if ( regex.startsWith( "!" ) )
-                {
-                    excludes.add( regex.substring( 1 ) );
-                }
-                else
-                {
-                    includes.add( regex );
-                }
+                job.setType( BuildJob.Type.SETUP );
             }
-
-            // it would be nice if we could figure out what types these are... 
but perhaps
-            // not necessary for the -Dinvoker.test=xxx t
-            buildJobs = scanProjectsDirectory( includes, excludes, 
BuildJob.Type.DIRECT );
+            InvokerProperties invokerProperties =
+                    getInvokerProperties( new File( projectsDirectory, 
job.getProject() ).getParentFile(),
+                            null );
+            job.setOrdinal( invokerProperties.getOrdinal() );
         }
 
-        relativizeProjectPaths( buildJobs );
+        // setup ordinal values to have an order here
+        buildJobsAll.sort( OrdinalComparator.INSTANCE );
+
+        relativizeProjectPaths( buildJobsAll );
 
-        return buildJobs;
+        return buildJobsAll;
     }
 
     /**
@@ -2522,12 +2508,11 @@ public abstract class AbstractInvokerMojo
      *
      * @param includes The include patterns for the scanner, may be 
<code>null</code>.
      * @param excludes The exclude patterns for the scanner, may be 
<code>null</code> to exclude nothing.
-     * @param type The type to assign to the resulting build jobs, must not be 
<code>null</code>.
      * @return The build jobs matching the patterns, never <code>null</code>.
      * @throws java.io.IOException If the project directory could not be 
scanned.
      */
-    private List<BuildJob> scanProjectsDirectory( List<String> includes, 
List<String> excludes, String type )
-        throws IOException, MojoExecutionException
+    private List<BuildJob> scanProjectsDirectory( List<String> includes, 
List<String> excludes )
+            throws IOException
     {
         if ( !projectsDirectory.isDirectory() )
         {
@@ -2552,7 +2537,7 @@ public abstract class AbstractInvokerMojo
 
         for ( String includedFile : scanner.getIncludedFiles() )
         {
-            matches.put( includedFile, new BuildJob( includedFile, type ) );
+            matches.put( includedFile, new BuildJob( includedFile ) );
         }
 
         for ( String includedDir : scanner.getIncludedDirectories() )
@@ -2560,27 +2545,15 @@ public abstract class AbstractInvokerMojo
             String includedFile = includedDir + File.separatorChar + "pom.xml";
             if ( new File( scanner.getBasedir(), includedFile ).isFile() )
             {
-                matches.put( includedFile, new BuildJob( includedFile, type ) 
);
+                matches.put( includedFile, new BuildJob( includedFile ) );
             }
             else
             {
-                matches.put( includedDir, new BuildJob( includedDir, type ) );
+                matches.put( includedDir, new BuildJob( includedDir ) );
             }
         }
 
-        List<BuildJob> projects = new ArrayList<>( matches.size() );
-
-        // setup ordinal values to have an order here
-        for ( BuildJob buildJob : matches.values() )
-        {
-            InvokerProperties invokerProperties =
-                    getInvokerProperties( new File( projectsDirectory, 
buildJob.getProject() ).getParentFile(),
-                            null );
-            buildJob.setOrdinal( invokerProperties.getOrdinal() );
-            projects.add( buildJob );
-        }
-        projects.sort( OrdinalComparator.INSTANCE );
-        return projects;
+        return new ArrayList<>( matches.values() );
     }
 
     /**
diff --git a/src/main/mdo/invocation.mdo b/src/main/mdo/invocation.mdo
index bc488f4..9abecec 100644
--- a/src/main/mdo/invocation.mdo
+++ b/src/main/mdo/invocation.mdo
@@ -95,6 +95,7 @@ under the License.
           <required>true</required>
           <type>String</type>
           <description>The type of the build job.</description>
+          <defaultValue>normal</defaultValue>
         </field>
         <field xml.attribute="true">
           <name>ordinal</name>
@@ -124,15 +125,13 @@ under the License.
     }
 
     /**
-     * Creates a new build job with the specified project path and type.
+     * Creates a new build job with the specified project path.
      * 
      * @param project The path to the project.
-     * @param type The type of the build job.
      */
-    public BuildJob( String project, String type )
+    public BuildJob( String project )
     {
         this.project = project;
-        this.type = type;
     }
           ]]></code>
         </codeSegment>
@@ -197,11 +196,6 @@ under the License.
          */
         public static final String NORMAL = "normal";
 
-        /**
-         * A build job that was directly selected via the 
<code>-Dinvoker.test=xxx,yyy</code> parameter.
-         */
-        public static final String DIRECT = "direct";
-
     }
           ]]></code>
         </codeSegment>
diff --git 
a/src/test/java/org/apache/maven/plugins/invoker/InvokerMojoTest.java 
b/src/test/java/org/apache/maven/plugins/invoker/InvokerMojoTest.java
index 1c22131..94f69f4 100644
--- a/src/test/java/org/apache/maven/plugins/invoker/InvokerMojoTest.java
+++ b/src/test/java/org/apache/maven/plugins/invoker/InvokerMojoTest.java
@@ -19,15 +19,17 @@ package org.apache.maven.plugins.invoker;
  * under the License.
  */
 
-import java.io.File;
-import java.util.Collections;
-import java.util.List;
+import static org.assertj.core.api.Assertions.assertThat;
 
 import org.apache.maven.plugin.testing.AbstractMojoTestCase;
 import org.apache.maven.plugins.invoker.model.BuildJob;
 import org.apache.maven.project.MavenProject;
 import org.apache.maven.settings.Settings;
 
+import java.io.File;
+import java.util.Collections;
+import java.util.List;
+
 /**
  * @author Olivier Lamy
  * @since 18 nov. 07
@@ -35,6 +37,11 @@ import org.apache.maven.settings.Settings;
 public class InvokerMojoTest extends AbstractMojoTestCase
 {
 
+    private static final String DUMMY_PROJECT = "dummy" + File.separator + 
"pom.xml";
+    private static final String GOALS_FROM_FILE_PROJECT = "goals-from-file" + 
File.separator + "pom.xml";
+    private static final String INTERPOLATION_PROJECT = "interpolation" + 
File.separator + "pom.xml";
+    private static final String PROFILES_FROM_FILE_PROJECT = 
"profiles-from-file";
+
     private MavenProject getMavenProject()
     {
         MavenProject mavenProject = new MavenProject();
@@ -44,47 +51,123 @@ public class InvokerMojoTest extends AbstractMojoTestCase
 
     public void testSingleInvokerTest() throws Exception
     {
+        // given
         InvokerMojo invokerMojo = new InvokerMojo();
         String dirPath = getBasedir() + "/src/test/resources/unit";
-        List<String> goals = invokerMojo.getGoals( new File( dirPath ) );
-        assertEquals( 1, goals.size() );
         setVariableValueToObject( invokerMojo, "projectsDirectory", new File( 
dirPath ) );
         setVariableValueToObject( invokerMojo, "invokerPropertiesFile", 
"invoker.properties" );
         setVariableValueToObject( invokerMojo, "project", getMavenProject() );
         setVariableValueToObject( invokerMojo, "invokerTest", "*dummy*" );
         setVariableValueToObject( invokerMojo, "settings", new Settings() );
-        List<BuildJob> poms = invokerMojo.getBuildJobs();
-        assertEquals( 1, poms.size() );
+
+        // when
+        List<BuildJob> jobs = invokerMojo.getBuildJobs();
+
+        // then
+        assertThat( jobs )
+                .map( BuildJob::getProject )
+                .containsExactlyInAnyOrder( DUMMY_PROJECT );
     }
 
     public void testMultiInvokerTest() throws Exception
     {
+        // given
         InvokerMojo invokerMojo = new InvokerMojo();
         String dirPath = getBasedir() + "/src/test/resources/unit";
-        List<String> goals = invokerMojo.getGoals( new File( dirPath ) );
-        assertEquals( 1, goals.size() );
         setVariableValueToObject( invokerMojo, "projectsDirectory", new File( 
dirPath ) );
         setVariableValueToObject( invokerMojo, "invokerPropertiesFile", 
"invoker.properties" );
         setVariableValueToObject( invokerMojo, "project", getMavenProject() );
         setVariableValueToObject( invokerMojo, "invokerTest", 
"*dummy*,*terpolatio*" );
         setVariableValueToObject( invokerMojo, "settings", new Settings() );
-        List<BuildJob> poms = invokerMojo.getBuildJobs();
-        assertEquals( 2, poms.size() );
+
+        // when
+        List<BuildJob> jobs = invokerMojo.getBuildJobs();
+
+        // then
+        assertThat( jobs )
+                .map( BuildJob::getProject )
+                .containsExactlyInAnyOrder( DUMMY_PROJECT, 
INTERPOLATION_PROJECT );
     }
 
     public void testFullPatternInvokerTest() throws Exception
     {
+        // given
         InvokerMojo invokerMojo = new InvokerMojo();
         String dirPath = getBasedir() + "/src/test/resources/unit";
-        List<String> goals = invokerMojo.getGoals( new File( dirPath ) );
-        assertEquals( 1, goals.size() );
         setVariableValueToObject( invokerMojo, "projectsDirectory", new File( 
dirPath ) );
         setVariableValueToObject( invokerMojo, "invokerPropertiesFile", 
"invoker.properties" );
         setVariableValueToObject( invokerMojo, "project", getMavenProject() );
         setVariableValueToObject( invokerMojo, "invokerTest", "*" );
         setVariableValueToObject( invokerMojo, "settings", new Settings() );
-        List<BuildJob> poms = invokerMojo.getBuildJobs();
-        assertEquals( 4, poms.size() );
+
+        // when
+        List<BuildJob> jobs = invokerMojo.getBuildJobs();
+
+        // then
+        assertThat( jobs )
+                .map( BuildJob::getProject )
+                .containsExactlyInAnyOrder(
+                        DUMMY_PROJECT, GOALS_FROM_FILE_PROJECT,
+                        INTERPOLATION_PROJECT, PROFILES_FROM_FILE_PROJECT );
+    }
+
+    public void testSetupInProjectList() throws Exception
+    {
+        // given
+        InvokerMojo invokerMojo = new InvokerMojo();
+        String dirPath = getBasedir() + "/src/test/resources/unit";
+        setVariableValueToObject( invokerMojo, "projectsDirectory", new File( 
dirPath ) );
+        setVariableValueToObject( invokerMojo, "invokerPropertiesFile", 
"invoker.properties" );
+        setVariableValueToObject( invokerMojo, "project", getMavenProject() );
+        setVariableValueToObject( invokerMojo, "settings", new Settings() );
+        setVariableValueToObject( invokerMojo, "setupIncludes", 
Collections.singletonList( "dum*/pom.xml" ) );
+
+        // when
+        List<BuildJob> jobs = invokerMojo.getBuildJobs();
+
+        // then
+
+        // we have all projects with pom.xml
+        assertThat( jobs )
+                .map( BuildJob::getProject )
+                .containsExactlyInAnyOrder(
+                        DUMMY_PROJECT, GOALS_FROM_FILE_PROJECT, 
INTERPOLATION_PROJECT );
+
+        // and we have one setup project
+        assertThat( jobs )
+                .filteredOn( job -> BuildJob.Type.SETUP.equals( job.getType() 
) )
+                .map( BuildJob::getProject )
+                .containsExactlyInAnyOrder(  DUMMY_PROJECT );
+    }
+
+    public void testSetupProjectIsFiltered() throws Exception
+    {
+        // given
+        InvokerMojo invokerMojo = new InvokerMojo();
+        String dirPath = getBasedir() + "/src/test/resources/unit";
+        setVariableValueToObject( invokerMojo, "projectsDirectory", new File( 
dirPath ) );
+        setVariableValueToObject( invokerMojo, "invokerPropertiesFile", 
"invoker.properties" );
+        setVariableValueToObject( invokerMojo, "project", getMavenProject() );
+        setVariableValueToObject( invokerMojo, "settings", new Settings() );
+        setVariableValueToObject( invokerMojo, "setupIncludes", 
Collections.singletonList( "dum*/pom.xml" ) );
+        setVariableValueToObject( invokerMojo, "invokerTest", "*from-file*" );
+
+
+        // when
+        List<BuildJob> jobs = invokerMojo.getBuildJobs();
+
+        // then
+
+        // we have filtered projects
+        assertThat( jobs )
+                .map( BuildJob::getProject )
+                .containsExactlyInAnyOrder(
+                        GOALS_FROM_FILE_PROJECT, PROFILES_FROM_FILE_PROJECT );
+
+        // and we don't have a setup project
+        assertThat( jobs )
+                .filteredOn( job -> BuildJob.Type.SETUP.equals( job.getType() 
) )
+                .isEmpty();
     }
 
     public void testAlreadyCloned()
@@ -116,5 +199,4 @@ public class InvokerMojoTest extends AbstractMojoTestCase
             assertEquals( expectedParallelThreads, 
invokerMojo.getParallelThreadsCount() );
         }
     }
-
 }
diff --git 
a/src/test/java/org/apache/maven/plugins/invoker/InvokerSessionTest.java 
b/src/test/java/org/apache/maven/plugins/invoker/InvokerSessionTest.java
index bd5c029..8960670 100644
--- a/src/test/java/org/apache/maven/plugins/invoker/InvokerSessionTest.java
+++ b/src/test/java/org/apache/maven/plugins/invoker/InvokerSessionTest.java
@@ -40,7 +40,7 @@ public class InvokerSessionTest
     public void skipSummary()
     {
         Log logger = mock( Log.class );
-        BuildJob skippedBuildJob = new BuildJob( "minvoker-279", null );
+        BuildJob skippedBuildJob = new BuildJob( "minvoker-279" );
         skippedBuildJob.setResult( BuildJob.Result.SKIPPED );
         InvokerSession session = new InvokerSession( 
Collections.singletonList( skippedBuildJob ) );
 

Reply via email to