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 2026/10/05 21:24:02 UTC
(maven-dependency-plugin) 01/03: [MDEP-969] Replace maven-dependency-tree with Maven Resolver
This is an automated email from the ASF dual-hosted git repository.
slachiewicz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-dependency-plugin.git
commit 1dfc4b659c30170c7ca36d9252ad2d5a64f4ec2d
Author: Sylwester Lachiewicz <sl...@apache.org>
AuthorDate: Wed Sep 30 19:05:05 2026 +0200
[MDEP-969] Replace maven-dependency-tree with Maven Resolver
maven-dependency-tree is obsolete. The tree goal now builds its nodes from
ProjectDependenciesResolver and RepositorySystem; output is byte-identical.
---
pom.xml | 5 -
.../tree/BuildingDependencyNodeVisitor.java | 119 +-----------
...r.java => CollectingDependencyNodeVisitor.java} | 35 ++--
.../dependency/tree/DOTDependencyNodeVisitor.java | 3 -
.../plugins/dependency/tree/DependencyNode.java | 89 +++++++++
.../dependency/tree/DependencyNodeVisitor.java | 36 ++++
.../dependency/tree/DependencyTreeBuilder.java | 203 +++++++++++++++++++++
.../tree/DirectScopeDependencySelector.java | 76 ++++++++
...or.java => FilteringDependencyNodeVisitor.java} | 23 +--
.../tree/GraphmlDependencyNodeVisitor.java | 3 -
.../dependency/tree/JsonDependencyNodeVisitor.java | 2 -
.../tree/PruningDependencyNodeVisitor.java | 11 +-
.../tree/SerializingDependencyNodeVisitor.java | 121 ++++++++++++
.../dependency/tree/TGFDependencyNodeVisitor.java | 3 -
.../maven/plugins/dependency/tree/TreeMojo.java | 86 ++++-----
.../dependency/tree/VerboseJavaScopeSelector.java | 53 ++++++
.../tree/PruningDependencyNodeVisitorTest.java | 22 +--
.../plugins/dependency/tree/TestTreeMojo.java | 6 +-
18 files changed, 648 insertions(+), 248 deletions(-)
diff --git a/pom.xml b/pom.xml
index 712bbb11..6d04b829 100644
--- a/pom.xml
+++ b/pom.xml
@@ -227,11 +227,6 @@ under the License.
<artifactId>maven-dependency-analyzer</artifactId>
<version>1.17.2</version>
</dependency>
- <dependency>
- <groupId>org.apache.maven.shared</groupId>
- <artifactId>maven-dependency-tree</artifactId>
- <version>3.3.0</version>
- </dependency>
<dependency>
<groupId>org.apache.maven.shared</groupId>
<artifactId>maven-common-artifact-filters</artifactId>
diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/BuildingDependencyNodeVisitor.java b/src/main/java/org/apache/maven/plugins/dependency/tree/BuildingDependencyNodeVisitor.java
index 411a1fb5..88ac7ef5 100644
--- a/src/main/java/org/apache/maven/plugins/dependency/tree/BuildingDependencyNodeVisitor.java
+++ b/src/main/java/org/apache/maven/plugins/dependency/tree/BuildingDependencyNodeVisitor.java
@@ -19,14 +19,8 @@
package org.apache.maven.plugins.dependency.tree;
import java.util.ArrayList;
-import java.util.List;
import java.util.Stack;
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.model.Exclusion;
-import org.apache.maven.shared.dependency.graph.DependencyNode;
-import org.apache.maven.shared.dependency.graph.traversal.DependencyNodeVisitor;
-
/**
* A dependency node visitor that clones visited nodes into a new dependency tree. This can be used in conjunction with
* a dependency node filter to construct subtrees.
@@ -81,15 +75,8 @@ public class BuildingDependencyNodeVisitor implements DependencyNodeVisitor {
@Override
public boolean visit(DependencyNode node) {
// clone the node
- WrapperNode newNode = new WrapperNode(
- parentNodes.isEmpty() ? null : parentNodes.peek(),
- node.getArtifact(),
- node.getPremanagedVersion(),
- node.getPremanagedScope(),
- node.getVersionConstraint(),
- node.getOptional(),
- node.getExclusions(),
- node.toNodeString());
+ DependencyNode newNode = new DependencyNode(
+ parentNodes.isEmpty() ? null : parentNodes.peek(), node.getArtifact(), node.toNodeString());
newNode.setChildren(new ArrayList<>());
if (parentNodes.empty()) {
@@ -138,106 +125,4 @@ public class BuildingDependencyNodeVisitor implements DependencyNodeVisitor {
public DependencyNode getDependencyTree() {
return rootNode;
}
-
- private static class WrapperNode implements DependencyNode {
-
- private final Artifact artifact;
-
- private final DependencyNode parent;
-
- private final String premanagedVersion;
-
- private final String premanagedScope;
-
- private final String versionConstraint;
-
- private List<DependencyNode> children;
-
- private final Boolean optional;
-
- private final List<Exclusion> exclusions;
-
- private final String nodeString;
-
- private WrapperNode(
- DependencyNode parent,
- Artifact artifact,
- String premanagedVersion,
- String premanagedScope,
- String versionConstraint,
- Boolean optional,
- List<Exclusion> exclusions,
- String nodeString) {
- this.artifact = artifact;
- this.parent = parent;
- this.premanagedVersion = premanagedVersion;
- this.premanagedScope = premanagedScope;
- this.versionConstraint = versionConstraint;
- this.optional = optional;
- this.exclusions = exclusions;
- this.nodeString = nodeString;
- }
-
- @Override
- public Artifact getArtifact() {
- return artifact;
- }
-
- @Override
- public List<DependencyNode> getChildren() {
- return children;
- }
-
- @Override
- public boolean accept(DependencyNodeVisitor visitor) {
- if (visitor.visit(this)) {
- for (DependencyNode child : getChildren()) {
- if (!child.accept(visitor)) {
- break;
- }
- }
- }
-
- return visitor.endVisit(this);
- }
-
- @Override
- public DependencyNode getParent() {
- return parent;
- }
-
- @Override
- public String getPremanagedVersion() {
- return premanagedVersion;
- }
-
- @Override
- public String getPremanagedScope() {
- return premanagedScope;
- }
-
- @Override
- public String getVersionConstraint() {
- return versionConstraint;
- }
-
- @Override
- public String toNodeString() {
- return nodeString;
- }
-
- @Override
- public Boolean getOptional() {
- return optional;
- }
-
- @Override
- public List<Exclusion> getExclusions() {
- return exclusions;
- }
-
- public void setChildren(List<DependencyNode> children) {
- this.children = children;
- }
- }
}
diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/PruningDependencyNodeVisitor.java b/src/main/java/org/apache/maven/plugins/dependency/tree/CollectingDependencyNodeVisitor.java
similarity index 50%
copy from src/main/java/org/apache/maven/plugins/dependency/tree/PruningDependencyNodeVisitor.java
copy to src/main/java/org/apache/maven/plugins/dependency/tree/CollectingDependencyNodeVisitor.java
index 380d2873..9d8b670d 100644
--- a/src/main/java/org/apache/maven/plugins/dependency/tree/PruningDependencyNodeVisitor.java
+++ b/src/main/java/org/apache/maven/plugins/dependency/tree/CollectingDependencyNodeVisitor.java
@@ -18,37 +18,28 @@
*/
package org.apache.maven.plugins.dependency.tree;
-import java.util.ArrayDeque;
-import java.util.Deque;
-
-import org.apache.maven.shared.dependency.graph.DependencyNode;
-import org.apache.maven.shared.dependency.graph.filter.DependencyNodeFilter;
-import org.apache.maven.shared.dependency.graph.traversal.DependencyNodeVisitor;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
/**
- * A dependency node visitor that delegates accepted nodes and prunes rejected nodes and their descendants.
+ * Collects all visited nodes.
*/
-final class PruningDependencyNodeVisitor implements DependencyNodeVisitor {
- private final DependencyNodeVisitor visitor;
-
- private final DependencyNodeFilter filter;
-
- private final Deque<Boolean> acceptedNodes = new ArrayDeque<>();
-
- PruningDependencyNodeVisitor(DependencyNodeVisitor visitor, DependencyNodeFilter filter) {
- this.visitor = visitor;
- this.filter = filter;
- }
+class CollectingDependencyNodeVisitor implements DependencyNodeVisitor {
+ private final List<DependencyNode> nodes = new ArrayList<>();
@Override
public boolean visit(DependencyNode node) {
- boolean accepted = filter.accept(node);
- acceptedNodes.push(accepted);
- return accepted && visitor.visit(node);
+ nodes.add(node);
+ return true;
}
@Override
public boolean endVisit(DependencyNode node) {
- return !acceptedNodes.pop() || visitor.endVisit(node);
+ return true;
+ }
+
+ List<DependencyNode> getNodes() {
+ return Collections.unmodifiableList(nodes);
}
}
diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/DOTDependencyNodeVisitor.java b/src/main/java/org/apache/maven/plugins/dependency/tree/DOTDependencyNodeVisitor.java
index 0508a313..4fca7fa3 100644
--- a/src/main/java/org/apache/maven/plugins/dependency/tree/DOTDependencyNodeVisitor.java
+++ b/src/main/java/org/apache/maven/plugins/dependency/tree/DOTDependencyNodeVisitor.java
@@ -23,9 +23,6 @@ import java.io.UncheckedIOException;
import java.io.Writer;
import java.util.List;
-import org.apache.maven.shared.dependency.graph.DependencyNode;
-import org.apache.maven.shared.dependency.graph.traversal.DependencyNodeVisitor;
-
/**
* A dependency node visitor that serializes visited nodes to <a href="https://en.wikipedia.org/wiki/DOT_language">DOT
* format</a>
diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/DependencyNode.java b/src/main/java/org/apache/maven/plugins/dependency/tree/DependencyNode.java
new file mode 100644
index 00000000..2d90bd7e
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/dependency/tree/DependencyNode.java
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+package org.apache.maven.plugins.dependency.tree;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+
+/**
+ * A node of the dependency tree displayed by the {@link TreeMojo}.
+ */
+public class DependencyNode {
+ private final DependencyNode parent;
+
+ private final Artifact artifact;
+
+ private final String nodeString;
+
+ private List<DependencyNode> children = Collections.emptyList();
+
+ /**
+ * @param parent the parent node, or <code>null</code> for the root
+ * @param artifact the artifact of this node
+ * @param nodeString the label of this node
+ */
+ public DependencyNode(DependencyNode parent, Artifact artifact, String nodeString) {
+ this.parent = parent;
+ this.artifact = artifact;
+ this.nodeString = nodeString;
+ }
+
+ public Artifact getArtifact() {
+ return artifact;
+ }
+
+ public DependencyNode getParent() {
+ return parent;
+ }
+
+ public List<DependencyNode> getChildren() {
+ return children;
+ }
+
+ public void setChildren(List<DependencyNode> children) {
+ this.children = children;
+ }
+
+ /**
+ * @return the label of this node
+ */
+ public String toNodeString() {
+ return nodeString;
+ }
+
+ /**
+ * Applies the visitor to this node and, as long as the visitor agrees, to its descendants.
+ *
+ * @param visitor the visitor
+ * @return the result of {@link DependencyNodeVisitor#endVisit(DependencyNode)}
+ */
+ public boolean accept(DependencyNodeVisitor visitor) {
+ if (visitor.visit(this)) {
+ for (DependencyNode child : children) {
+ if (!child.accept(visitor)) {
+ break;
+ }
+ }
+ }
+
+ return visitor.endVisit(this);
+ }
+}
diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/DependencyNodeVisitor.java b/src/main/java/org/apache/maven/plugins/dependency/tree/DependencyNodeVisitor.java
new file mode 100644
index 00000000..159f8f69
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/dependency/tree/DependencyNodeVisitor.java
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+package org.apache.maven.plugins.dependency.tree;
+
+/**
+ * Visits the nodes of a dependency tree.
+ */
+public interface DependencyNodeVisitor {
+ /**
+ * @param node the node being visited
+ * @return <code>true</code> to visit the children of the node
+ */
+ boolean visit(DependencyNode node);
+
+ /**
+ * @param node the node whose visit is finished
+ * @return <code>true</code> to visit the following siblings of the node
+ */
+ boolean endVisit(DependencyNode node);
+}
diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/DependencyTreeBuilder.java b/src/main/java/org/apache/maven/plugins/dependency/tree/DependencyTreeBuilder.java
new file mode 100644
index 00000000..7f3ec0e4
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/dependency/tree/DependencyTreeBuilder.java
@@ -0,0 +1,203 @@
+/*
+ * 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.
+ */
+package org.apache.maven.plugins.dependency.tree;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.maven.RepositoryUtils;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.project.DefaultDependencyResolutionRequest;
+import org.apache.maven.project.DependencyResolutionException;
+import org.apache.maven.project.DependencyResolutionRequest;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.ProjectDependenciesResolver;
+import org.eclipse.aether.DefaultRepositorySystemSession;
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.artifact.ArtifactTypeRegistry;
+import org.eclipse.aether.collection.CollectRequest;
+import org.eclipse.aether.collection.DependencyCollectionException;
+import org.eclipse.aether.util.artifact.JavaScopes;
+import org.eclipse.aether.util.graph.manager.DependencyManagerUtils;
+import org.eclipse.aether.util.graph.selector.AndDependencySelector;
+import org.eclipse.aether.util.graph.selector.ExclusionDependencySelector;
+import org.eclipse.aether.util.graph.selector.OptionalDependencySelector;
+import org.eclipse.aether.util.graph.transformer.ConflictResolver;
+import org.eclipse.aether.util.graph.transformer.JavaScopeDeriver;
+import org.eclipse.aether.util.graph.transformer.NearestVersionSelector;
+import org.eclipse.aether.util.graph.transformer.SimpleOptionalitySelector;
+
+/**
+ * Builds the {@link DependencyNode} tree of a project from Maven Resolver's dependency graph.
+ * <p>
+ * The plain tree is what Maven resolves for the project, so it is consistent with the Maven version running. The
+ * verbose tree is collected again with the conflict resolver keeping the omitted nodes.
+ */
+class DependencyTreeBuilder {
+ private final RepositorySystem repositorySystem;
+
+ private final ProjectDependenciesResolver projectDependenciesResolver;
+
+ DependencyTreeBuilder(RepositorySystem repositorySystem, ProjectDependenciesResolver projectDependenciesResolver) {
+ this.repositorySystem = repositorySystem;
+ this.projectDependenciesResolver = projectDependenciesResolver;
+ }
+
+ /**
+ * Builds the tree resolved by Maven, without omitted nodes.
+ */
+ DependencyNode build(MavenProject project, RepositorySystemSession session, ArtifactFilter filter)
+ throws DependencyResolutionException {
+ DependencyResolutionRequest request = new DefaultDependencyResolutionRequest();
+ request.setMavenProject(project);
+ request.setRepositorySession(session);
+ // only collect the graph, do not download the artifacts
+ request.setResolutionFilter((node, parents) -> false);
+
+ org.eclipse.aether.graph.DependencyNode root =
+ projectDependenciesResolver.resolve(request).getDependencyGraph();
+
+ return buildNode(null, root, project.getArtifact(), filter, false);
+ }
+
+ /**
+ * Builds the tree including the nodes omitted for duplicates and conflicts, and the managed versions and scopes.
+ */
+ DependencyNode buildVerbose(MavenProject project, RepositorySystemSession repositorySession, ArtifactFilter filter)
+ throws DependencyCollectionException {
+ DefaultRepositorySystemSession session = new DefaultRepositorySystemSession(repositorySession);
+ session.setDependencyGraphTransformer(new ConflictResolver(
+ new NearestVersionSelector(),
+ new VerboseJavaScopeSelector(),
+ new SimpleOptionalitySelector(),
+ new JavaScopeDeriver()));
+ session.setDependencySelector(new AndDependencySelector(
+ new DirectScopeDependencySelector(JavaScopes.TEST),
+ new DirectScopeDependencySelector(JavaScopes.PROVIDED),
+ new OptionalDependencySelector(),
+ new ExclusionDependencySelector()));
+ session.setConfigProperty(ConflictResolver.CONFIG_PROP_VERBOSE, true);
+ session.setConfigProperty(DependencyManagerUtils.CONFIG_PROP_VERBOSE, true);
+
+ ArtifactTypeRegistry stereotypes = session.getArtifactTypeRegistry();
+ CollectRequest collectRequest = new CollectRequest();
+ collectRequest.setRootArtifact(RepositoryUtils.toArtifact(project.getArtifact()));
+ collectRequest.setRepositories(RepositoryUtils.toRepos(project.getRemoteArtifactRepositories()));
+ for (Dependency dependency : project.getDependencies()) {
+ collectRequest.addDependency(RepositoryUtils.toDependency(dependency, stereotypes));
+ }
+ if (project.getDependencyManagement() != null) {
+ for (Dependency dependency : project.getDependencyManagement().getDependencies()) {
+ collectRequest.addManagedDependency(RepositoryUtils.toDependency(dependency, stereotypes));
+ }
+ }
+
+ org.eclipse.aether.graph.DependencyNode root =
+ repositorySystem.collectDependencies(session, collectRequest).getRoot();
+
+ return buildNode(null, root, project.getArtifact(), filter, true);
+ }
+
+ private DependencyNode buildNode(
+ DependencyNode parent,
+ org.eclipse.aether.graph.DependencyNode node,
+ Artifact artifact,
+ ArtifactFilter filter,
+ boolean verbose) {
+ DependencyNode current = new DependencyNode(
+ parent, artifact, verbose ? verboseNodeString(node, artifact) : nodeString(artifact));
+
+ List<DependencyNode> children = new ArrayList<>(node.getChildren().size());
+ for (org.eclipse.aether.graph.DependencyNode child : node.getChildren()) {
+ Artifact childArtifact = toArtifact(child.getDependency());
+
+ if (filter == null || filter.include(childArtifact)) {
+ children.add(buildNode(current, child, childArtifact, filter, verbose));
+ }
+ }
+ current.setChildren(Collections.unmodifiableList(children));
+
+ return current;
+ }
+
+ private static Artifact toArtifact(org.eclipse.aether.graph.Dependency dependency) {
+ Artifact artifact = RepositoryUtils.toArtifact(dependency.getArtifact());
+ artifact.setScope(dependency.getScope());
+ artifact.setOptional(dependency.isOptional());
+ return artifact;
+ }
+
+ private static String nodeString(Artifact artifact) {
+ return artifact + (artifact.isOptional() ? " (optional)" : "");
+ }
+
+ private static String verboseNodeString(org.eclipse.aether.graph.DependencyNode node, Artifact artifact) {
+ org.eclipse.aether.graph.DependencyNode winner =
+ (org.eclipse.aether.graph.DependencyNode) node.getData().get(ConflictResolver.NODE_DATA_WINNER);
+ String winnerVersion = null;
+ String ignoredScope = null;
+ if (winner != null) {
+ winnerVersion = winner.getArtifact().getBaseVersion();
+ } else {
+ ignoredScope = (String) node.getData().get(VerboseJavaScopeSelector.REDUCED_SCOPE);
+ }
+
+ boolean included = winnerVersion == null;
+
+ StringBuilder buffer = new StringBuilder();
+ if (!included) {
+ buffer.append('(');
+ }
+ buffer.append(artifact);
+
+ List<String> items = new ArrayList<>();
+ String premanagedVersion = DependencyManagerUtils.getPremanagedVersion(node);
+ if (premanagedVersion != null) {
+ items.add("version managed from " + premanagedVersion);
+ }
+ String premanagedScope = DependencyManagerUtils.getPremanagedScope(node);
+ if (premanagedScope != null) {
+ items.add("scope managed from " + premanagedScope);
+ }
+ if (ignoredScope != null) {
+ items.add("scope not updated to " + ignoredScope);
+ }
+ if (!included) {
+ items.add(
+ winnerVersion.equals(artifact.getVersion())
+ ? "omitted for duplicate"
+ : "omitted for conflict with " + winnerVersion);
+ }
+
+ if (!items.isEmpty()) {
+ buffer.append(included ? " (" : " - ")
+ .append(String.join("; ", items))
+ .append(included ? ")" : "");
+ }
+ if (!included) {
+ buffer.append(')');
+ }
+
+ return buffer.toString();
+ }
+}
diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/DirectScopeDependencySelector.java b/src/main/java/org/apache/maven/plugins/dependency/tree/DirectScopeDependencySelector.java
new file mode 100644
index 00000000..945d0da2
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/dependency/tree/DirectScopeDependencySelector.java
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+package org.apache.maven.plugins.dependency.tree;
+
+import java.util.Objects;
+
+import org.eclipse.aether.collection.DependencyCollectionContext;
+import org.eclipse.aether.collection.DependencySelector;
+import org.eclipse.aether.graph.Dependency;
+
+/**
+ * Excludes dependencies of a scope, unless they are direct dependencies of the project or its dependencies' first
+ * level, as the verbose tree shows them.
+ */
+class DirectScopeDependencySelector implements DependencySelector {
+
+ private final String scope;
+
+ private final int depth;
+
+ DirectScopeDependencySelector(String scope) {
+ this(scope, 0);
+ }
+
+ private DirectScopeDependencySelector(String scope, int depth) {
+ this.scope = Objects.requireNonNull(scope, "scope is null!");
+ this.depth = depth;
+ }
+
+ @Override
+ public boolean selectDependency(Dependency dependency) {
+ return depth < 2 || !scope.equals(dependency.getScope());
+ }
+
+ @Override
+ public DependencySelector deriveChildSelector(DependencyCollectionContext context) {
+ if (depth >= 2) {
+ return this;
+ }
+
+ return new DirectScopeDependencySelector(scope, depth + 1);
+ }
+
+ @Override
+ public int hashCode() {
+ return 31 * (31 + depth) + scope.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ DirectScopeDependencySelector other = (DirectScopeDependencySelector) obj;
+ return depth == other.depth && scope.equals(other.scope);
+ }
+}
diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/PruningDependencyNodeVisitor.java b/src/main/java/org/apache/maven/plugins/dependency/tree/FilteringDependencyNodeVisitor.java
similarity index 56%
copy from src/main/java/org/apache/maven/plugins/dependency/tree/PruningDependencyNodeVisitor.java
copy to src/main/java/org/apache/maven/plugins/dependency/tree/FilteringDependencyNodeVisitor.java
index 380d2873..4761d732 100644
--- a/src/main/java/org/apache/maven/plugins/dependency/tree/PruningDependencyNodeVisitor.java
+++ b/src/main/java/org/apache/maven/plugins/dependency/tree/FilteringDependencyNodeVisitor.java
@@ -18,37 +18,28 @@
*/
package org.apache.maven.plugins.dependency.tree;
-import java.util.ArrayDeque;
-import java.util.Deque;
-
-import org.apache.maven.shared.dependency.graph.DependencyNode;
-import org.apache.maven.shared.dependency.graph.filter.DependencyNodeFilter;
-import org.apache.maven.shared.dependency.graph.traversal.DependencyNodeVisitor;
+import java.util.function.Predicate;
/**
- * A dependency node visitor that delegates accepted nodes and prunes rejected nodes and their descendants.
+ * Passes only the accepted nodes to the delegate, while still traversing the children of the rejected ones.
*/
-final class PruningDependencyNodeVisitor implements DependencyNodeVisitor {
+class FilteringDependencyNodeVisitor implements DependencyNodeVisitor {
private final DependencyNodeVisitor visitor;
- private final DependencyNodeFilter filter;
-
- private final Deque<Boolean> acceptedNodes = new ArrayDeque<>();
+ private final Predicate<DependencyNode> filter;
- PruningDependencyNodeVisitor(DependencyNodeVisitor visitor, DependencyNodeFilter filter) {
+ FilteringDependencyNodeVisitor(DependencyNodeVisitor visitor, Predicate<DependencyNode> filter) {
this.visitor = visitor;
this.filter = filter;
}
@Override
public boolean visit(DependencyNode node) {
- boolean accepted = filter.accept(node);
- acceptedNodes.push(accepted);
- return accepted && visitor.visit(node);
+ return !filter.test(node) || visitor.visit(node);
}
@Override
public boolean endVisit(DependencyNode node) {
- return !acceptedNodes.pop() || visitor.endVisit(node);
+ return !filter.test(node) || visitor.endVisit(node);
}
}
diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/GraphmlDependencyNodeVisitor.java b/src/main/java/org/apache/maven/plugins/dependency/tree/GraphmlDependencyNodeVisitor.java
index 78811c62..076bcc9e 100644
--- a/src/main/java/org/apache/maven/plugins/dependency/tree/GraphmlDependencyNodeVisitor.java
+++ b/src/main/java/org/apache/maven/plugins/dependency/tree/GraphmlDependencyNodeVisitor.java
@@ -22,9 +22,6 @@ import java.io.IOException;
import java.io.UncheckedIOException;
import java.io.Writer;
-import org.apache.maven.shared.dependency.graph.DependencyNode;
-import org.apache.maven.shared.dependency.graph.traversal.DependencyNodeVisitor;
-
/**
* A dependency node visitor that serializes visited nodes to a writer using the
* <a href="https://en.wikipedia.org/wiki/GraphML">graphml format</a>.
diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/JsonDependencyNodeVisitor.java b/src/main/java/org/apache/maven/plugins/dependency/tree/JsonDependencyNodeVisitor.java
index 719d36cd..630afcce 100644
--- a/src/main/java/org/apache/maven/plugins/dependency/tree/JsonDependencyNodeVisitor.java
+++ b/src/main/java/org/apache/maven/plugins/dependency/tree/JsonDependencyNodeVisitor.java
@@ -25,8 +25,6 @@ import java.util.HashSet;
import java.util.Set;
import org.apache.maven.artifact.Artifact;
-import org.apache.maven.shared.dependency.graph.DependencyNode;
-import org.apache.maven.shared.dependency.graph.traversal.DependencyNodeVisitor;
/**
* A dependency node visitor that serializes visited nodes to a writer using the JSON format.
diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/PruningDependencyNodeVisitor.java b/src/main/java/org/apache/maven/plugins/dependency/tree/PruningDependencyNodeVisitor.java
index 380d2873..daf0afba 100644
--- a/src/main/java/org/apache/maven/plugins/dependency/tree/PruningDependencyNodeVisitor.java
+++ b/src/main/java/org/apache/maven/plugins/dependency/tree/PruningDependencyNodeVisitor.java
@@ -20,10 +20,7 @@ package org.apache.maven.plugins.dependency.tree;
import java.util.ArrayDeque;
import java.util.Deque;
-
-import org.apache.maven.shared.dependency.graph.DependencyNode;
-import org.apache.maven.shared.dependency.graph.filter.DependencyNodeFilter;
-import org.apache.maven.shared.dependency.graph.traversal.DependencyNodeVisitor;
+import java.util.function.Predicate;
/**
* A dependency node visitor that delegates accepted nodes and prunes rejected nodes and their descendants.
@@ -31,18 +28,18 @@ import org.apache.maven.shared.dependency.graph.traversal.DependencyNodeVisitor;
final class PruningDependencyNodeVisitor implements DependencyNodeVisitor {
private final DependencyNodeVisitor visitor;
- private final DependencyNodeFilter filter;
+ private final Predicate<DependencyNode> filter;
private final Deque<Boolean> acceptedNodes = new ArrayDeque<>();
- PruningDependencyNodeVisitor(DependencyNodeVisitor visitor, DependencyNodeFilter filter) {
+ PruningDependencyNodeVisitor(DependencyNodeVisitor visitor, Predicate<DependencyNode> filter) {
this.visitor = visitor;
this.filter = filter;
}
@Override
public boolean visit(DependencyNode node) {
- boolean accepted = filter.accept(node);
+ boolean accepted = filter.test(node);
acceptedNodes.push(accepted);
return accepted && visitor.visit(node);
}
diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/SerializingDependencyNodeVisitor.java b/src/main/java/org/apache/maven/plugins/dependency/tree/SerializingDependencyNodeVisitor.java
new file mode 100644
index 00000000..448e89f9
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/dependency/tree/SerializingDependencyNodeVisitor.java
@@ -0,0 +1,121 @@
+/*
+ * 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.
+ */
+package org.apache.maven.plugins.dependency.tree;
+
+import java.io.PrintWriter;
+import java.io.Writer;
+import java.util.List;
+
+/**
+ * Writes the dependency tree as indented text.
+ */
+class SerializingDependencyNodeVisitor implements DependencyNodeVisitor {
+
+ static class GraphTokens {
+ private final String nodeIndent;
+
+ private final String lastNodeIndent;
+
+ private final String fillIndent;
+
+ private final String lastFillIndent;
+
+ GraphTokens(String nodeIndent, String lastNodeIndent, String fillIndent, String lastFillIndent) {
+ this.nodeIndent = nodeIndent;
+ this.lastNodeIndent = lastNodeIndent;
+ this.fillIndent = fillIndent;
+ this.lastFillIndent = lastFillIndent;
+ }
+
+ String getNodeIndent(boolean last) {
+ return last ? lastNodeIndent : nodeIndent;
+ }
+
+ String getFillIndent(boolean last) {
+ return last ? lastFillIndent : fillIndent;
+ }
+ }
+
+ static final GraphTokens WHITESPACE_TOKENS = new GraphTokens(" ", " ", " ", " ");
+
+ static final GraphTokens STANDARD_TOKENS = new GraphTokens("+- ", "\\- ", "| ", " ");
+
+ static final GraphTokens EXTENDED_TOKENS = new GraphTokens("├─ ", "└─ ", "│ ", " ");
+
+ private final PrintWriter writer;
+
+ private final GraphTokens tokens;
+
+ private int depth;
+
+ SerializingDependencyNodeVisitor(Writer writer, GraphTokens tokens) {
+ this.writer = writer instanceof PrintWriter ? (PrintWriter) writer : new PrintWriter(writer, true);
+ this.tokens = tokens;
+ }
+
+ @Override
+ public boolean visit(DependencyNode node) {
+ indent(node);
+
+ writer.println(node.toNodeString());
+
+ depth++;
+
+ return true;
+ }
+
+ @Override
+ public boolean endVisit(DependencyNode node) {
+ depth--;
+
+ return true;
+ }
+
+ private void indent(DependencyNode node) {
+ for (int i = 1; i < depth; i++) {
+ writer.write(tokens.getFillIndent(isLast(node, i)));
+ }
+
+ if (depth > 0) {
+ writer.write(tokens.getNodeIndent(isLast(node)));
+ }
+ }
+
+ private boolean isLast(DependencyNode node) {
+ DependencyNode parent = node.getParent();
+
+ if (parent == null) {
+ return true;
+ }
+
+ List<DependencyNode> siblings = parent.getChildren();
+
+ return siblings.indexOf(node) == siblings.size() - 1;
+ }
+
+ private boolean isLast(DependencyNode node, int ancestorDepth) {
+ int distance = depth - ancestorDepth;
+
+ while (distance-- > 0) {
+ node = node.getParent();
+ }
+
+ return isLast(node);
+ }
+}
diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/TGFDependencyNodeVisitor.java b/src/main/java/org/apache/maven/plugins/dependency/tree/TGFDependencyNodeVisitor.java
index 3dc3a328..e5dbc64b 100644
--- a/src/main/java/org/apache/maven/plugins/dependency/tree/TGFDependencyNodeVisitor.java
+++ b/src/main/java/org/apache/maven/plugins/dependency/tree/TGFDependencyNodeVisitor.java
@@ -24,9 +24,6 @@ import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
-import org.apache.maven.shared.dependency.graph.DependencyNode;
-import org.apache.maven.shared.dependency.graph.traversal.DependencyNodeVisitor;
-
/**
* A dependency node visitor that serializes visited nodes to a writer using the
* <a href="https://en.wikipedia.org/wiki/Trivial_Graph_Format">TGF format</a>.
diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/TreeMojo.java b/src/main/java/org/apache/maven/plugins/dependency/tree/TreeMojo.java
index cbb0af33..ff213501 100644
--- a/src/main/java/org/apache/maven/plugins/dependency/tree/TreeMojo.java
+++ b/src/main/java/org/apache/maven/plugins/dependency/tree/TreeMojo.java
@@ -24,8 +24,12 @@ import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
+import java.util.Collections;
+import java.util.IdentityHashMap;
import java.util.List;
import java.util.Objects;
+import java.util.Set;
+import java.util.function.Predicate;
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
@@ -36,25 +40,15 @@ import org.apache.maven.plugin.MojoFailureException;
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.plugins.dependency.tree.SerializingDependencyNodeVisitor.GraphTokens;
import org.apache.maven.plugins.dependency.utils.DependencyUtil;
-import org.apache.maven.project.DefaultProjectBuildingRequest;
+import org.apache.maven.project.DependencyResolutionException;
import org.apache.maven.project.MavenProject;
-import org.apache.maven.project.ProjectBuildingRequest;
+import org.apache.maven.project.ProjectDependenciesResolver;
import org.apache.maven.shared.artifact.filter.StrictPatternExcludesArtifactFilter;
import org.apache.maven.shared.artifact.filter.StrictPatternIncludesArtifactFilter;
-import org.apache.maven.shared.dependency.graph.DependencyCollectorBuilder;
-import org.apache.maven.shared.dependency.graph.DependencyCollectorBuilderException;
-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.filter.AncestorOrSelfDependencyNodeFilter;
-import org.apache.maven.shared.dependency.graph.filter.ArtifactDependencyNodeFilter;
-import org.apache.maven.shared.dependency.graph.filter.DependencyNodeFilter;
-import org.apache.maven.shared.dependency.graph.traversal.CollectingDependencyNodeVisitor;
-import org.apache.maven.shared.dependency.graph.traversal.DependencyNodeVisitor;
-import org.apache.maven.shared.dependency.graph.traversal.FilteringDependencyNodeVisitor;
-import org.apache.maven.shared.dependency.graph.traversal.SerializingDependencyNodeVisitor;
-import org.apache.maven.shared.dependency.graph.traversal.SerializingDependencyNodeVisitor.GraphTokens;
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.collection.DependencyCollectionException;
/**
* Displays the dependency tree for this project. Multiple formats are supported: text (by default), but also
@@ -77,15 +71,7 @@ public class TreeMojo extends AbstractMojo {
private final MavenSession session;
- /**
- * The dependency collector builder to use.
- */
- private final DependencyCollectorBuilder dependencyCollectorBuilder;
-
- /**
- * The dependency graph builder to use.
- */
- private final DependencyGraphBuilder dependencyGraphBuilder;
+ private final DependencyTreeBuilder dependencyTreeBuilder;
@Parameter(property = "outputEncoding", defaultValue = "${project.reporting.outputEncoding}")
private String outputEncoding;
@@ -208,12 +194,11 @@ public class TreeMojo extends AbstractMojo {
public TreeMojo(
MavenProject project,
MavenSession session,
- DependencyCollectorBuilder dependencyCollectorBuilder,
- DependencyGraphBuilder dependencyGraphBuilder) {
+ RepositorySystem repositorySystem,
+ ProjectDependenciesResolver projectDependenciesResolver) {
this.project = project;
this.session = session;
- this.dependencyCollectorBuilder = dependencyCollectorBuilder;
- this.dependencyGraphBuilder = dependencyGraphBuilder;
+ this.dependencyTreeBuilder = new DependencyTreeBuilder(repositorySystem, projectDependenciesResolver);
}
// Mojo methods -----------------------------------------------------------
@@ -229,27 +214,17 @@ public class TreeMojo extends AbstractMojo {
}
try {
- String dependencyTreeString;
-
- // TODO: note that filter does not get applied due to MSHARED-4
ArtifactFilter artifactFilter = createResolvingArtifactFilter();
- ProjectBuildingRequest buildingRequest =
- new DefaultProjectBuildingRequest(session.getProjectBuildingRequest());
-
- buildingRequest.setProject(project);
-
if (verbose) {
- rootNode = dependencyCollectorBuilder.collectDependencyGraph(buildingRequest, artifactFilter);
- dependencyTreeString = serializeDependencyTree(rootNode);
+ rootNode = dependencyTreeBuilder.buildVerbose(project, session.getRepositorySession(), artifactFilter);
} else {
- // non-verbose mode use dependency graph component, which gives consistent results with Maven version
- // running
- rootNode = dependencyGraphBuilder.buildDependencyGraph(buildingRequest, artifactFilter);
-
- dependencyTreeString = serializeDependencyTree(rootNode);
+ // non-verbose mode shows what Maven resolves, consistent with the Maven version running
+ rootNode = dependencyTreeBuilder.build(project, session.getRepositorySession(), artifactFilter);
}
+ String dependencyTreeString = serializeDependencyTree(rootNode);
+
if (outputFile != null) {
String encoding = Objects.toString(outputEncoding, "UTF-8");
DependencyUtil.write(dependencyTreeString, outputFile, this.appendOutput, encoding);
@@ -258,7 +233,7 @@ public class TreeMojo extends AbstractMojo {
} else {
DependencyUtil.log(dependencyTreeString, getLog());
}
- } catch (DependencyGraphBuilderException | DependencyCollectorBuilderException exception) {
+ } catch (DependencyResolutionException | DependencyCollectionException exception) {
throw new MojoExecutionException("Cannot build project dependency graph", exception);
} catch (IOException exception) {
throw new MojoExecutionException("Cannot serialize project dependency graph", exception);
@@ -335,8 +310,8 @@ public class TreeMojo extends AbstractMojo {
// TODO: remove the need for this when the serializer can calculate last nodes from visitor calls only
visitor = new BuildingDependencyNodeVisitor(visitor);
- DependencyNodeFilter includesFilter = createIncludesDependencyNodeFilter();
- DependencyNodeFilter excludesFilter = createExcludesDependencyNodeFilter();
+ Predicate<DependencyNode> includesFilter = createIncludesDependencyNodeFilter();
+ Predicate<DependencyNode> excludesFilter = createExcludesDependencyNodeFilter();
if (includesFilter != null) {
CollectingDependencyNodeVisitor collectingVisitor = new CollectingDependencyNodeVisitor();
@@ -347,9 +322,14 @@ public class TreeMojo extends AbstractMojo {
}
theRootNode.accept(firstPassVisitor);
- DependencyNodeFilter secondPassFilter =
- new AncestorOrSelfDependencyNodeFilter(collectingVisitor.getNodes());
- visitor = new FilteringDependencyNodeVisitor(visitor, secondPassFilter);
+ // keep the included nodes together with their ancestors
+ Set<DependencyNode> ancestorOrSelf = Collections.newSetFromMap(new IdentityHashMap<>());
+ for (DependencyNode included : collectingVisitor.getNodes()) {
+ for (DependencyNode node = included; node != null; node = node.getParent()) {
+ ancestorOrSelf.add(node);
+ }
+ }
+ visitor = new FilteringDependencyNodeVisitor(visitor, ancestorOrSelf::contains);
}
if (excludesFilter != null) {
@@ -408,23 +388,23 @@ public class TreeMojo extends AbstractMojo {
*
* @return the dependency node filter, or <code>null</code> if none required
*/
- private DependencyNodeFilter createIncludesDependencyNodeFilter() {
+ private Predicate<DependencyNode> createIncludesDependencyNodeFilter() {
if (includes != null && !includes.isEmpty()) {
getLog().debug("+ Filtering dependency tree by artifact include patterns: " + includes);
ArtifactFilter artifactFilter = new StrictPatternIncludesArtifactFilter(includes);
- return new ArtifactDependencyNodeFilter(artifactFilter);
+ return node -> artifactFilter.include(node.getArtifact());
}
return null;
}
- private DependencyNodeFilter createExcludesDependencyNodeFilter() {
+ private Predicate<DependencyNode> createExcludesDependencyNodeFilter() {
if (excludes != null && !excludes.isEmpty()) {
getLog().debug("+ Filtering dependency tree by artifact exclude patterns: " + excludes);
ArtifactFilter artifactFilter = new StrictPatternExcludesArtifactFilter(excludes);
- return new ArtifactDependencyNodeFilter(artifactFilter);
+ return node -> artifactFilter.include(node.getArtifact());
}
return null;
diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/VerboseJavaScopeSelector.java b/src/main/java/org/apache/maven/plugins/dependency/tree/VerboseJavaScopeSelector.java
new file mode 100644
index 00000000..1ddeb893
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/dependency/tree/VerboseJavaScopeSelector.java
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+package org.apache.maven.plugins.dependency.tree;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+
+import org.eclipse.aether.RepositoryException;
+import org.eclipse.aether.util.graph.transformer.ConflictResolver.ConflictContext;
+import org.eclipse.aether.util.graph.transformer.ConflictResolver.ScopeSelector;
+import org.eclipse.aether.util.graph.transformer.JavaScopeSelector;
+
+/**
+ * Selects the scope like Maven does and records on the winning node a wider scope that was not applied, so the verbose
+ * tree can report it.
+ */
+class VerboseJavaScopeSelector extends ScopeSelector {
+ static final String REDUCED_SCOPE = "REDUCED_SCOPE";
+
+ private static final List<String> ORDERED_SCOPES = Arrays.asList("compile", "runtime", "provided", "test");
+
+ private final ScopeSelector scopeSelector = new JavaScopeSelector();
+
+ @Override
+ public void selectScope(ConflictContext context) throws RepositoryException {
+ scopeSelector.selectScope(context);
+
+ context.getItems().stream()
+ .flatMap(i -> i.getScopes().stream())
+ .distinct()
+ .max(Comparator.comparingInt((String s) -> ORDERED_SCOPES.indexOf(s))
+ .reversed())
+ .filter(s -> s != context.getScope())
+ .ifPresent(s -> context.getWinner().getNode().setData(REDUCED_SCOPE, s));
+ }
+}
diff --git a/src/test/java/org/apache/maven/plugins/dependency/tree/PruningDependencyNodeVisitorTest.java b/src/test/java/org/apache/maven/plugins/dependency/tree/PruningDependencyNodeVisitorTest.java
index 2231d7c5..9a1b0b27 100644
--- a/src/test/java/org/apache/maven/plugins/dependency/tree/PruningDependencyNodeVisitorTest.java
+++ b/src/test/java/org/apache/maven/plugins/dependency/tree/PruningDependencyNodeVisitorTest.java
@@ -21,13 +21,9 @@ package org.apache.maven.plugins.dependency.tree;
import java.util.Arrays;
import java.util.Collections;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Predicate;
import org.apache.maven.artifact.Artifact;
-import org.apache.maven.shared.dependency.graph.DependencyNode;
-import org.apache.maven.shared.dependency.graph.filter.DependencyNodeFilter;
-import org.apache.maven.shared.dependency.graph.internal.DefaultDependencyNode;
-import org.apache.maven.shared.dependency.graph.traversal.CollectingDependencyNodeVisitor;
-import org.apache.maven.shared.dependency.graph.traversal.DependencyNodeVisitor;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -36,7 +32,7 @@ import static org.mockito.Mockito.mock;
class PruningDependencyNodeVisitorTest {
@Test
void evaluatesFilterOnlyWhenStartingNodeVisit() {
- DefaultDependencyNode root = newNode(null);
+ DependencyNode root = newNode(null);
root.setChildren(Collections.emptyList());
AtomicInteger filterInvocations = new AtomicInteger();
AtomicInteger endVisits = new AtomicInteger();
@@ -61,10 +57,10 @@ class PruningDependencyNodeVisitorTest {
@Test
void prunesRejectedSubtreeAndContinuesWithSiblings() {
- DefaultDependencyNode root = newNode(null);
- DefaultDependencyNode rejected = newNode(root);
- DefaultDependencyNode rejectedChild = newNode(rejected);
- DefaultDependencyNode sibling = newNode(root);
+ DependencyNode root = newNode(null);
+ DependencyNode rejected = newNode(root);
+ DependencyNode rejectedChild = newNode(rejected);
+ DependencyNode sibling = newNode(root);
root.setChildren(Arrays.asList(rejected, sibling));
rejected.setChildren(Collections.singletonList(rejectedChild));
@@ -72,14 +68,14 @@ class PruningDependencyNodeVisitorTest {
sibling.setChildren(Collections.emptyList());
CollectingDependencyNodeVisitor collectingVisitor = new CollectingDependencyNodeVisitor();
- DependencyNodeFilter filter = node -> node != rejected;
+ Predicate<DependencyNode> filter = node -> node != rejected;
root.accept(new PruningDependencyNodeVisitor(collectingVisitor, filter));
assertEquals(Arrays.asList(root, sibling), collectingVisitor.getNodes());
}
- private DefaultDependencyNode newNode(DependencyNode parent) {
- return new DefaultDependencyNode(parent, mock(Artifact.class), null, null, null);
+ private DependencyNode newNode(DependencyNode parent) {
+ return new DependencyNode(parent, mock(Artifact.class), "node");
}
}
diff --git a/src/test/java/org/apache/maven/plugins/dependency/tree/TestTreeMojo.java b/src/test/java/org/apache/maven/plugins/dependency/tree/TestTreeMojo.java
index 487a1e84..034ef3b9 100644
--- a/src/test/java/org/apache/maven/plugins/dependency/tree/TestTreeMojo.java
+++ b/src/test/java/org/apache/maven/plugins/dependency/tree/TestTreeMojo.java
@@ -46,8 +46,6 @@ import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugins.dependency.testUtils.DependencyArtifactStubFactory;
import org.apache.maven.project.DefaultProjectBuildingRequest;
import org.apache.maven.project.MavenProject;
-import org.apache.maven.shared.dependency.graph.DependencyNode;
-import org.apache.maven.shared.dependency.graph.internal.DefaultDependencyNode;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
@@ -188,8 +186,8 @@ class TestTreeMojo {
Artifact artifact1 = this.stubFactory.createArtifact("testGroupId", "project1", "1.0");
Artifact artifact2 = this.stubFactory.createArtifact("testGroupId", "project2", "1.0");
- DefaultDependencyNode node1 = new DefaultDependencyNode(artifact1);
- DefaultDependencyNode node2 = new DefaultDependencyNode(artifact2);
+ DependencyNode node1 = new DependencyNode(null, artifact1, artifact1.toString());
+ DependencyNode node2 = new DependencyNode(null, artifact2, artifact2.toString());
node1.setChildren(new ArrayList<>());
node2.setChildren(new ArrayList<>());