This closes #27
Project: http://git-wip-us.apache.org/repos/asf/ant-ivy/repo Commit: http://git-wip-us.apache.org/repos/asf/ant-ivy/commit/fdeb6b86 Tree: http://git-wip-us.apache.org/repos/asf/ant-ivy/tree/fdeb6b86 Diff: http://git-wip-us.apache.org/repos/asf/ant-ivy/diff/fdeb6b86 Branch: refs/heads/master Commit: fdeb6b86219d13a370d325ee49c694631b7e9ff3 Parents: 0dbae41 2f75745 Author: Nicolas LaleveÌe <nicolas.lale...@hibnet.org> Authored: Thu Jun 1 14:02:06 2017 +0200 Committer: Nicolas LaleveÌe <nicolas.lale...@hibnet.org> Committed: Thu Jun 1 14:09:44 2017 +0200 ---------------------------------------------------------------------- .../org/apache/ivy/ant/IvyDependencyTree.java | 68 ++++++++++++-------- .../apache/ivy/ant/IvyDependencyTreeTest.java | 25 +++++++ .../1/org/foo-bar/ivys/ivy-1.2.3.xml | 28 ++++++++ .../1/org/foo-bar/jars/foo-bar-1.2.3.jar | 0 test/repositories/1/org/mod1/ivys/ivy-2.0.xml | 27 ++++++++ test/repositories/1/org/mod1/jars/mod1-2.0.jar | 0 .../m2/org/circular/module1/1.0/module1-1.0.jar | 1 + .../m2/org/circular/module1/1.0/module1-1.0.pom | 35 ++++++++++ .../m2/org/circular/module2/2.0/module2-2.0.jar | 1 + .../m2/org/circular/module2/2.0/module2-2.0.pom | 35 ++++++++++ 10 files changed, 194 insertions(+), 26 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/fdeb6b86/src/java/org/apache/ivy/ant/IvyDependencyTree.java ---------------------------------------------------------------------- diff --cc src/java/org/apache/ivy/ant/IvyDependencyTree.java index b95aa91,5df9548..e2e5978 --- a/src/java/org/apache/ivy/ant/IvyDependencyTree.java +++ b/src/java/org/apache/ivy/ant/IvyDependencyTree.java @@@ -17,25 -17,24 +17,24 @@@ */ package org.apache.ivy.ant; -import org.apache.ivy.core.module.id.ModuleRevisionId; -import org.apache.ivy.core.report.ResolveReport; -import org.apache.ivy.core.resolve.IvyNode; -import org.apache.ivy.core.resolve.IvyNodeCallers.Caller; -import org.apache.ivy.core.resolve.IvyNodeEviction.EvictionData; -import org.apache.tools.ant.BuildException; - import java.util.ArrayList; import java.util.HashMap; + import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; + import java.util.Set; +import org.apache.ivy.core.module.id.ModuleRevisionId; +import org.apache.ivy.core.report.ResolveReport; +import org.apache.ivy.core.resolve.IvyNode; +import org.apache.ivy.core.resolve.IvyNodeCallers.Caller; +import org.apache.ivy.core.resolve.IvyNodeEviction.EvictionData; +import org.apache.tools.ant.BuildException; + public class IvyDependencyTree extends IvyPostResolveTask { - private Map/* <ModuleRevisionId, List<IvyNode>> */dependencies = new HashMap/* - * <ModuleRevisionId, - * List<IvyNode>> - */(); - private final Map<ModuleRevisionId, List<IvyNode>> dependencies = new HashMap<ModuleRevisionId, List<IvyNode>>(); ++ private final Map<ModuleRevisionId, List<IvyNode>> dependencies = new HashMap<>(); private boolean showEvicted = false; @@@ -45,24 -47,30 +47,29 @@@ log("Dependency tree for " + report.getResolveId()); ModuleRevisionId mrid = report.getModuleDescriptor().getModuleRevisionId(); // make dependency tree easier to fetch information -- for (Iterator iterator = report.getDependencies().iterator(); iterator.hasNext();) { -- IvyNode dependency = (IvyNode) iterator.next(); -- populateDependencyTree(dependency, mrid, report); ++ for (IvyNode dependency : report.getDependencies()) { ++ populateDependencyTree(dependency); } - List dependencyList = (List) dependencies.get(mrid); + final List<IvyNode> dependencyList = dependencies.get(mrid); if (dependencyList != null) { - printDependencies(dependencyList, 0); + printDependencies(mrid, dependencyList, 0, new HashSet<ModuleRevisionId>()); } } - private void printDependencies(List/* <IvyNode> */dependencyList, int indent) { - for (Iterator iterator = dependencyList.iterator(); iterator.hasNext();) { - IvyNode dependency = (IvyNode) iterator.next(); - boolean evicted = dependency.isEvicted(getConf()); + private void printDependencies(final ModuleRevisionId mrid, final List<IvyNode> dependencyList, final int indent, + final Set<ModuleRevisionId> ancestors) { + for (final Iterator iterator = dependencyList.iterator(); iterator.hasNext();) { - final Set<ModuleRevisionId> ancestorsForCurrentDep = new HashSet<ModuleRevisionId>(ancestors); ++ final Set<ModuleRevisionId> ancestorsForCurrentDep = new HashSet<>(ancestors); + // previous ancestors plus the module to whom these dependencies belong to + ancestorsForCurrentDep.add(mrid); + final IvyNode dependency = (IvyNode) iterator.next(); - final ModuleRevisionId dependencyMrid = dependency.getId(); - final boolean circular = ancestorsForCurrentDep.contains(dependencyMrid); + final boolean evicted = dependency.isEvicted(getConf()); - final StringBuilder sb = new StringBuilder(); if (evicted && !showEvicted) { continue; } - StringBuffer sb = new StringBuffer(); ++ final StringBuilder sb = new StringBuilder(); ++ final ModuleRevisionId dependencyMrid = dependency.getId(); ++ final boolean circular = ancestorsForCurrentDep.contains(dependencyMrid); if (indent > 0) { for (int i = 0; i < indent; i++) { if (i == indent - 1 && !iterator.hasNext() && !hasDependencies(dependency)) { @@@ -78,7 -86,15 +85,14 @@@ } else { sb.append("\\- "); } - sb.append(dependency.getId().toString()); + if (!evicted && circular) { + // log and skip processing the (transitive) dependencies of this dependency + sb.append("(circularly depends on) ").append(dependencyMrid); + log(sb.toString()); + continue; - + } else { + sb.append(dependencyMrid.toString()); + } if (evicted && showEvicted) { EvictionData evictedData = dependency.getEvictedData(getConf()); if (evictedData.isTransitivelyEvicted()) { @@@ -98,13 -114,16 +112,15 @@@ } } - private boolean hasDependencies(IvyNode dependency) { - List dependencyList = (List) dependencies.get(dependency.getId()); - return dependencyList.size() > 0; + private boolean hasDependencies(final IvyNode module) { + if (module == null) { + return false; + } + final List<IvyNode> dependenciesForModule = dependencies.get(module.getId()); + return dependenciesForModule != null && !dependenciesForModule.isEmpty(); } -- private void populateDependencyTree(IvyNode dependency, ModuleRevisionId currentMrid, -- ResolveReport report) { ++ private void populateDependencyTree(IvyNode dependency) { registerNodeIfNecessary(dependency.getId()); for (int i = 0; i < dependency.getAllCallers().length; i++) { Caller caller = dependency.getAllCallers()[i]; http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/fdeb6b86/test/java/org/apache/ivy/ant/IvyDependencyTreeTest.java ----------------------------------------------------------------------