PR: MNG-947

add optional attribute to a dependency

git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@291507 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Brett Leslie Porter 2005-09-26 01:17:59 +00:00
parent 853028dfab
commit f3932e47fa
9 changed files with 196 additions and 54 deletions

View File

@ -150,4 +150,6 @@ public interface Artifact
List getAvailableVersions();
void setAvailableVersions( List versions );
boolean isOptional();
}

View File

@ -80,8 +80,16 @@ public class DefaultArtifact
private Map metadataMap;
private boolean optional;
public DefaultArtifact( String groupId, String artifactId, VersionRange versionRange, String scope, String type,
String classifier, ArtifactHandler artifactHandler )
{
this( groupId, artifactId, versionRange, scope, type, classifier, artifactHandler, false );
}
public DefaultArtifact( String groupId, String artifactId, VersionRange versionRange, String scope, String type,
String classifier, ArtifactHandler artifactHandler, boolean optional )
{
this.groupId = groupId;
@ -102,6 +110,8 @@ public class DefaultArtifact
this.classifier = classifier;
this.optional = optional;
validateIdentity();
}
@ -504,4 +514,9 @@ public class DefaultArtifact
{
this.availableVersions = availableVersions;
}
public boolean isOptional()
{
return optional;
}
}

View File

@ -47,6 +47,9 @@ public interface ArtifactFactory
Artifact createDependencyArtifact( String groupId, String artifactId, VersionRange versionRange, String type,
String classifier, String scope, String inheritedScope );
Artifact createDependencyArtifact( String groupId, String artifactId, VersionRange versionRange, String type,
String classifier, String scope, String inheritedScope, boolean optional );
Artifact createBuildArtifact( String groupId, String artifactId, String version, String packaging );
Artifact createProjectArtifact( String groupId, String artifactId, String version );

View File

@ -52,13 +52,19 @@ public class DefaultArtifactFactory
public Artifact createDependencyArtifact( String groupId, String artifactId, VersionRange versionRange, String type,
String classifier, String scope )
{
return createArtifact( groupId, artifactId, versionRange, null, type, classifier, null );
return createArtifact( groupId, artifactId, versionRange, type, classifier, null, null );
}
public Artifact createDependencyArtifact( String groupId, String artifactId, VersionRange versionRange, String type,
String classifier, String scope, String inheritedScope )
{
return createArtifact( groupId, artifactId, versionRange, scope, type, classifier, inheritedScope );
return createArtifact( groupId, artifactId, versionRange, type, classifier, scope, inheritedScope );
}
public Artifact createDependencyArtifact( String groupId, String artifactId, VersionRange versionRange, String type,
String classifier, String scope, String inheritedScope, boolean optional )
{
return createArtifact( groupId, artifactId, versionRange, type, classifier, scope, inheritedScope, optional );
}
public Artifact createBuildArtifact( String groupId, String artifactId, String version, String packaging )
@ -78,7 +84,7 @@ public class DefaultArtifactFactory
public Artifact createPluginArtifact( String groupId, String artifactId, VersionRange versionRange )
{
return createArtifact( groupId, artifactId, versionRange, Artifact.SCOPE_RUNTIME, "maven-plugin", null, null );
return createArtifact( groupId, artifactId, versionRange, "maven-plugin", null, Artifact.SCOPE_RUNTIME, null );
}
public Artifact createProjectArtifact( String groupId, String artifactId, String version, String scope )
@ -88,7 +94,7 @@ public class DefaultArtifactFactory
public Artifact createExtensionArtifact( String groupId, String artifactId, VersionRange versionRange )
{
return createArtifact( groupId, artifactId, versionRange, Artifact.SCOPE_RUNTIME, "jar", null, null );
return createArtifact( groupId, artifactId, versionRange, "jar", null, Artifact.SCOPE_RUNTIME, null );
}
public Artifact createArtifact( String groupId, String artifactId, String version, String scope, String type,
@ -105,11 +111,17 @@ public class DefaultArtifactFactory
{
versionRange = VersionRange.createFromVersion( version );
}
return createArtifact( groupId, artifactId, versionRange, scope, type, classifier, inheritedScope );
return createArtifact( groupId, artifactId, versionRange, type, classifier, scope, inheritedScope );
}
private Artifact createArtifact( String groupId, String artifactId, VersionRange versionRange, String scope,
String type, String classifier, String inheritedScope )
private Artifact createArtifact( String groupId, String artifactId, VersionRange versionRange, String type,
String classifier, String scope, String inheritedScope )
{
return createArtifact( groupId, artifactId, versionRange, type, classifier, scope, inheritedScope, false );
}
private Artifact createArtifact( String groupId, String artifactId, VersionRange versionRange, String type,
String classifier, String scope, String inheritedScope, boolean optional )
{
// TODO: can refactor - inherited scope calculation belongs in the collector, use scope handler
@ -140,6 +152,7 @@ public class DefaultArtifactFactory
ArtifactHandler handler = artifactHandlerManager.getArtifactHandler( type );
return new DefaultArtifact( groupId, artifactId, versionRange, desiredScope, type, classifier, handler );
return new DefaultArtifact( groupId, artifactId, versionRange, desiredScope, type, classifier, handler,
optional );
}
}

