PR: MNG-820

ensure only the right dependencies are used when two different versions have different deps.

git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@291563 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Brett Leslie Porter 2005-09-26 05:52:36 +00:00
parent 7d1fb02010
commit d955fbef5c
3 changed files with 228 additions and 104 deletions

View File

@ -26,6 +26,7 @@ import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.OverConstrainedVersionException; import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
import org.apache.maven.artifact.versioning.VersionRange; import org.apache.maven.artifact.versioning.VersionRange;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -72,8 +73,11 @@ public class DefaultArtifactCollector
for ( Iterator i = resolvedArtifacts.values().iterator(); i.hasNext(); ) for ( Iterator i = resolvedArtifacts.values().iterator(); i.hasNext(); )
{ {
ResolutionNode node = (ResolutionNode) i.next(); List nodes = (List) i.next();
if ( !node.equals( root ) ) for ( Iterator j = nodes.iterator(); j.hasNext(); )
{
ResolutionNode node = (ResolutionNode) j.next();
if ( !node.equals( root ) && node.isActive() )
{ {
Artifact artifact = node.getArtifact(); Artifact artifact = node.getArtifact();
@ -86,6 +90,7 @@ public class DefaultArtifactCollector
} }
} }
} }
}
ArtifactResolutionResult result = new ArtifactResolutionResult(); ArtifactResolutionResult result = new ArtifactResolutionResult();
result.setArtifactResolutionNodes( set ); result.setArtifactResolutionNodes( set );
@ -122,13 +127,20 @@ public class DefaultArtifactCollector
} }
} }
ResolutionNode previous = (ResolutionNode) resolvedArtifacts.get( key ); List previousNodes = (List) resolvedArtifacts.get( key );
if ( previous != null ) if ( previousNodes != null )
{ {
// TODO: use as conflict resolver(s), chain and introduce version mediation for ( Iterator i = previousNodes.iterator(); i.hasNext(); )
{
ResolutionNode previous = (ResolutionNode) i.next();
if ( previous.isActive() )
{
// Version mediation
VersionRange previousRange = previous.getArtifact().getVersionRange(); VersionRange previousRange = previous.getArtifact().getVersionRange();
VersionRange currentRange = node.getArtifact().getVersionRange(); VersionRange currentRange = node.getArtifact().getVersionRange();
// TODO: why do we force the version on it? what if they don't match?
if ( previousRange == null ) if ( previousRange == null )
{ {
// version was already resolved // version was already resolved
@ -147,6 +159,10 @@ public class DefaultArtifactCollector
node.getArtifact().setVersionRange( currentRange.restrict( previousRange ) ); node.getArtifact().setVersionRange( currentRange.restrict( previousRange ) );
} }
// Conflict Resolution
// TODO: use as conflict resolver(s), chain
// TODO: should this be part of mediation?
// previous one is more dominant // previous one is more dominant
if ( previous.getDepth() <= node.getDepth() ) if ( previous.getDepth() <= node.getDepth() )
{ {
@ -159,15 +175,28 @@ public class DefaultArtifactCollector
if ( previous.getDepth() <= node.getDepth() ) if ( previous.getDepth() <= node.getDepth() )
{ {
// previous was nearer
fireEvent( ResolutionListener.OMIT_FOR_NEARER, listeners, node, previous.getArtifact() ); fireEvent( ResolutionListener.OMIT_FOR_NEARER, listeners, node, previous.getArtifact() );
return; node.disable();
}
else
{
previous.disable();
} }
} }
}
resolvedArtifacts.put( key, node ); }
else
{
previousNodes = new ArrayList();
resolvedArtifacts.put( key, previousNodes );
}
previousNodes.add( node );
fireEvent( ResolutionListener.INCLUDE_ARTIFACT, listeners, node ); fireEvent( ResolutionListener.INCLUDE_ARTIFACT, listeners, node );
if ( node.isActive() )
{
fireEvent( ResolutionListener.PROCESS_CHILDREN, listeners, node ); fireEvent( ResolutionListener.PROCESS_CHILDREN, listeners, node );
for ( Iterator i = node.getChildrenIterator(); i.hasNext(); ) for ( Iterator i = node.getChildrenIterator(); i.hasNext(); )
@ -208,8 +237,8 @@ public class DefaultArtifactCollector
} }
else else
{ {
throw new OverConstrainedVersionException( throw new OverConstrainedVersionException( "Couldn't find a version in " +
"Couldn't find a version in " + versions + " to match range " + versionRange ); versions + " to match range " + versionRange );
} }
} }
} }
@ -237,16 +266,18 @@ public class DefaultArtifactCollector
catch ( ArtifactMetadataRetrievalException e ) catch ( ArtifactMetadataRetrievalException e )
{ {
artifact.setDependencyTrail( node.getDependencyTrail() ); artifact.setDependencyTrail( node.getDependencyTrail() );
throw new TransitiveArtifactResolutionException( e.getMessage(), artifact, remoteRepositories, e ); throw new TransitiveArtifactResolutionException( e.getMessage(), artifact, remoteRepositories,
e );
} }
recurse( child, resolvedArtifacts, managedVersions, localRepository, remoteRepositories, source, filter, recurse( child, resolvedArtifacts, managedVersions, localRepository, remoteRepositories, source,
listeners ); filter, listeners );
} }
} }
fireEvent( ResolutionListener.FINISH_PROCESSING_CHILDREN, listeners, node ); fireEvent( ResolutionListener.FINISH_PROCESSING_CHILDREN, listeners, node );
} }
}
private void checkScopeUpdate( ResolutionNode node, ResolutionNode previous, List listeners ) private void checkScopeUpdate( ResolutionNode node, ResolutionNode previous, List listeners )
{ {

View File

@ -42,6 +42,8 @@ public class ResolutionNode
private final List remoteRepositories; private final List remoteRepositories;
private boolean active = true;
public ResolutionNode( Artifact artifact, List remoteRepositories ) public ResolutionNode( Artifact artifact, List remoteRepositories )
{ {
this.artifact = artifact; this.artifact = artifact;
@ -144,4 +146,35 @@ public class ResolutionNode
return remoteRepositories; return remoteRepositories;
} }
public boolean isActive()
{
return active;
}
public void enable()
{
this.active = true;
// TODO: if it was null, we really need to go find them now... or is this taken care of by the ordering?
if ( children != null )
{
for ( Iterator i = children.iterator(); i.hasNext(); )
{
ResolutionNode node = (ResolutionNode) i.next();
node.enable();
}
}
}
public void disable()
{
this.active = false;
if ( children != null )
{
for ( Iterator i = children.iterator(); i.hasNext(); )
{
ResolutionNode node = (ResolutionNode) i.next();
node.disable();
}
}
}
} }

