Adding system scope...uses scope == 'system' and systemPath in dependency. SystemPath was chosen over mappings inside the setings.xml for scalability, heritability, and injectability (via managed deps).

git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@264960 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
John Dennis Casey 2005-08-31 07:39:01 +00:00
parent 94ab6a4076
commit 8201bb9d18
19 changed files with 357 additions and 107 deletions

View File

@ -73,74 +73,91 @@ public class DefaultArtifactResolver
boolean force )
throws ArtifactResolutionException
{
// skip artifacts with a file - they are already resolved
if ( artifact != null && artifact.getFile() == null )
if ( artifact != null )
{
// ----------------------------------------------------------------------
// Check for the existence of the artifact in the specified local
// ArtifactRepository. If it is present then simply return as the
// request for resolution has been satisfied.
// ----------------------------------------------------------------------
String localPath = localRepository.pathOf( artifact );
artifact.setFile( new File( localRepository.getBasedir(), localPath ) );
try
if ( Artifact.SCOPE_SYSTEM.equals( artifact.getScope() ) )
{
transformationManager.transformForResolve( artifact, remoteRepositories, localRepository );
File systemFile = artifact.getFile();
if ( !systemFile.exists() )
{
throw new ArtifactResolutionException( "System artifact: " + artifact.getId()
+ " not found in path: " + systemFile, artifact );
}
else
{
artifact.setResolved( true );
}
}
catch ( ArtifactMetadataRetrievalException e )
// skip artifacts with a file - they are already resolved
else if ( artifact.getFile() == null )
{
throw new ArtifactResolutionException( e.getMessage(), artifact, remoteRepositories, e );
}
// ----------------------------------------------------------------------
// Check for the existence of the artifact in the specified local
// ArtifactRepository. If it is present then simply return as the
// request for resolution has been satisfied.
// ----------------------------------------------------------------------
String localPath = localRepository.pathOf( artifact );
artifact.setFile( new File( localRepository.getBasedir(), localPath ) );
File destination = artifact.getFile();
if ( !destination.exists() || force )
{
try
{
if ( artifact.getRepository() != null )
{
// the transformations discovered the artifact - so use it exclusively
wagonManager.getArtifact( artifact, artifact.getRepository() );
}
else
{
wagonManager.getArtifact( artifact, remoteRepositories );
}
if ( !artifact.isResolved() )
{
throw new ArtifactResolutionException(
"Failed to resolve artifact, possibly due to a repository list that is not appropriately equipped for this artifact's metadata.",
artifact, remoteRepositories );
}
// must be after the artifact is downloaded
for ( Iterator i = artifact.getMetadataList().iterator(); i.hasNext(); )
{
ArtifactMetadata metadata = (ArtifactMetadata) i.next();
metadata.storeInLocalRepository( localRepository );
}
}
catch ( ResourceDoesNotExistException e )
{
throw new ArtifactResolutionException( e.getMessage(), artifact, remoteRepositories, e );
}
catch ( TransferFailedException e )
{
throw new ArtifactResolutionException( e.getMessage(), artifact, remoteRepositories, e );
transformationManager.transformForResolve( artifact, remoteRepositories, localRepository );
}
catch ( ArtifactMetadataRetrievalException e )
{
throw new ArtifactResolutionException( e.getMessage(), artifact, remoteRepositories, e );
}
}
else if ( destination.exists() )
{
// locally resolved...no need to hit the remote repo.
artifact.setResolved( true );
File destination = artifact.getFile();
if ( !destination.exists() || force )
{
try
{
if ( artifact.getRepository() != null )
{
// the transformations discovered the artifact - so use it exclusively
wagonManager.getArtifact( artifact, artifact.getRepository() );
}
else
{
wagonManager.getArtifact( artifact, remoteRepositories );
}
if ( !artifact.isResolved() )
{
throw new ArtifactResolutionException(
"Failed to resolve artifact, possibly due to a repository list that is not appropriately equipped for this artifact's metadata.",
artifact, remoteRepositories );
}
// must be after the artifact is downloaded
for ( Iterator i = artifact.getMetadataList().iterator(); i.hasNext(); )
{
ArtifactMetadata metadata = (ArtifactMetadata) i.next();
metadata.storeInLocalRepository( localRepository );
}
}
catch ( ResourceDoesNotExistException e )
{
throw new ArtifactResolutionException( e.getMessage(), artifact, remoteRepositories, e );
}
catch ( TransferFailedException e )
{
throw new ArtifactResolutionException( e.getMessage(), artifact, remoteRepositories, e );
}
catch ( ArtifactMetadataRetrievalException e )
{
throw new ArtifactResolutionException( e.getMessage(), artifact, remoteRepositories, e );
}
}
else if ( destination.exists() )
{
// locally resolved...no need to hit the remote repo.
artifact.setResolved( true );
}
}
}
}

