Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

[AETHER-82] Incomplete dirty tree in case of cyclic dependencies

  • Loading branch information...
commit a537899308f3d22df5509e33628a0012ba912293 1 parent 47e5a24
@bentmann bentmann authored
View
30 aether-impl/src/main/java/org/sonatype/aether/impl/internal/DefaultDependencyCollector.java
@@ -308,12 +308,14 @@ private String getId( Artifact a )
return a.getGroupId() + ':' + a.getArtifactId() + ':' + a.getClassifier() + ':' + a.getExtension();
}
- private void process( RepositorySystemSession session, RequestTrace trace, CollectResult result,
- LinkedList<GraphEdge> edges, List<Dependency> dependencies,
- List<RemoteRepository> repositories, DependencySelector depSelector,
- DependencyManager depManager, DependencyTraverser depTraverser, DataPool pool )
+ private boolean process( RepositorySystemSession session, RequestTrace trace, CollectResult result,
+ LinkedList<GraphEdge> edges, List<Dependency> dependencies,
+ List<RemoteRepository> repositories, DependencySelector depSelector,
+ DependencyManager depManager, DependencyTraverser depTraverser, DataPool pool )
throws DependencyCollectionException
{
+ boolean cycle = false;
+
nextDependency: for ( Dependency dependency : dependencies )
{
boolean disableVersionManagement = false;
@@ -444,6 +446,7 @@ else if ( repo == null )
if ( findDuplicate( edges, d.getArtifact() ) != null )
{
+ cycle = true;
continue;
}
@@ -489,13 +492,15 @@ else if ( repo == null )
key = pool.toKey( d.getArtifact(), repositories );
}
+ boolean cacheNode = false;
+
GraphNode child = pool.getNode( key );
if ( child == null )
{
child = new GraphNode();
child.setAliases( descriptorResult.getAliases() );
child.setRepositories( repos );
- pool.putNode( key, child );
+ cacheNode = true;
}
else
{
@@ -525,16 +530,27 @@ else if ( repo == null )
{
edges.addFirst( edge );
- process( session, trace, result, edges, descriptorResult.getDependencies(), childRepos,
- childSelector, childManager, childTraverser, pool );
+ if ( process( session, trace, result, edges, descriptorResult.getDependencies(), childRepos,
+ childSelector, childManager, childTraverser, pool ) )
+ {
+ cacheNode = false;
+ cycle = true;
+ }
edges.removeFirst();
}
+
+ if ( cacheNode )
+ {
+ pool.putNode( key, child );
+ }
}
break;
}
}
+
+ return cycle;
}
private GraphEdge findDuplicate( List<GraphEdge> edges, Artifact artifact )
View
37 aether-impl/src/test/java/org/sonatype/aether/impl/internal/DefaultDependencyCollectorTest.java
@@ -18,6 +18,7 @@
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -68,19 +69,29 @@ public void setup()
repository = new RemoteRepository( "id", "default", "file:///" );
}
- private static void assertEqualSubtree( DependencyNode root1, DependencyNode root2 )
+ private static void assertEqualSubtree( DependencyNode expected, DependencyNode actual )
{
- assertEquals( root1.getDependency(), root2.getDependency() );
- assertEquals( root1.getChildren().size(), root2.getChildren().size() );
+ assertEqualSubtree( expected, actual, new LinkedList<DependencyNode>() );
+ }
+
+ private static void assertEqualSubtree( DependencyNode expected, DependencyNode actual,
+ LinkedList<DependencyNode> parents )
+ {
+ assertEquals( "path: " + parents, expected.getDependency(), actual.getDependency() );
+
+ parents.addLast( expected );
- Iterator<DependencyNode> iterator1 = root1.getChildren().iterator();
- Iterator<DependencyNode> iterator2 = root2.getChildren().iterator();
+ assertEquals( "path: " + parents + ", expected: " + expected.getChildren() + ", actual: "
+ + actual.getChildren(), expected.getChildren().size(), actual.getChildren().size() );
+
+ Iterator<DependencyNode> iterator1 = expected.getChildren().iterator();
+ Iterator<DependencyNode> iterator2 = actual.getChildren().iterator();
while ( iterator1.hasNext() )
{
- assertEqualSubtree( iterator1.next(), iterator2.next() );
+ assertEqualSubtree( iterator1.next(), iterator2.next(), parents );
}
-
+ parents.removeLast();
}
private Dependency dep( DependencyNode root, int... coords )
@@ -99,7 +110,6 @@ private DependencyNode path( DependencyNode root, int... coords )
}
return node;
-
}
catch ( IndexOutOfBoundsException e )
{
@@ -109,7 +119,6 @@ private DependencyNode path( DependencyNode root, int... coords )
{
throw new IllegalArgumentException( "Illegal coordinates for child", e );
}
-
}
@Test
@@ -203,6 +212,16 @@ public void testEqualSubtree()
}
@Test
+ public void testCyclicDependencies()
+ throws Exception
+ {
+ DependencyNode root = parser.parse( "cycle.txt" );
+ CollectRequest request = new CollectRequest( root.getDependency(), Arrays.asList( repository ) );
+ CollectResult result = collector.collectDependencies( session, request );
+ assertEqualSubtree( root, result.getRoot() );
+ }
+
+ @Test
public void testPartialResultOnError()
throws IOException
{
View
7 aether-impl/src/test/resources/artifact-descriptions/cycle.txt
@@ -0,0 +1,7 @@
+cycle:root:jar:1
++- cycle:a:jar:1:compile
+| \- cycle:b:jar:1:compile
+| \- cycle:c:jar:1:compile
+\- cycle:b:jar:1:compile
+ \- cycle:c:jar:1:compile
+ \- cycle:a:jar:1:compile
View
2  aether-impl/src/test/resources/artifact-descriptions/cycle_a_1_jar.ini
@@ -0,0 +1,2 @@
+[dependencies]
+cycle:b:jar:1
View
2  aether-impl/src/test/resources/artifact-descriptions/cycle_b_1_jar.ini
@@ -0,0 +1,2 @@
+[dependencies]
+cycle:c:jar:1
View
2  aether-impl/src/test/resources/artifact-descriptions/cycle_c_1_jar.ini
@@ -0,0 +1,2 @@
+[dependencies]
+cycle:a:jar:1
View
3  aether-impl/src/test/resources/artifact-descriptions/cycle_root_1_jar.ini
@@ -0,0 +1,3 @@
+[dependencies]
+cycle:a:jar:1
+cycle:b:jar:1
Please sign in to comment.
Something went wrong with that request. Please try again.