View File

@ -77,9 +77,13 @@ public class DefaultArtifactCollector
{
Artifact artifact = node.getArtifact();
artifact.setDependencyTrail( node.getDependencyTrail() );
// If it was optional, we don't add it or its children, just allow the update of the version and scope
if ( !node.getArtifact().isOptional() )
{
artifact.setDependencyTrail( node.getDependencyTrail() );
set.add( node );
set.add( node );
}
}
}
@ -169,7 +173,8 @@ public class DefaultArtifactCollector
for ( Iterator i = node.getChildrenIterator(); i.hasNext(); )
{
ResolutionNode child = (ResolutionNode) i.next();
if ( !child.isResolved() )
// We leave in optional ones, but don't pick up its dependencies
if ( !child.isResolved() && !child.getArtifact().isOptional() )
{
Artifact artifact = child.getArtifact();
try

View File

@ -75,24 +75,31 @@ public class ResolutionNode
public void addDependencies( Set artifacts, List remoteRepositories, ArtifactFilter filter )
throws CyclicDependencyException, OverConstrainedVersionException
{
children = new ArrayList( artifacts.size() );
for ( Iterator i = artifacts.iterator(); i.hasNext(); )
if ( !artifacts.isEmpty() )
{
Artifact a = (Artifact) i.next();
children = new ArrayList( artifacts.size() );
if ( filter == null || filter.include( a ) )
for ( Iterator i = artifacts.iterator(); i.hasNext(); )
{
if ( parents.contains( a.getDependencyConflictId() ) )
Artifact a = (Artifact) i.next();
if ( filter == null || filter.include( a ) )
{
a.setDependencyTrail( getDependencyTrail() );
if ( parents.contains( a.getDependencyConflictId() ) )
{
a.setDependencyTrail( getDependencyTrail() );
throw new CyclicDependencyException( "A dependency has introduced a cycle", a );
throw new CyclicDependencyException( "A dependency has introduced a cycle", a );
}
children.add( new ResolutionNode( a, remoteRepositories, this ) );
}
children.add( new ResolutionNode( a, remoteRepositories, this ) );
}
}
else
{
children = Collections.EMPTY_LIST;
}
}
public List getDependencyTrail()

View File

@ -70,11 +70,11 @@ public class DefaultArtifactCollectorTest
// works, but we don't fail on cycles presently
public void disabledtestCircularDependencyNotIncludingCurrentProject()
throws ArtifactResolutionException
throws ArtifactResolutionException, InvalidVersionSpecificationException
{
ArtifactSpec a = createArtifact( "a", "1.0" );
ArtifactSpec b = a.addDependency( "b", "1.0" );
b.addDependency( a );
b.addDependency( "a", "1.0" );
try
{
collect( a );
@ -88,7 +88,7 @@ public class DefaultArtifactCollectorTest
// works, but we don't fail on cycles presently
public void disabledtestCircularDependencyIncludingCurrentProject()
throws ArtifactResolutionException
throws ArtifactResolutionException, InvalidVersionSpecificationException
{
ArtifactSpec a = createArtifact( "a", "1.0" );
ArtifactSpec b = a.addDependency( "b", "1.0" );
@ -105,7 +105,7 @@ public class DefaultArtifactCollectorTest
}
public void testResolveWithFilter()
throws ArtifactResolutionException
throws ArtifactResolutionException, InvalidVersionSpecificationException
{
ArtifactSpec a = createArtifact( "a", "1.0" );
ArtifactSpec b = a.addDependency( "b", "1.0" );
@ -124,7 +124,7 @@ public class DefaultArtifactCollectorTest
}
public void testResolveNearestNewestIsNearest()
throws ArtifactResolutionException
throws ArtifactResolutionException, InvalidVersionSpecificationException
{
ArtifactSpec a = createArtifact( "a", "1.0" );
ArtifactSpec b = a.addDependency( "b", "1.0" );
@ -139,7 +139,7 @@ public class DefaultArtifactCollectorTest
}
public void testResolveNearestOldestIsNearest()
throws ArtifactResolutionException
throws ArtifactResolutionException, InvalidVersionSpecificationException
{
ArtifactSpec a = createArtifact( "a", "1.0" );
ArtifactSpec b = a.addDependency( "b", "1.0" );
@ -154,7 +154,7 @@ public class DefaultArtifactCollectorTest
}
public void testResolveNearestWithRanges()
throws ArtifactResolutionException
throws ArtifactResolutionException, InvalidVersionSpecificationException
{
ArtifactSpec a = createArtifact( "a", "1.0" );
ArtifactSpec b = a.addDependency( "b", "1.0" );
@ -169,7 +169,7 @@ public class DefaultArtifactCollectorTest
}
public void testCompatibleRanges()
throws ArtifactResolutionException
throws ArtifactResolutionException, InvalidVersionSpecificationException
{
ArtifactSpec a = createArtifact( "a", "1.0" );
ArtifactSpec b = a.addDependency( "b", "1.0" );
@ -185,7 +185,7 @@ public class DefaultArtifactCollectorTest
}
public void testIncompatibleRanges()
throws ArtifactResolutionException
throws ArtifactResolutionException, InvalidVersionSpecificationException
{
ArtifactSpec a = createArtifact( "a", "1.0" );
ArtifactSpec b = a.addDependency( "b", "1.0" );
@ -204,7 +204,7 @@ public class DefaultArtifactCollectorTest
}
public void testUnboundedRange()
throws ArtifactResolutionException
throws ArtifactResolutionException, InvalidVersionSpecificationException
{
ArtifactSpec a = createArtifact( "a", "1.0" );
ArtifactSpec b = a.addDependency( "b", "1.0" );
@ -220,7 +220,7 @@ public class DefaultArtifactCollectorTest
}
public void testResolveManagedVersion()
throws ArtifactResolutionException
throws ArtifactResolutionException, InvalidVersionSpecificationException
{
ArtifactSpec a = createArtifact( "a", "1.0" );
a.addDependency( "b", "3.0", Artifact.SCOPE_RUNTIME );
@ -233,7 +233,7 @@ public class DefaultArtifactCollectorTest
}
public void testResolveCompileScopeOverTestScope()
throws ArtifactResolutionException
throws ArtifactResolutionException, InvalidVersionSpecificationException
{
ArtifactSpec a = createArtifact( "a", "1.0" );
ArtifactSpec c = createArtifact( "c", "3.0", Artifact.SCOPE_TEST );
@ -249,7 +249,7 @@ public class DefaultArtifactCollectorTest
}
public void testResolveRuntimeScopeOverTestScope()
throws ArtifactResolutionException
throws ArtifactResolutionException, InvalidVersionSpecificationException
{
ArtifactSpec a = createArtifact( "a", "1.0" );
ArtifactSpec c = createArtifact( "c", "3.0", Artifact.SCOPE_TEST );
@ -265,7 +265,7 @@ public class DefaultArtifactCollectorTest
}
public void testResolveCompileScopeOverRuntimeScope()
throws ArtifactResolutionException
throws ArtifactResolutionException, InvalidVersionSpecificationException
{
ArtifactSpec a = createArtifact( "a", "1.0" );
ArtifactSpec c = createArtifact( "c", "3.0", Artifact.SCOPE_RUNTIME );
@ -281,7 +281,7 @@ public class DefaultArtifactCollectorTest
}
public void testResolveCompileScopeOverProvidedScope()
throws ArtifactResolutionException
throws ArtifactResolutionException, InvalidVersionSpecificationException
{
ArtifactSpec a = createArtifact( "a", "1.0" );
ArtifactSpec c = createArtifact( "c", "3.0", Artifact.SCOPE_PROVIDED );
@ -297,7 +297,7 @@ public class DefaultArtifactCollectorTest
}
public void testResolveRuntimeScopeOverProvidedScope()
throws ArtifactResolutionException
throws ArtifactResolutionException, InvalidVersionSpecificationException
{
ArtifactSpec a = createArtifact( "a", "1.0" );
ArtifactSpec c = createArtifact( "c", "3.0", Artifact.SCOPE_PROVIDED );
@ -313,7 +313,7 @@ public class DefaultArtifactCollectorTest
}
public void testProvidedScopeNotTransitive()
throws ArtifactResolutionException
throws ArtifactResolutionException, InvalidVersionSpecificationException
{
ArtifactSpec a = createArtifact( "a", "1.0", Artifact.SCOPE_PROVIDED );
ArtifactSpec b = createArtifact( "b", "1.0" );
@ -323,8 +323,51 @@ public class DefaultArtifactCollectorTest
assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, b.artifact} ), res.getArtifacts() );
}
public void testOptionalNotTransitive()
throws ArtifactResolutionException, InvalidVersionSpecificationException
{
ArtifactSpec a = createArtifact( "a", "1.0" );
ArtifactSpec b = createArtifact( "b", "1.0" );
b.addDependency( "c", "3.0", true );
ArtifactResolutionResult res = collect( createSet( new Object[]{a.artifact, b.artifact} ) );
assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, b.artifact} ), res.getArtifacts() );
}
public void testOptionalIncludedAtRoot()
throws ArtifactResolutionException, InvalidVersionSpecificationException
{
ArtifactSpec a = createArtifact( "a", "1.0" );
createArtifact( "b", "1.0", true );
ArtifactSpec b = createArtifact( "b", "1.0" );
ArtifactResolutionResult res = collect( createSet( new Object[]{a.artifact, b.artifact} ) );
assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, b.artifact} ), res.getArtifacts() );
}
public void disabledtestOptionalNotTransitiveButVersionIsInfluential()
throws ArtifactResolutionException, InvalidVersionSpecificationException
{
ArtifactSpec a = createArtifact( "a", "1.0" );
ArtifactSpec b = createArtifact( "b", "1.0" );
b.addDependency( "c", "3.0", true );
ArtifactSpec d = a.addDependency( "d", "1.0" );
ArtifactSpec e = d.addDependency( "e", "1.0" );
e.addDependency( "c", "2.0" );
ArtifactSpec c = createArtifact( "c", "3.0" );
ArtifactResolutionResult res = collect( createSet( new Object[]{a.artifact, b.artifact} ) );
assertEquals( "Check artifact list",
createSet( new Object[]{a.artifact, b.artifact, c.artifact, d.artifact, e.artifact} ),
res.getArtifacts() );
Artifact artifact = getArtifact( "c", res.getArtifacts() );
assertEquals( "Check version", "3.0", artifact.getVersion() );
}
public void testTestScopeNotTransitive()
throws ArtifactResolutionException
throws ArtifactResolutionException, InvalidVersionSpecificationException
{
ArtifactSpec a = createArtifact( "a", "1.0", Artifact.SCOPE_TEST );
ArtifactSpec b = createArtifact( "b", "1.0" );
@ -377,16 +420,37 @@ public class DefaultArtifactCollectorTest
}
private ArtifactSpec createArtifact( String id, String version )
throws InvalidVersionSpecificationException
{
return createArtifact( id, version, Artifact.SCOPE_COMPILE );
}
private ArtifactSpec createArtifact( String id, String version, String scope )
private ArtifactSpec createArtifact( String id, String version, boolean optional )
throws InvalidVersionSpecificationException
{
ArtifactSpec spec = new ArtifactSpec();
Artifact artifact = artifactFactory.createArtifact( GROUP_ID, id, version, scope, "jar" );
spec.artifact = artifact;
source.artifacts.put( source.getKey( artifact ), spec );
return createArtifact( id, version, Artifact.SCOPE_COMPILE, null, optional );
}
private ArtifactSpec createArtifact( String id, String version, String scope )
throws InvalidVersionSpecificationException
{
return createArtifact( id, version, scope, null, false );
}
private ArtifactSpec createArtifact( String id, String version, String scope, String inheritedScope,
boolean optional )
throws InvalidVersionSpecificationException
{
VersionRange versionRange = VersionRange.createFromVersionSpec( version );
Artifact artifact = artifactFactory.createDependencyArtifact( GROUP_ID, id, versionRange, "jar", null, scope,
inheritedScope, optional );
ArtifactSpec spec = null;
if ( artifact != null )
{
spec = new ArtifactSpec();
spec.artifact = artifact;
source.artifacts.put( source.getKey( artifact ), spec );
}
return spec;
}
@ -402,20 +466,32 @@ public class DefaultArtifactCollectorTest
private Set dependencies = new HashSet();
public ArtifactSpec addDependency( String id, String version )
throws InvalidVersionSpecificationException
{
return addDependency( id, version, null );
}
public ArtifactSpec addDependency( String id, String version, String scope )
throws InvalidVersionSpecificationException
{
ArtifactSpec dep = createArtifact( id, version, scope );
addDependency( dep );
return addDependency( id, version, scope, false );
}
private ArtifactSpec addDependency( String id, String version, String scope, boolean optional )
throws InvalidVersionSpecificationException
{
ArtifactSpec dep = createArtifact( id, version, scope, this.artifact.getScope(), optional );
if ( dep != null )
{
dependencies.add( dep.artifact );
}
return dep;
}
public void addDependency( ArtifactSpec dep )
public ArtifactSpec addDependency( String id, String version, boolean optional )
throws InvalidVersionSpecificationException
{
dependencies.add( dep.artifact );
return addDependency( id, version, Artifact.SCOPE_COMPILE, optional );
}
}
@ -459,11 +535,19 @@ public class DefaultArtifactCollectorTest
{
Artifact d = (Artifact) i.next();
VersionRange versionRange = VersionRange.createFromVersionSpec( d.getVersion() );
VersionRange versionRange;
if ( d.getVersionRange() != null )
{
versionRange = d.getVersionRange();
}
else
{
versionRange = VersionRange.createFromVersionSpec( d.getVersion() );
}
Artifact artifact = artifactFactory.createDependencyArtifact( d.getGroupId(), d.getArtifactId(),
versionRange, d.getType(),
d.getClassifier(), d.getScope(),
inheritedScope );
inheritedScope, d.isOptional() );
if ( artifact != null && ( dependencyFilter == null || dependencyFilter.include( artifact ) ) )
{

View File

@ -1303,6 +1303,7 @@
<type>String</type>
<!-- This default has to be enforced at the maven-artifact layer, to allow
| injection of defaults from <dependencyManagement/>.
| TODO: how can we document it?
|-->
<!-- defaultValue>compile</defaultValue -->
</field>
@ -1325,6 +1326,17 @@
<multiplicity>*</multiplicity>
</association>
</field>
<field>
<name>optional</name>
<version>4.0.0</version>
<description>
Indicates the dependency is optional for use of this library. While the version of the dependency will be
taken into account for dependency calculation if the library is used elsewhere, it will not be passed on
transitively.
</description>
<type>boolean</type>
<defaultValue>false</defaultValue>
</field>
</fields>
<codeSegments>
<codeSegment>

View File

@ -76,7 +76,7 @@ public class MavenMetadataSource
private ArtifactFactory artifactFactory;
private RepositoryMetadataManager repositoryMetadataManager;
// lazily instantiated and cached.
private MavenProject superProject;
@ -190,8 +190,9 @@ public class MavenMetadataSource
Set artifacts = project.createArtifacts( artifactFactory, artifact.getScope(),
artifact.getDependencyFilter() );
List repositories = aggregateRepositoryLists( remoteRepositories, project.getRemoteArtifactRepositories() );
List repositories = aggregateRepositoryLists( remoteRepositories,
project.getRemoteArtifactRepositories() );
result = new ResolutionGroup( pomArtifact, artifacts, repositories );
}
@ -275,7 +276,7 @@ public class MavenMetadataSource
VersionRange versionRange = VersionRange.createFromVersionSpec( d.getVersion() );
Artifact artifact = artifactFactory.createDependencyArtifact( d.getGroupId(), d.getArtifactId(),
versionRange, d.getType(), d.getClassifier(),
scope, inheritedScope );
scope, inheritedScope, d.isOptional() );
if ( Artifact.SCOPE_SYSTEM.equals( scope ) )
{