You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by rf...@apache.org on 2020/06/20 09:33:42 UTC
[maven] 29/31: Split off BuildResumptionAnalyzer from
BuildResumptionDataRepository
This is an automated email from the ASF dual-hosted git repository.
rfscholte pushed a commit to branch MNG-5760
in repository https://gitbox.apache.org/repos/asf/maven.git
commit 6faa4cd12a2b2478c63e88d34a62637c7f75e653
Author: Maarten Mulders <ma...@infosupport.com>
AuthorDate: Wed Jun 17 20:24:28 2020 +0200
Split off BuildResumptionAnalyzer from BuildResumptionDataRepository
---
.../main/java/org/apache/maven/DefaultMaven.java | 32 ++--
.../maven/execution/BuildResumptionAnalyzer.java | 36 ++++
.../maven/execution/BuildResumptionData.java | 55 ++++++
.../execution/BuildResumptionDataRepository.java | 4 +-
.../execution/DefaultBuildResumptionAnalyzer.java | 162 ++++++++++++++++++
.../DefaultBuildResumptionDataRepository.java | 190 +++------------------
.../DefaultBuildResumptionAnalyzerTest.java | 150 ++++++++++++++++
.../DefaultBuildResumptionDataRepositoryTest.java | 132 +-------------
8 files changed, 453 insertions(+), 308 deletions(-)
diff --git a/maven-core/src/main/java/org/apache/maven/DefaultMaven.java b/maven-core/src/main/java/org/apache/maven/DefaultMaven.java
index ad5aad7..167cb7b 100644
--- a/maven-core/src/main/java/org/apache/maven/DefaultMaven.java
+++ b/maven-core/src/main/java/org/apache/maven/DefaultMaven.java
@@ -36,6 +36,7 @@ import javax.inject.Named;
import javax.inject.Singleton;
import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.execution.BuildResumptionAnalyzer;
import org.apache.maven.execution.BuildResumptionDataRepository;
import org.apache.maven.execution.BuildResumptionPersistenceException;
import org.apache.maven.execution.DefaultMavenExecutionResult;
@@ -103,6 +104,9 @@ public class DefaultMaven
private GraphBuilder graphBuilder;
@Inject
+ private BuildResumptionAnalyzer buildResumptionAnalyzer;
+
+ @Inject
private BuildResumptionDataRepository buildResumptionDataRepository;
@Override
@@ -371,21 +375,23 @@ public class DefaultMaven
if ( hasLifecycleExecutionExceptions )
{
- session.getAllProjects().stream()
+ MavenProject rootProject = session.getAllProjects().stream()
.filter( MavenProject::isExecutionRoot )
.findFirst()
- .ifPresent( rootProject ->
- {
- try
- {
- boolean persistenceResult = buildResumptionDataRepository.persistResumptionData( result, rootProject );
- result.setCanResume( persistenceResult );
- }
- catch ( BuildResumptionPersistenceException e )
- {
- logger.warn( "Could not persist build resumption data", e );
- }
- } );
+ .orElseThrow( () -> new IllegalStateException( "No project in the session is execution root" ) );
+
+ buildResumptionAnalyzer.determineBuildResumptionData( result ).ifPresent( resumption ->
+ {
+ try
+ {
+ boolean canResume = buildResumptionDataRepository.persistResumptionData( rootProject, resumption );
+ result.setCanResume( canResume );
+ }
+ catch ( BuildResumptionPersistenceException e )
+ {
+ logger.warn( "Could not persist build resumption data", e );
+ }
+ } );
}
}
diff --git a/maven-core/src/main/java/org/apache/maven/execution/BuildResumptionAnalyzer.java b/maven-core/src/main/java/org/apache/maven/execution/BuildResumptionAnalyzer.java
new file mode 100644
index 0000000..1778946
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/execution/BuildResumptionAnalyzer.java
@@ -0,0 +1,36 @@
+package org.apache.maven.execution;
+
+/*
+ * 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.Optional;
+
+/**
+ * Instances of this class are responsible for determining whether it makes sense to "resume" a build (i.e., using
+ * the {@code --resume} flag.
+ */
+public interface BuildResumptionAnalyzer
+{
+ /**
+ * Construct an instance of {@link BuildResumptionData} based on the outcome of the current Maven build.
+ * @param result Outcome of the current Maven build.
+ * @return A {@link BuildResumptionData} instance or {@link Optional#empty()} if resuming the build is not possible.
+ */
+ Optional<BuildResumptionData> determineBuildResumptionData( final MavenExecutionResult result );
+}
diff --git a/maven-core/src/main/java/org/apache/maven/execution/BuildResumptionData.java b/maven-core/src/main/java/org/apache/maven/execution/BuildResumptionData.java
new file mode 100644
index 0000000..9330929
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/execution/BuildResumptionData.java
@@ -0,0 +1,55 @@
+package org.apache.maven.execution;
+
+/*
+ * 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.Collections;
+import java.util.List;
+
+/**
+ * This class holds the information required to enable resuming a Maven build with {@code --resume}.
+ */
+public class BuildResumptionData
+{
+ /**
+ * The project where the next build could resume from.
+ */
+ private final String resumeFrom;
+
+ /**
+ * List of projects to skip if the build would be resumed from {@link #resumeFrom}.
+ */
+ private final List<String> projectsToSkip;
+
+ public BuildResumptionData ( final String resumeFrom, final List<String> projectsToSkip )
+ {
+ this.resumeFrom = resumeFrom;
+ this.projectsToSkip = projectsToSkip;
+ }
+
+ public String getResumeFrom()
+ {
+ return this.resumeFrom;
+ }
+
+ public List<String> getProjectsToSkip()
+ {
+ return this.projectsToSkip;
+ }
+}
diff --git a/maven-core/src/main/java/org/apache/maven/execution/BuildResumptionDataRepository.java b/maven-core/src/main/java/org/apache/maven/execution/BuildResumptionDataRepository.java
index 8733819..b8a3b22 100644
--- a/maven-core/src/main/java/org/apache/maven/execution/BuildResumptionDataRepository.java
+++ b/maven-core/src/main/java/org/apache/maven/execution/BuildResumptionDataRepository.java
@@ -33,12 +33,12 @@ public interface BuildResumptionDataRepository
* may also decide it is not needed or meaningful to persist such data, and return <code>false</code> to indicate
* so.
*
- * @param result The result of the current Maven invocation.
* @param rootProject The root project that is being built.
+ * @param buildResumptionData Information needed to resume the build.
* @throws BuildResumptionPersistenceException When an error occurs while persisting data.
* @return Whether any data was persisted.
*/
- boolean persistResumptionData( final MavenExecutionResult result, final MavenProject rootProject )
+ boolean persistResumptionData( final MavenProject rootProject, final BuildResumptionData buildResumptionData )
throws BuildResumptionPersistenceException;
/**
diff --git a/maven-core/src/main/java/org/apache/maven/execution/DefaultBuildResumptionAnalyzer.java b/maven-core/src/main/java/org/apache/maven/execution/DefaultBuildResumptionAnalyzer.java
new file mode 100644
index 0000000..3d100dc
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/execution/DefaultBuildResumptionAnalyzer.java
@@ -0,0 +1,162 @@
+package org.apache.maven.execution;
+
+/*
+ * 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 org.apache.maven.lifecycle.LifecycleExecutionException;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.project.MavenProject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import static java.util.Comparator.comparing;
+
+/**
+ * Default implementation of {@link BuildResumptionAnalyzer}.
+ */
+@Named
+@Singleton
+public class DefaultBuildResumptionAnalyzer implements BuildResumptionAnalyzer
+{
+ private static final Logger LOGGER = LoggerFactory.getLogger( DefaultBuildResumptionAnalyzer.class );
+
+ @Override
+ public Optional<BuildResumptionData> determineBuildResumptionData( final MavenExecutionResult result )
+ {
+ final List<MavenProject> failedProjects = getFailedProjectsInOrder( result );
+
+ if ( failedProjects.isEmpty() )
+ {
+ LOGGER.info( "No failed projects found, resuming the build would not make sense." );
+ return Optional.empty();
+ }
+
+ final MavenProject resumeFromProject = failedProjects.get( 0 );
+
+ if ( isFailedProjectFirstInBuild( result, resumeFromProject ) )
+ {
+ LOGGER.info( "The first module in the build failed, resuming the build would not make sense." );
+ return Optional.empty();
+ }
+
+ final String resumeFromSelector = resumeFromProject.getGroupId() + ":" + resumeFromProject.getArtifactId();
+ final List<String> projectsToSkip = determineProjectsToSkip( result, failedProjects, resumeFromProject );
+
+ return Optional.of( new BuildResumptionData( resumeFromSelector, projectsToSkip ) );
+ }
+
+ private boolean isFailedProjectFirstInBuild( final MavenExecutionResult result, final MavenProject failedProject )
+ {
+ final List<MavenProject> sortedProjects = result.getTopologicallySortedProjects();
+ return sortedProjects.indexOf( failedProject ) == 0;
+ }
+
+ private List<MavenProject> getFailedProjectsInOrder( MavenExecutionResult result )
+ {
+ List<MavenProject> sortedProjects = result.getTopologicallySortedProjects();
+
+ return result.getExceptions().stream()
+ .filter( LifecycleExecutionException.class::isInstance )
+ .map( LifecycleExecutionException.class::cast )
+ .map( LifecycleExecutionException::getProject )
+ .sorted( comparing( sortedProjects::indexOf ) )
+ .collect( Collectors.toList() );
+ }
+
+ /**
+ * Projects after the first failed project could have succeeded by using -T or --fail-at-end.
+ * These projects can be skipped from later builds.
+ * This is not the case these projects are dependent on one of the failed projects.
+ * @param result The result of the Maven build.
+ * @param failedProjects The list of failed projects in the build.
+ * @param resumeFromProject The project where the build will be resumed with in the next run.
+ * @return A list of projects which can be skipped in a later build.
+ */
+ private List<String> determineProjectsToSkip( MavenExecutionResult result,
+ List<MavenProject> failedProjects,
+ MavenProject resumeFromProject )
+ {
+ List<MavenProject> allProjects = result.getTopologicallySortedProjects();
+ int resumeFromProjectIndex = allProjects.indexOf( resumeFromProject );
+ List<MavenProject> remainingProjects = allProjects.subList( resumeFromProjectIndex + 1, allProjects.size() );
+
+ List<GroupArtifactPair> failedProjectsGAList = failedProjects.stream()
+ .map( GroupArtifactPair::new )
+ .collect( Collectors.toList() );
+
+ return remainingProjects.stream()
+ .filter( project -> result.getBuildSummary( project ) instanceof BuildSuccess )
+ .filter( project -> hasNoDependencyOnProjects( project, failedProjectsGAList ) )
+ .map( project -> project.getGroupId() + ":" + project.getArtifactId() )
+ .collect( Collectors.toList() );
+ }
+
+ private boolean hasNoDependencyOnProjects( MavenProject project, List<GroupArtifactPair> projectsGAs )
+ {
+ return project.getDependencies().stream()
+ .map( GroupArtifactPair::new )
+ .noneMatch( projectsGAs::contains );
+ }
+
+ private static class GroupArtifactPair
+ {
+ private final String groupId;
+ private final String artifactId;
+
+ GroupArtifactPair( MavenProject project )
+ {
+ this.groupId = project.getGroupId();
+ this.artifactId = project.getArtifactId();
+ }
+
+ GroupArtifactPair( Dependency dependency )
+ {
+ this.groupId = dependency.getGroupId();
+ this.artifactId = dependency.getArtifactId();
+ }
+
+ @Override
+ public boolean equals( Object o )
+ {
+ if ( this == o )
+ {
+ return true;
+ }
+ if ( o == null || getClass() != o.getClass() )
+ {
+ return false;
+ }
+ GroupArtifactPair that = (GroupArtifactPair) o;
+ return Objects.equals( groupId, that.groupId ) && Objects.equals( artifactId, that.artifactId );
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return Objects.hash( groupId, artifactId );
+ }
+ }
+}
diff --git a/maven-core/src/main/java/org/apache/maven/execution/DefaultBuildResumptionDataRepository.java b/maven-core/src/main/java/org/apache/maven/execution/DefaultBuildResumptionDataRepository.java
index 7e647d7..e7965b3 100644
--- a/maven-core/src/main/java/org/apache/maven/execution/DefaultBuildResumptionDataRepository.java
+++ b/maven-core/src/main/java/org/apache/maven/execution/DefaultBuildResumptionDataRepository.java
@@ -20,8 +20,6 @@ package org.apache.maven.execution;
*/
import org.apache.commons.lang3.StringUtils;
-import org.apache.maven.lifecycle.LifecycleExecutionException;
-import org.apache.maven.model.Dependency;
import org.apache.maven.project.MavenProject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -35,17 +33,11 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-import java.util.Optional;
import java.util.Properties;
-import java.util.stream.Collectors;
-
-import static java.util.Comparator.comparing;
/**
- * This implementation of {@link BuildResumptionDataRepository} persists information in a properties file. The file is stored
- * in the build output directory under the Maven execution root.
+ * This implementation of {@link BuildResumptionDataRepository} persists information in a properties file. The file is
+ * stored in the build output directory under the Maven execution root.
*/
@Named
@Singleton
@@ -58,151 +50,58 @@ public class DefaultBuildResumptionDataRepository implements BuildResumptionData
private static final Logger LOGGER = LoggerFactory.getLogger( DefaultBuildResumptionDataRepository.class );
@Override
- public boolean persistResumptionData( MavenExecutionResult result, MavenProject rootProject )
+ public boolean persistResumptionData( MavenProject rootProject, BuildResumptionData buildResumptionData )
throws BuildResumptionPersistenceException
{
- Properties properties = determineResumptionProperties( result );
-
- if ( properties.isEmpty() )
- {
- LOGGER.debug( "Will not create {} file: nothing to resume from", RESUME_PROPERTIES_FILENAME );
- return false;
- }
-
- return writeResumptionFile( rootProject, properties );
- }
-
- @Override
- public void applyResumptionData( MavenExecutionRequest request, MavenProject rootProject )
- {
- Properties properties = loadResumptionFile( Paths.get( rootProject.getBuild().getDirectory() ) );
- applyResumptionProperties( request, properties );
- }
+ Properties properties = convertToProperties( buildResumptionData );
- @Override
- public void removeResumptionData( MavenProject rootProject )
- {
Path resumeProperties = Paths.get( rootProject.getBuild().getDirectory(), RESUME_PROPERTIES_FILENAME );
try
{
- Files.deleteIfExists( resumeProperties );
+ Files.createDirectories( resumeProperties.getParent() );
+ try ( Writer writer = Files.newBufferedWriter( resumeProperties ) )
+ {
+ properties.store( writer, null );
+ }
}
catch ( IOException e )
{
- LOGGER.warn( "Could not delete {} file. ", RESUME_PROPERTIES_FILENAME, e );
+ String message = "Could not create " + RESUME_PROPERTIES_FILENAME + " file.";
+ throw new BuildResumptionPersistenceException( message, e );
}
+
+ return true;
}
- // This method is made package-private for testing purposes
- Properties determineResumptionProperties( MavenExecutionResult result )
+ private Properties convertToProperties( final BuildResumptionData buildResumptionData )
{
Properties properties = new Properties();
-
- List<MavenProject> failedProjects = getFailedProjectsInOrder( result );
- if ( !failedProjects.isEmpty() )
- {
- MavenProject resumeFromProject = failedProjects.get( 0 );
- Optional<String> resumeFrom = getResumeFrom( result, resumeFromProject );
- List<String> projectsToSkip = determineProjectsToSkip( result, failedProjects, resumeFromProject );
-
- resumeFrom.ifPresent( value -> properties.setProperty( RESUME_FROM_PROPERTY, value ) );
- if ( !projectsToSkip.isEmpty() ) {
- String excludedProjects = String.join( PROPERTY_DELIMITER, projectsToSkip );
- properties.setProperty( EXCLUDED_PROJECTS_PROPERTY, excludedProjects );
- }
- }
- else
- {
- LOGGER.warn( "Could not create {} file: no failed projects found", RESUME_PROPERTIES_FILENAME );
- }
+ properties.setProperty( RESUME_FROM_PROPERTY, buildResumptionData.getResumeFrom() );
+ String excludedProjects = String.join( PROPERTY_DELIMITER, buildResumptionData.getProjectsToSkip() );
+ properties.setProperty( EXCLUDED_PROJECTS_PROPERTY, excludedProjects );
return properties;
}
- private List<MavenProject> getFailedProjectsInOrder( MavenExecutionResult result )
- {
- List<MavenProject> sortedProjects = result.getTopologicallySortedProjects();
-
- return result.getExceptions().stream()
- .filter( LifecycleExecutionException.class::isInstance )
- .map( LifecycleExecutionException.class::cast )
- .map( LifecycleExecutionException::getProject )
- .sorted( comparing( sortedProjects::indexOf ) )
- .collect( Collectors.toList() );
- }
-
- /**
- * Determine the project where the next build can be resumed from.
- * If the failed project is the first project of the build,
- * it does not make sense to use --resume-from, so the result will be empty.
- * @param result The result of the Maven build.
- * @param failedProject The first failed project of the build.
- * @return An optional containing the resume-from suggestion.
- */
- private Optional<String> getResumeFrom( MavenExecutionResult result, MavenProject failedProject )
- {
- List<MavenProject> allSortedProjects = result.getTopologicallySortedProjects();
- if ( !allSortedProjects.get( 0 ).equals( failedProject ) )
- {
- return Optional.of( failedProject.getGroupId() + ":" + failedProject.getArtifactId() );
- }
-
- return Optional.empty();
- }
-
- /**
- * Projects after the first failed project could have succeeded by using -T or --fail-at-end.
- * These projects can be skipped from later builds.
- * This is not the case these projects are dependent on one of the failed projects.
- * @param result The result of the Maven build.
- * @param failedProjects The list of failed projects in the build.
- * @param resumeFromProject The project where the build will be resumed with in the next run.
- * @return A list of projects which can be skipped in a later build.
- */
- private List<String> determineProjectsToSkip( MavenExecutionResult result, List<MavenProject> failedProjects,
- MavenProject resumeFromProject )
- {
- List<MavenProject> allProjects = result.getTopologicallySortedProjects();
- int resumeFromProjectIndex = allProjects.indexOf( resumeFromProject );
- List<MavenProject> remainingProjects = allProjects.subList( resumeFromProjectIndex + 1, allProjects.size() );
-
- List<GroupArtifactPair> failedProjectsGAList = failedProjects.stream()
- .map( GroupArtifactPair::new )
- .collect( Collectors.toList() );
-
- return remainingProjects.stream()
- .filter( project -> result.getBuildSummary( project ) instanceof BuildSuccess )
- .filter( project -> hasNoDependencyOnProjects( project, failedProjectsGAList ) )
- .map( project -> project.getGroupId() + ":" + project.getArtifactId() )
- .collect( Collectors.toList() );
- }
-
- private boolean hasNoDependencyOnProjects( MavenProject project, List<GroupArtifactPair> projectsGAs )
+ @Override
+ public void applyResumptionData( MavenExecutionRequest request, MavenProject rootProject )
{
- return project.getDependencies().stream()
- .map( GroupArtifactPair::new )
- .noneMatch( projectsGAs::contains );
+ Properties properties = loadResumptionFile( Paths.get( rootProject.getBuild().getDirectory() ) );
+ applyResumptionProperties( request, properties );
}
- private boolean writeResumptionFile( MavenProject rootProject, Properties properties )
- throws BuildResumptionPersistenceException
+ @Override
+ public void removeResumptionData( MavenProject rootProject )
{
Path resumeProperties = Paths.get( rootProject.getBuild().getDirectory(), RESUME_PROPERTIES_FILENAME );
try
{
- Files.createDirectories( resumeProperties.getParent() );
- try ( Writer writer = Files.newBufferedWriter( resumeProperties ) )
- {
- properties.store( writer, null );
- }
+ Files.deleteIfExists( resumeProperties );
}
catch ( IOException e )
{
- String message = "Could not create " + RESUME_PROPERTIES_FILENAME + " file.";
- throw new BuildResumptionPersistenceException( message, e );
+ LOGGER.warn( "Could not delete {} file. ", RESUME_PROPERTIES_FILENAME, e );
}
-
- return true;
}
private Properties loadResumptionFile( Path rootBuildDirectory )
@@ -245,43 +144,4 @@ public class DefaultBuildResumptionDataRepository implements BuildResumptionData
LOGGER.info( "Additionally excluding projects '{}' due to the --resume / -r feature.", propertyValue );
}
}
-
- private static class GroupArtifactPair
- {
- private final String groupId;
- private final String artifactId;
-
- GroupArtifactPair( MavenProject project )
- {
- this.groupId = project.getGroupId();
- this.artifactId = project.getArtifactId();
- }
-
- GroupArtifactPair( Dependency dependency )
- {
- this.groupId = dependency.getGroupId();
- this.artifactId = dependency.getArtifactId();
- }
-
- @Override
- public boolean equals( Object o )
- {
- if ( this == o )
- {
- return true;
- }
- if ( o == null || getClass() != o.getClass() )
- {
- return false;
- }
- GroupArtifactPair that = (GroupArtifactPair) o;
- return Objects.equals( groupId, that.groupId ) && Objects.equals( artifactId, that.artifactId );
- }
-
- @Override
- public int hashCode()
- {
- return Objects.hash( groupId, artifactId );
- }
- }
}
diff --git a/maven-core/src/test/java/org/apache/maven/execution/DefaultBuildResumptionAnalyzerTest.java b/maven-core/src/test/java/org/apache/maven/execution/DefaultBuildResumptionAnalyzerTest.java
new file mode 100644
index 0000000..59a8e63
--- /dev/null
+++ b/maven-core/src/test/java/org/apache/maven/execution/DefaultBuildResumptionAnalyzerTest.java
@@ -0,0 +1,150 @@
+package org.apache.maven.execution;
+
+/*
+ * 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 org.apache.maven.lifecycle.LifecycleExecutionException;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.project.MavenProject;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Optional;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.is;
+
+public class DefaultBuildResumptionAnalyzerTest
+{
+ private final DefaultBuildResumptionAnalyzer analyzer = new DefaultBuildResumptionAnalyzer();
+
+ private MavenExecutionResult executionResult;
+
+ @Before
+ public void before() {
+ executionResult = new DefaultMavenExecutionResult();
+ }
+
+ @Test
+ public void resumeFromGetsDetermined()
+ {
+ MavenProject projectA = createSucceededMavenProject( "A" );
+ MavenProject projectB = createFailedMavenProject( "B" );
+ executionResult.setTopologicallySortedProjects( asList( projectA, projectB ) );
+
+ Optional<BuildResumptionData> result = analyzer.determineBuildResumptionData( executionResult );
+
+ assertThat( result.isPresent(), is( true ) );
+ assertThat( result.get().getResumeFrom(), is( "test:B" ) );
+ }
+
+ @Test
+ public void resumeFromIsIgnoredWhenFirstProjectFails()
+ {
+ MavenProject projectA = createFailedMavenProject( "A" );
+ MavenProject projectB = createMavenProject( "B" );
+ executionResult.setTopologicallySortedProjects( asList( projectA, projectB ) );
+
+ Optional<BuildResumptionData> result = analyzer.determineBuildResumptionData( executionResult );
+
+ assertThat( result.isPresent(), is( false ) );
+ }
+
+ @Test
+ public void projectsSucceedingAfterFailedProjectsAreExcluded()
+ {
+ MavenProject projectA = createSucceededMavenProject( "A" );
+ MavenProject projectB = createFailedMavenProject( "B" );
+ MavenProject projectC = createSucceededMavenProject( "C" );
+ executionResult.setTopologicallySortedProjects( asList( projectA, projectB, projectC ) );
+
+ Optional<BuildResumptionData> result = analyzer.determineBuildResumptionData( executionResult );
+
+ assertThat( result.isPresent(), is( true ) );
+ assertThat( result.get().getProjectsToSkip(), contains( "test:C" ) );
+ }
+
+ @Test
+ public void projectsDependingOnFailedProjectsAreNotExcluded()
+ {
+ MavenProject projectA = createSucceededMavenProject( "A" );
+ MavenProject projectB = createFailedMavenProject( "B" );
+ MavenProject projectC = createSucceededMavenProject( "C" );
+ projectC.setDependencies( singletonList( toDependency( projectB ) ) );
+ executionResult.setTopologicallySortedProjects( asList( projectA, projectB, projectC ) );
+
+ Optional<BuildResumptionData> result = analyzer.determineBuildResumptionData( executionResult );
+
+ assertThat( result.isPresent(), is( true ) );
+ assertThat( result.get().getProjectsToSkip().isEmpty(), is( true ) );
+ }
+
+ @Test
+ public void projectsFailingAfterAnotherFailedProjectAreNotExcluded()
+ {
+ MavenProject projectA = createSucceededMavenProject( "A" );
+ MavenProject projectB = createFailedMavenProject( "B" );
+ MavenProject projectC = createSucceededMavenProject( "C" );
+ MavenProject projectD = createFailedMavenProject( "D" );
+ executionResult.setTopologicallySortedProjects( asList( projectA, projectB, projectC, projectD ) );
+
+ Optional<BuildResumptionData> result = analyzer.determineBuildResumptionData( executionResult );
+
+ assertThat( result.isPresent(), is( true ) );
+ assertThat( result.get().getResumeFrom(), is( "test:B" ) );
+ assertThat( result.get().getProjectsToSkip(), contains( "test:C" ) );
+ assertThat( result.get().getProjectsToSkip(), not( contains( "test:D" ) ) );
+ }
+
+ private MavenProject createMavenProject( String artifactId )
+ {
+ MavenProject project = new MavenProject();
+ project.setGroupId( "test" );
+ project.setArtifactId( artifactId );
+ return project;
+ }
+
+ private Dependency toDependency(MavenProject mavenProject )
+ {
+ Dependency dependency = new Dependency();
+ dependency.setGroupId( mavenProject.getGroupId() );
+ dependency.setArtifactId( mavenProject.getArtifactId() );
+ dependency.setVersion( mavenProject.getVersion() );
+ return dependency;
+ }
+
+ private MavenProject createSucceededMavenProject( String artifactId )
+ {
+ MavenProject project = createMavenProject( artifactId );
+ executionResult.addBuildSummary( new BuildSuccess( project, 0 ) );
+ return project;
+ }
+
+ private MavenProject createFailedMavenProject( String artifactId )
+ {
+ MavenProject project = createMavenProject( artifactId );
+ executionResult.addBuildSummary( new BuildFailure( project, 0, new Exception() ) );
+ executionResult.addException( new LifecycleExecutionException( "", project ) );
+ return project;
+ }
+}
\ No newline at end of file
diff --git a/maven-core/src/test/java/org/apache/maven/execution/DefaultBuildResumptionDataRepositoryTest.java b/maven-core/src/test/java/org/apache/maven/execution/DefaultBuildResumptionDataRepositoryTest.java
index 279fb11..415b946 100644
--- a/maven-core/src/test/java/org/apache/maven/execution/DefaultBuildResumptionDataRepositoryTest.java
+++ b/maven-core/src/test/java/org/apache/maven/execution/DefaultBuildResumptionDataRepositoryTest.java
@@ -19,10 +19,6 @@ package org.apache.maven.execution;
* under the License.
*/
-import org.apache.maven.lifecycle.LifecycleExecutionException;
-import org.apache.maven.model.Dependency;
-import org.apache.maven.project.MavenProject;
-import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
@@ -31,8 +27,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
-import static java.util.Arrays.asList;
-import static java.util.Collections.singletonList;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.is;
@@ -40,93 +34,7 @@ import static org.hamcrest.Matchers.is;
@RunWith( MockitoJUnitRunner.class )
public class DefaultBuildResumptionDataRepositoryTest
{
- private final DefaultBuildResumptionDataRepository buildResumer = new DefaultBuildResumptionDataRepository();
-
- private MavenExecutionResult result;
-
- @Before
- public void before() {
- result = new DefaultMavenExecutionResult();
- }
-
- @Test
- public void resumeFromGetsDetermined()
- {
- MavenProject projectA = createSucceededMavenProject( "A" );
- MavenProject projectB = createFailedMavenProject( "B" );
- result.setTopologicallySortedProjects( asList( projectA, projectB ) );
-
- Properties properties = buildResumer.determineResumptionProperties( result );
-
- assertThat( properties.get( "resumeFrom" ), is( "test:B" ) );
- }
-
- @Test
- public void resumeFromIsIgnoredWhenFirstProjectFails()
- {
- MavenProject projectA = createFailedMavenProject( "A" );
- MavenProject projectB = createMavenProject( "B" );
- result.setTopologicallySortedProjects( asList( projectA, projectB ) );
-
- Properties properties = buildResumer.determineResumptionProperties( result );
-
- assertThat( properties.containsKey( "resumeFrom" ), is(false) );
- }
-
- @Test
- public void projectsSucceedingAfterFailedProjectsAreExcluded()
- {
- MavenProject projectA = createSucceededMavenProject( "A" );
- MavenProject projectB = createFailedMavenProject( "B" );
- MavenProject projectC = createSucceededMavenProject( "C" );
- result.setTopologicallySortedProjects( asList( projectA, projectB, projectC ) );
-
- Properties properties = buildResumer.determineResumptionProperties( result );
-
- assertThat( properties.get( "excludedProjects" ), is("test:C") );
- }
-
- @Test
- public void projectsDependingOnFailedProjectsAreNotExcluded()
- {
- MavenProject projectA = createSucceededMavenProject( "A" );
- MavenProject projectB = createFailedMavenProject( "B" );
- MavenProject projectC = createSucceededMavenProject( "C" );
- projectC.setDependencies( singletonList( toDependency( projectB ) ) );
- result.setTopologicallySortedProjects( asList( projectA, projectB, projectC ) );
-
- Properties properties = buildResumer.determineResumptionProperties( result );
-
- assertThat( properties.containsKey( "excludedProjects" ), is(false) );
- }
-
- @Test
- public void projectsFailingAfterAnotherFailedProjectAreNotExcluded()
- {
- MavenProject projectA = createSucceededMavenProject( "A" );
- MavenProject projectB = createFailedMavenProject( "B" );
- MavenProject projectC = createSucceededMavenProject( "C" );
- MavenProject projectD = createFailedMavenProject( "D" );
- result.setTopologicallySortedProjects( asList( projectA, projectB, projectC, projectD ) );
-
- Properties properties = buildResumer.determineResumptionProperties( result );
-
- assertThat( properties.get( "resumeFrom" ), is("test:B") );
- assertThat( properties.get( "excludedProjects" ), is("test:C") );
- }
-
- @Test
- public void multipleExcludedProjectsAreCommaSeparated()
- {
- MavenProject projectA = createFailedMavenProject( "A" );
- MavenProject projectB = createSucceededMavenProject( "B" );
- MavenProject projectC = createSucceededMavenProject( "C" );
- result.setTopologicallySortedProjects( asList( projectA, projectB, projectC ) );
-
- Properties properties = buildResumer.determineResumptionProperties( result );
-
- assertThat( properties.get( "excludedProjects" ), is( "test:B, test:C" ) );
- }
+ private final DefaultBuildResumptionDataRepository repository = new DefaultBuildResumptionDataRepository();
@Test
public void resumeFromPropertyGetsApplied()
@@ -135,7 +43,7 @@ public class DefaultBuildResumptionDataRepositoryTest
Properties properties = new Properties();
properties.setProperty( "resumeFrom", ":module-a" );
- buildResumer.applyResumptionProperties( request, properties );
+ repository.applyResumptionProperties( request, properties );
assertThat( request.getResumeFrom(), is( ":module-a" ) );
}
@@ -148,7 +56,7 @@ public class DefaultBuildResumptionDataRepositoryTest
Properties properties = new Properties();
properties.setProperty( "resumeFrom", ":module-a" );
- buildResumer.applyResumptionProperties( request, properties );
+ repository.applyResumptionProperties( request, properties );
assertThat( request.getResumeFrom(), is( ":module-b" ) );
}
@@ -163,40 +71,8 @@ public class DefaultBuildResumptionDataRepositoryTest
Properties properties = new Properties();
properties.setProperty( "excludedProjects", ":module-b, :module-c" );
- buildResumer.applyResumptionProperties( request, properties );
+ repository.applyResumptionProperties( request, properties );
assertThat( request.getExcludedProjects(), contains( ":module-a", ":module-b", ":module-c" ) );
}
-
- private MavenProject createMavenProject( String artifactId )
- {
- MavenProject project = new MavenProject();
- project.setGroupId( "test" );
- project.setArtifactId( artifactId );
- return project;
- }
-
- private Dependency toDependency( MavenProject mavenProject )
- {
- Dependency dependency = new Dependency();
- dependency.setGroupId( mavenProject.getGroupId() );
- dependency.setArtifactId( mavenProject.getArtifactId() );
- dependency.setVersion( mavenProject.getVersion() );
- return dependency;
- }
-
- private MavenProject createSucceededMavenProject( String artifactId )
- {
- MavenProject project = createMavenProject( artifactId );
- result.addBuildSummary( new BuildSuccess( project, 0 ) );
- return project;
- }
-
- private MavenProject createFailedMavenProject( String artifactId )
- {
- MavenProject project = createMavenProject( artifactId );
- result.addBuildSummary( new BuildFailure( project, 0, new Exception() ) );
- result.addException( new LifecycleExecutionException( "", project ) );
- return project;
- }
}