diff --git a/src/it/projects/profile-with-deps-inherit-parent-depMgmt-test/pom.xml b/src/it/projects/profile-with-deps-inherit-parent-depMgmt-test/pom.xml
index 69df2f23..bdd0f72f 100644
--- a/src/it/projects/profile-with-deps-inherit-parent-depMgmt-test/pom.xml
+++ b/src/it/projects/profile-with-deps-inherit-parent-depMgmt-test/pom.xml
@@ -3,12 +3,12 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
org.codehaus.mojo.flatten.its
- profile-with-deps-inherit-parent-depMgmt-jdk
+ profile-with-deps-inherit-parent-depMgmt-test
0.1-SNAPSHOT
jar
org.codehaus.mojo.flatten.its
- profile-with-deps-inherit-parent-depMgmt-jdk_parent
+ profile-with-deps-inherit-parent-depMgmt-test_parent
0.1-SNAPSHOT
parent
diff --git a/src/main/java/org/codehaus/mojo/flatten/FlattenMojo.java b/src/main/java/org/codehaus/mojo/flatten/FlattenMojo.java
index bf764dce..af6b9a1a 100644
--- a/src/main/java/org/codehaus/mojo/flatten/FlattenMojo.java
+++ b/src/main/java/org/codehaus/mojo/flatten/FlattenMojo.java
@@ -19,7 +19,6 @@
* under the License.
*/
-import java.util.Queue;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.repository.ArtifactRepository;
@@ -51,11 +50,13 @@
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.apache.maven.project.DefaultProjectBuildingRequest;
import org.apache.maven.project.MavenProject;
-import org.apache.maven.shared.dependency.tree.DependencyNode;
-import org.apache.maven.shared.dependency.tree.DependencyTreeBuilder;
-import org.apache.maven.shared.dependency.tree.DependencyTreeBuilderException;
-import org.apache.maven.shared.dependency.tree.traversal.DependencyNodeVisitor;
+import org.apache.maven.project.ProjectBuildingRequest;
+import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder;
+import org.apache.maven.shared.dependency.graph.DependencyGraphBuilderException;
+import org.apache.maven.shared.dependency.graph.DependencyNode;
+import org.apache.maven.shared.dependency.graph.traversal.DependencyNodeVisitor;
import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolver;
import org.codehaus.mojo.flatten.cifriendly.CiInterpolator;
import org.codehaus.mojo.flatten.model.resolution.FlattenModelResolver;
@@ -86,9 +87,11 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
+import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
+import java.util.Queue;
import java.util.Set;
/**
@@ -224,7 +227,7 @@ public class FlattenMojo
@Parameter( property = "updatePomFile" )
private Boolean updatePomFile;
- /** The {@link ArtifactRepository} required to resolve POM using {@link #modelBuilder}. */
+ /** The {@link ArtifactRepository} required to resolve POM. */
@Parameter( defaultValue = "${localRepository}", readonly = true, required = true )
private ArtifactRepository localRepository;
@@ -284,7 +287,7 @@ public class FlattenMojo
*
*
* bom |
- * Like {@link #ossrh} but additionally keeps {@link Model#getDependencyManagement() dependencyManagement} and
+ * | Like ossrh but additionally keeps {@link Model#getDependencyManagement() dependencyManagement} and
* {@link Model#getProperties() properties}. Especially it will keep the {@link Model#getDependencyManagement()
* dependencyManagement} as-is without resolving parent influences and import-scoped dependencies. This is
* useful if your POM represents a projectDependen
* The collected dependencies are stored in order, so that the leaf dependencies are prioritized in front of direct dependencies.
* In addition, every non-leaf dependencies will exclude its own direct dependency, since all transitive dependencies
* will be collected.
- *
+ *
* Transitive dependencies are all going to be collected and become a direct dependency. Maven should already resolve
* versions properly because now the transitive dependencies are closer to the artifact. However, when this artifact is
* being consumed, Maven Enforcer Convergence rule will fail because there may be multiple versions for the same transitive dependency.
- *
+ *
* Typically, exclusion can be done by using the wildcard. However, a known Maven issue prevents convergence enforcer from
* working properly w/ wildcard exclusions. Thus, this will exclude each dependencies explicitly rather than using the wildcard.
*
* @param projectDependencies is the effective POM {@link Model}'s current dependencies
* @param flattenedDependencies is the {@link List} where to add the collected {@link Dependency dependencies}.
- * @throws DependencyTreeBuilderException
+ * @throws DependencyGraphBuilderException
* @throws ArtifactDescriptorException
*/
private void createFlattenedDependenciesAll( List projectDependencies, List flattenedDependencies )
- throws DependencyTreeBuilderException, ArtifactDescriptorException
+ throws ArtifactDescriptorException, DependencyGraphBuilderException
{
final Queue dependencyNodeLinkedList = new LinkedList<>();
final Set processedDependencies = new HashSet<>();
final Artifact projectArtifact = this.project.getArtifact();
- final DependencyNode dependencyNode = this.dependencyTreeBuilder.buildDependencyTree(this.project,
- this.localRepository, null);
+ ProjectBuildingRequest buildingRequest = new DefaultProjectBuildingRequest( session.getProjectBuildingRequest() );
+ buildingRequest.setProject( cloneProjectWithoutTestDependencies( project ) );
+
+ final DependencyNode dependencyNode = this.dependencyGraphBuilder.buildDependencyGraph( buildingRequest, null);
dependencyNode.accept(new DependencyNodeVisitor()
{
@@ -1110,10 +1115,6 @@ private void createFlattenedDependenciesAll( List projectDependencie
return false;
}
}
- if (node.getState() != DependencyNode.INCLUDED)
- {
- return false;
- }
if (node.getArtifact().isOptional())
{
return false;
@@ -1183,6 +1184,43 @@ private void createFlattenedDependenciesAll( List projectDependencie
}
}
+ /**
+ * Returns a cloned project that does not have direct test-scope dependencies.
+ *
+ * Test-scope project dependencies may hinder transitive dependencies by marking them as 'omitted for duplicate' when
+ * building dependency tree. This was a problem when the transitive dependency is actually needed by another non-test dependency
+ * of the project (See https://github.com/mojohaus/flatten-maven-plugin/issues/185). To avoid this interference of
+ * test-scope project dependencies, this plugin builds a dependency tree of the project without direct, test-scope dependencies.
+ *
+ * Removal of test scope dependencies is safe because these dependencies do not appear in library users' class path in
+ * any case.
+ *
+ * @param project is the original project to clone.
+ * @return a cloned project without direct test-scope dependencies.
+ */
+ private static MavenProject cloneProjectWithoutTestDependencies( MavenProject project )
+ {
+ final Set testScopeProjectDependencyKeys = new HashSet<>();
+ for ( Dependency projectDependency : project.getDependencies() )
+ {
+ if ( "test".equals( projectDependency.getScope() ) )
+ {
+ testScopeProjectDependencyKeys.add( projectDependency.getManagementKey() );
+ }
+ }
+ // LinkedHashSet preserves the order.
+ final Set dependencyArtifactsWithoutTest = new LinkedHashSet<>( project.getDependencyArtifacts() );
+ dependencyArtifactsWithoutTest.removeIf(artifact -> {
+ // The same logic as org.apache.maven.model.Dependency.getManagementKey()
+ String managementKey = artifact.getGroupId() + ":" + artifact.getArtifactId() + ":" + artifact.getType()
+ + ( artifact.getClassifier() != null ? ":" + artifact.getClassifier() : "" );
+ return testScopeProjectDependencyKeys.contains( managementKey );
+ });
+ final MavenProject projectWithoutTestScopeDeps = project.clone();
+ projectWithoutTestScopeDeps.setDependencyArtifacts( dependencyArtifactsWithoutTest );
+ return projectWithoutTestScopeDeps;
+ }
+
/**
* Collects the resolved {@link Dependency dependencies} from the given effectiveModel .
*
|