You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by sl...@apache.org on 2021/12/01 00:11:29 UTC
[maven-invoker-plugin] 01/04: [MINVOKER-271] fix detection of setup projects
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 <s....@gmail.com>
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 ) );