View File

@ -49,6 +49,8 @@ public interface Artifact
String SCOPE_RUNTIME = "runtime";
String SCOPE_PROVIDED = "provided";
String SCOPE_SYSTEM = "system";
String getGroupId();

View File

@ -35,11 +35,14 @@ public class ScopeArtifactFilter
private final boolean testScope;
private final boolean providedScope;
private final boolean systemScope;
public ScopeArtifactFilter( String scope )
{
if ( DefaultArtifact.SCOPE_COMPILE.equals( scope ) )
{
systemScope = true;
providedScope = true;
compileScope = true;
runtimeScope = false;
@ -47,6 +50,7 @@ public class ScopeArtifactFilter
}
else if ( DefaultArtifact.SCOPE_RUNTIME.equals( scope ) )
{
systemScope = false;
providedScope = false;
compileScope = true;
runtimeScope = true;
@ -54,6 +58,7 @@ public class ScopeArtifactFilter
}
else if ( DefaultArtifact.SCOPE_TEST.equals( scope ) )
{
systemScope = true;
providedScope = true;
compileScope = true;
runtimeScope = true;
@ -61,6 +66,7 @@ public class ScopeArtifactFilter
}
else
{
systemScope = false;
providedScope = false;
compileScope = false;
runtimeScope = false;
@ -70,22 +76,26 @@ public class ScopeArtifactFilter
public boolean include( Artifact artifact )
{
if ( DefaultArtifact.SCOPE_COMPILE.equals( artifact.getScope() ) )
if ( Artifact.SCOPE_COMPILE.equals( artifact.getScope() ) )
{
return compileScope;
}
else if ( DefaultArtifact.SCOPE_RUNTIME.equals( artifact.getScope() ) )
else if ( Artifact.SCOPE_RUNTIME.equals( artifact.getScope() ) )
{
return runtimeScope;
}
else if ( DefaultArtifact.SCOPE_TEST.equals( artifact.getScope() ) )
else if ( Artifact.SCOPE_TEST.equals( artifact.getScope() ) )
{
return testScope;
}
else if ( DefaultArtifact.SCOPE_PROVIDED.equals( artifact.getScope() ) )
else if ( Artifact.SCOPE_PROVIDED.equals( artifact.getScope() ) )
{
return providedScope;
}
else if ( Artifact.SCOPE_SYSTEM.equals( artifact.getScope() ) )
{
return systemScope;
}
else
{
// TODO: should this be true? Does it even happen?

View File

@ -178,6 +178,8 @@ it0061: Verify that deployment of artifacts to a legacy-layout repository
it0062: Test that a deployment of a snapshot falls back to a non-snapshot repository if no snapshot repository is
specified.
it0063: Test the use of a system scoped dependency to tools.jar.
-------------------------------------------------------------------------------
- generated sources

View File

@ -1,3 +1,4 @@
it0063
it0062
it0061
it0060

View File

@ -1,2 +1 @@
compile
package

View File

@ -0,0 +1,4 @@
target/classes/org/apache/maven/it0001/Person.class
target/test-classes/org/apache/maven/it0001/PersonTest.class
target/maven-core-it0063-1.0.jar
target/maven-core-it0063-1.0.jar!/it0001.properties

View File

@ -0,0 +1 @@
package

View File

@ -0,0 +1,22 @@
<model>
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.maven.it</groupId>
<artifactId>maven-core-it0063</artifactId>
<packaging>jar</packaging>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>jdk-tools</groupId>
<artifactId>jdk-tools</artifactId>
<version>1.4.2</version>
<scope>system</scope>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</model>

View File

@ -0,0 +1,18 @@
package org.apache.maven.it0001;
import com.sun.tools.javac.Main;
public class Person
{
private String name;
public void setName( String name )
{
this.name = name;
}
public String getName()
{
return name;
}
}

View File

@ -0,0 +1 @@
name = jason

View File

@ -0,0 +1,16 @@
package org.apache.maven.it0001;
import junit.framework.TestCase;
public class PersonTest
extends TestCase
{
public void testPerson()
{
Person person = new Person();
person.setName( "foo" );
assertEquals( "foo", person.getName() );
}
}

View File

@ -1253,6 +1253,12 @@
|-->
<!-- defaultValue>compile</defaultValue -->
</field>
<field>
<name>systemPath</name>
<version>4.0.0</version>
<description>FOR SYSTEM SCOPE ONLY. This specifies the path on the filesystem for this dependency.</description>
<type>String</type>
</field>
<field>
<name>exclusions</name>
<version>4.0.0</version>

View File

@ -579,7 +579,9 @@ public class DefaultMavenProjectBuilder
// TODO: Clean this up...we're using this to 'jump' the interpolation step for model properties not expressed in XML.
// [BP] - Can this above comment be explained?
// We don't need all the project methods that are added over those in the model, but we do need basedir
Map context = Collections.singletonMap( "basedir", project.getBasedir() );
Map context = new HashMap( System.getProperties() );
context.put( "basedir", project.getBasedir() );
model = modelInterpolator.interpolate( model, context );
// interpolation is before injection, because interpolation is off-limits in the injected variables

View File

@ -347,7 +347,8 @@ public class MavenProject
if ( isAddedToClasspath( a ) )
{
// TODO: let the scope handler deal with this
if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_PROVIDED.equals( a.getScope() ) )
if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_PROVIDED.equals( a.getScope() )
|| Artifact.SCOPE_SYSTEM.equals( a.getScope() ) )
{
String refId = getProjectReferenceId( a.getGroupId(), a.getArtifactId() );
MavenProject project = (MavenProject) projectReferences.get( refId );
@ -382,7 +383,8 @@ public class MavenProject
if ( isAddedToClasspath( a ) )
{
// TODO: let the scope handler deal with this
if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_PROVIDED.equals( a.getScope() ) )
if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_PROVIDED.equals( a.getScope() )
|| Artifact.SCOPE_SYSTEM.equals( a.getScope() ) )
{
list.add( a );
}
@ -407,7 +409,8 @@ public class MavenProject
Artifact a = (Artifact) i.next();
// TODO: let the scope handler deal with this
if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_PROVIDED.equals( a.getScope() ) )
if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_PROVIDED.equals( a.getScope() )
|| Artifact.SCOPE_SYSTEM.equals( a.getScope() ) )
{
Dependency dependency = new Dependency();

View File

@ -38,6 +38,7 @@ import org.apache.maven.project.ProjectBuildingException;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.util.StringUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
@ -72,7 +73,7 @@ public class MavenMetadataSource
public ResolutionGroup retrieve( Artifact artifact, ArtifactRepository localRepository, List remoteRepositories )
throws ArtifactMetadataRetrievalException
{
MavenProject project;
MavenProject project = null;
Artifact pomArtifact;
boolean done = false;
@ -82,65 +83,76 @@ public class MavenMetadataSource
pomArtifact = artifactFactory.createProjectArtifact( artifact.getGroupId(), artifact.getArtifactId(),
artifact.getVersion(), artifact.getScope() );
try
if ( Artifact.SCOPE_SYSTEM.equals( artifact.getScope() ) )
{
project = mavenProjectBuilder.buildFromRepository( pomArtifact, remoteRepositories, localRepository );
done = true;
}
catch ( InvalidModelException e )
else
{
getLogger().warn( "POM for: \'" + pomArtifact.getId() + "\' does not appear to be valid. Its will be ignored for artifact resolution." );
project = null;
}
catch ( ProjectBuildingException e )
{
throw new ArtifactMetadataRetrievalException( "Unable to read the metadata file", e );
}
if ( project != null )
{
Relocation relocation = null;
DistributionManagement distMgmt = project.getDistributionManagement();
if ( distMgmt != null )
try
{
relocation = distMgmt.getRelocation();
project = mavenProjectBuilder
.buildFromRepository( pomArtifact, remoteRepositories, localRepository );
}
catch ( InvalidModelException e )
{
getLogger()
.warn(
"POM for: \'" + pomArtifact.getId()
+ "\' does not appear to be valid. Its will be ignored for artifact resolution." );
project = null;
}
catch ( ProjectBuildingException e )
{
throw new ArtifactMetadataRetrievalException( "Unable to read the metadata file", e );
}
if ( relocation != null )
if ( project != null )
{
if ( relocation.getGroupId() != null )
Relocation relocation = null;
DistributionManagement distMgmt = project.getDistributionManagement();
if ( distMgmt != null )
{
artifact.setGroupId( relocation.getGroupId() );
}
if ( relocation.getArtifactId() != null )
{
artifact.setArtifactId( relocation.getArtifactId() );
}
if ( relocation.getVersion() != null )
{
artifact.setVersion( relocation.getVersion() );
relocation = distMgmt.getRelocation();
}
String message = "\n This artifact has been relocated to " + artifact.getGroupId() + ":"
+ artifact.getArtifactId() + ":" + artifact.getVersion() + ".\n";
if ( relocation.getMessage() != null )
if ( relocation != null )
{
message += " " + relocation.getMessage() + "\n";
}
if ( relocation.getGroupId() != null )
{
artifact.setGroupId( relocation.getGroupId() );
}
if ( relocation.getArtifactId() != null )
{
artifact.setArtifactId( relocation.getArtifactId() );
}
if ( relocation.getVersion() != null )
{
artifact.setVersion( relocation.getVersion() );
}
getLogger().warn( message + "\n" );
String message = "\n This artifact has been relocated to " + artifact.getGroupId() + ":"
+ artifact.getArtifactId() + ":" + artifact.getVersion() + ".\n";
if ( relocation.getMessage() != null )
{
message += " " + relocation.getMessage() + "\n";
}
getLogger().warn( message + "\n" );
}
else
{
done = true;
}
}
else
{
done = true;
}
}
else
{
done = true;
}
}
while ( !done );
@ -250,6 +262,11 @@ public class MavenMetadataSource
Artifact artifact = artifactFactory.createDependencyArtifact( d.getGroupId(), d.getArtifactId(),
versionRange, d.getType(), d.getClassifier(),
scope, inheritedScope );
if ( Artifact.SCOPE_SYSTEM.equals( scope ) )
{
artifact.setFile( new File( d.getSystemPath() ) );
}
if ( artifact != null && ( dependencyFilter == null || dependencyFilter.include( artifact ) ) )
{

View File

@ -83,6 +83,7 @@ public class DefaultModelDefaultsInjector
if ( dep.getScope() == null && def.getScope() != null )
{
dep.setScope( def.getScope() );
dep.setSystemPath( def.getSystemPath() );
}
if ( dep.getVersion() == null && def.getVersion() != null )

View File

@ -16,6 +16,7 @@ package org.apache.maven.project.validation;
* limitations under the License.
*/
import org.apache.maven.artifact.Artifact;
import org.apache.maven.model.Build;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.DependencyManagement;
@ -23,6 +24,7 @@ import org.apache.maven.model.Model;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.ReportPlugin;
import org.apache.maven.model.Reporting;
import org.codehaus.plexus.util.StringUtils;
import java.util.Iterator;
import java.util.List;
@ -62,6 +64,15 @@ public class DefaultModelValidator
validateSubElementStringNotEmpty( d, "dependencies.dependency.type", result, d.getType() );
validateSubElementStringNotEmpty( d, "dependencies.dependency.version", result, d.getVersion() );
if ( Artifact.SCOPE_SYSTEM.equals( d.getScope() ) && StringUtils.isEmpty( d.getSystemPath() ) )
{
result.addMessage( "For dependency " + d + ": system-scoped dependency must specify systemPath." );
}
else if ( !Artifact.SCOPE_SYSTEM.equals( d.getScope() ) && StringUtils.isNotEmpty( d.getSystemPath() ) )
{
result.addMessage( "For dependency " + d + ": only dependency with system scope can specify systemPath." );
}
}
DependencyManagement mgmt = model.getDependencyManagement();
@ -76,6 +87,15 @@ public class DefaultModelValidator
validateSubElementStringNotEmpty( d, "dependencyManagement.dependencies.dependency.groupId", result,
d.getGroupId() );
if ( Artifact.SCOPE_SYSTEM.equals( d.getScope() ) && StringUtils.isEmpty( d.getSystemPath() ) )
{
result.addMessage( "For managed dependency " + d + ": system-scoped dependency must specify systemPath." );
}
else if ( !Artifact.SCOPE_SYSTEM.equals( d.getScope() ) && StringUtils.isNotEmpty( d.getSystemPath() ) )
{
result.addMessage( "For managed dependency " + d + ": only dependency with system scope can specify systemPath." );
}
}
}

