Skip to content

Commit

Permalink
Removing test-scope dependencies before building dependency tree
Browse files Browse the repository at this point in the history
  • Loading branch information
suztomo committed Aug 11, 2022
1 parent 5311c18 commit 3ed08bc
Showing 1 changed file with 27 additions and 6 deletions.
33 changes: 27 additions & 6 deletions src/main/java/org/codehaus/mojo/flatten/FlattenMojo.java
Expand Up @@ -19,6 +19,7 @@
* under the License.
*/

import java.util.LinkedHashSet;
import java.util.Queue;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
Expand Down Expand Up @@ -1070,11 +1071,11 @@ private void createFlattenedDependenciesDirect( List<Dependency> 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.
*
Expand All @@ -1091,11 +1092,31 @@ private void createFlattenedDependenciesAll( List<Dependency> projectDependencie

final Artifact projectArtifact = this.project.getArtifact();

// The test-scope project dependencies will hinder transitive dependencies by marking them
// as 'omitted for duplicate.'
this.project.getDependencies().removeIf(dependency -> "test".equals(dependency.getScope()));
// The test-scope project dependencies may hinder transitive dependencies by marking them as 'omitted for duplicate' when
// building dependency tree. This is a problem when the transitive dependency is actually needed by another non-test dependency
// of the project. To avoid this interference of test-scope project dependencies, this plugin builds a dependency tree
// of the project without direct, test-scope dependencies. This is safe because these dependencies do not appear in
// library users' class path in any case.
final Set<String> testScopeProjectDependencyKeys = new HashSet<>();
for (Dependency projectDependency : projectDependencies)
{
if ("test".equals(projectDependency.getScope()))
{
testScopeProjectDependencyKeys.add(projectDependency.getManagementKey());
}
}
// LinkedHashSet preserves the order.
final Set<Artifact> dependencyArtifactsWithoutTest = new LinkedHashSet<>(this.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 = this.project.clone();
projectWithoutTestScopeDeps.setDependencyArtifacts(dependencyArtifactsWithoutTest);

final DependencyNode dependencyNode = this.dependencyTreeBuilder.buildDependencyTree(this.project,
final DependencyNode dependencyNode = this.dependencyTreeBuilder.buildDependencyTree(projectWithoutTestScopeDeps,
this.localRepository, null);

dependencyNode.accept(new DependencyNodeVisitor()
Expand Down

0 comments on commit 3ed08bc

Please sign in to comment.