View File

@ -123,6 +123,66 @@ public class DefaultArtifactCollectorTest
assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, c.artifact} ), res.getArtifacts() ); assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, c.artifact} ), res.getArtifacts() );
} }
public void testResolveCorrectDependenciesWhenDifferentDependenciesOnNearest()
throws ArtifactResolutionException, InvalidVersionSpecificationException
{
ArtifactSpec a = createArtifact( "a", "1.0" );
ArtifactSpec b = a.addDependency( "b", "1.0" );
ArtifactSpec c2 = b.addDependency( "c", "2.0" );
c2.addDependency( "d", "1.0" );
ArtifactSpec e = createArtifact( "e", "1.0" );
ArtifactSpec c1 = e.addDependency( "c", "1.0" );
ArtifactSpec f = c1.addDependency( "f", "1.0" );
ArtifactResolutionResult res = collect( createSet( new Object[]{a.artifact, e.artifact} ) );
assertEquals( "Check artifact list",
createSet( new Object[]{a.artifact, b.artifact, e.artifact, c1.artifact, f.artifact} ),
res.getArtifacts() );
assertEquals( "Check version", "1.0", getArtifact( "c", res.getArtifacts() ).getVersion() );
}
public void disabledtestResolveCorrectDependenciesWhenDifferentDependenciesOnNewest()
throws ArtifactResolutionException, InvalidVersionSpecificationException
{
// TODO: use newest conflict resolver
ArtifactSpec a = createArtifact( "a", "1.0" );
ArtifactSpec b = a.addDependency( "b", "1.0" );
ArtifactSpec c2 = b.addDependency( "c", "2.0" );
ArtifactSpec d = c2.addDependency( "d", "1.0" );
ArtifactSpec e = createArtifact( "e", "1.0" );
ArtifactSpec c1 = e.addDependency( "c", "1.0" );
c1.addDependency( "f", "1.0" );
ArtifactResolutionResult res = collect( createSet( new Object[]{a.artifact, e.artifact} ) );
assertEquals( "Check artifact list",
createSet( new Object[]{a.artifact, b.artifact, e.artifact, c2.artifact, d.artifact} ),
res.getArtifacts() );
assertEquals( "Check version", "2.0", getArtifact( "c", res.getArtifacts() ).getVersion() );
}
public void disabledtestResolveCorrectDependenciesWhenDifferentDependenciesOnNewestVersionReplaced()
throws ArtifactResolutionException, InvalidVersionSpecificationException
{
// TODO: use newest conflict resolver
ArtifactSpec a = createArtifact( "a", "1.0" );
ArtifactSpec b1 = a.addDependency( "b", "1.0" );
ArtifactSpec c = a.addDependency( "c", "1.0" );
ArtifactSpec d2 = b1.addDependency( "d", "2.0" );
d2.addDependency( "h", "1.0" );
ArtifactSpec d1 = c.addDependency( "d", "1.0" );
ArtifactSpec b2 = c.addDependency( "b", "2.0" );
ArtifactSpec e = b2.addDependency( "e", "1.0" );
ArtifactSpec g = d1.addDependency( "g", "1.0" );
ArtifactResolutionResult res = collect( createSet( new Object[]{a.artifact} ) );
Object[] artifacts = new Object[]{a.artifact, c.artifact, d1.artifact, b2.artifact, e.artifact, g.artifact};
assertEquals( "Check artifact list", createSet( artifacts ), res.getArtifacts() );
assertEquals( "Check version", "1.0", getArtifact( "d", res.getArtifacts() ).getVersion() );
assertEquals( "Check version", "2.0", getArtifact( "b", res.getArtifacts() ).getVersion() );
}
public void testResolveNearestNewestIsNearest() public void testResolveNearestNewestIsNearest()
throws ArtifactResolutionException, InvalidVersionSpecificationException throws ArtifactResolutionException, InvalidVersionSpecificationException
{ {