View File

@ -0,0 +1,108 @@
package org.apache.maven.project.artifact;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.ArtifactUtils;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.DependencyManagement;
import org.apache.maven.model.Model;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.injection.ModelDefaultsInjector;
import org.codehaus.plexus.PlexusTestCase;
import java.util.Map;
public class MavenMetadataSourceTest
extends PlexusTestCase
{
public void testShouldUseCompileScopeIfDependencyScopeEmpty() throws Exception
{
String groupId = "org.apache.maven";
String artifactId = "maven-model";
Dependency dep = new Dependency();
dep.setGroupId(groupId);
dep.setArtifactId(artifactId);
dep.setVersion("2.0-alpha-3");
Model model = new Model();
model.addDependency(dep);
MavenProject project = new MavenProject( model );
ArtifactFactory factory = (ArtifactFactory) lookup( ArtifactFactory.ROLE );
project.setArtifacts( project.createArtifacts(factory, null, null) );
String key = ArtifactUtils.versionlessKey(groupId, artifactId );
Map artifactMap = project.getArtifactMap();
assertNotNull( "artifact-map should not be null.", artifactMap );
assertEquals( "artifact-map should contain 1 element.", 1, artifactMap.size() );
Artifact artifact = (Artifact) artifactMap.get( key );
assertNotNull( "dependency artifact not found in map.", artifact );
assertEquals( "dependency artifact has wrong scope.", Artifact.SCOPE_COMPILE, artifact.getScope() );
//check for back-propagation of default scope.
assertEquals( "default scope NOT back-propagated to dependency.", Artifact.SCOPE_COMPILE, dep.getScope() );
}
public void testShouldUseInjectedTestScopeFromDependencyManagement() throws Exception
{
String groupId = "org.apache.maven";
String artifactId = "maven-model";
Dependency dep = new Dependency();
dep.setGroupId(groupId);
dep.setArtifactId(artifactId);
dep.setVersion("2.0-alpha-3");
Model model = new Model();
model.addDependency(dep);
Dependency mgd = new Dependency();
mgd.setGroupId( groupId);
mgd.setArtifactId( artifactId );
mgd.setScope( Artifact.SCOPE_TEST);
DependencyManagement depMgmt = new DependencyManagement();
depMgmt.addDependency(mgd);
model.setDependencyManagement(depMgmt);
MavenProject project = new MavenProject( model );
ModelDefaultsInjector injector = (ModelDefaultsInjector) lookup( ModelDefaultsInjector.ROLE );
injector.injectDefaults( model );
ArtifactFactory factory = (ArtifactFactory) lookup( ArtifactFactory.ROLE );
project.setArtifacts( project.createArtifacts(factory, null, null) );
String key = ArtifactUtils.versionlessKey(groupId, artifactId );
Map artifactMap = project.getArtifactMap();
assertNotNull( "artifact-map should not be null.", artifactMap );
assertEquals( "artifact-map should contain 1 element.", 1, artifactMap.size() );
Artifact artifact = (Artifact) artifactMap.get( key );
assertNotNull( "dependency artifact not found in map.", artifact );
assertEquals( "dependency artifact has wrong scope.", Artifact.SCOPE_TEST, artifact.getScope() );
//check for back-propagation of default scope.
assertEquals( "default scope NOT back-propagated to dependency.", Artifact.SCOPE_TEST, dep.getScope() );
}
}