Bug 433102 - Allow nested <dependencies> groups Made <dependencies> element accept other <dependencies> elements as children
Project: http://git-wip-us.apache.org/repos/asf/maven-aether/repo Commit: http://git-wip-us.apache.org/repos/asf/maven-aether/commit/d981a952 Tree: http://git-wip-us.apache.org/repos/asf/maven-aether/tree/d981a952 Diff: http://git-wip-us.apache.org/repos/asf/maven-aether/diff/d981a952 Branch: refs/heads/ant-tasks Commit: d981a952a5bbe3a4a8ce0bbfcf6b56266c9eecca Parents: 7f4fa03 Author: Benjamin Bentmann <bentm...@sonatype.com> Authored: Sun Apr 20 00:18:08 2014 +0200 Committer: Benjamin Bentmann <bentm...@sonatype.com> Committed: Sun Apr 20 00:18:08 2014 +0200 ---------------------------------------------------------------------- README.md | 7 +- .../java/org/eclipse/aether/ant/AntRepoSys.java | 135 +++++++++++-------- .../eclipse/aether/ant/types/Dependencies.java | 51 +++++-- .../eclipse/aether/ant/types/Dependency.java | 1 + .../aether/ant/types/DependencyContainer.java | 22 +++ .../org/eclipse/aether/ant/ResolveTest.java | 12 ++ src/test/resources/ant/Resolve/ant.xml | 17 ++- 7 files changed, 172 insertions(+), 73 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/maven-aether/blob/d981a952/README.md ---------------------------------------------------------------------- diff --git a/README.md b/README.md index afc62e5..e5ffb9c 100644 --- a/README.md +++ b/README.md @@ -132,7 +132,7 @@ Dependencies are used to to create classpaths or filesets. They are used by the `<resolve>`-task, which collects the artifacts belonging to the dependencies transitively. - <dependency coords="g:a:v"/> + <dependency coords="g:a:v:scope"/> <dependency groupId="g" artifactId="a" version="v" classifier="c" type="jar" scope="runtime"> <exclusion coords="g:a"/> @@ -145,6 +145,11 @@ transitively. <exclusion coords="g:a"/> <!-- global exclusion for all dependencies of this group --> </dependencies> + <dependencies> + <dependency coords="test:artifact:1.0:runtime"/> + <dependencies refid="deps"/> <!-- nested dependency collection merged into this one --> + </dependencies> + <dependencies id="depsFromPom" pomRef="pom"/> <dependencies id="depsFromPlainTextFile" file="dependencies.txt"/> http://git-wip-us.apache.org/repos/asf/maven-aether/blob/d981a952/src/main/java/org/eclipse/aether/ant/AntRepoSys.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/eclipse/aether/ant/AntRepoSys.java b/src/main/java/org/eclipse/aether/ant/AntRepoSys.java index cf81357..364173f 100644 --- a/src/main/java/org/eclipse/aether/ant/AntRepoSys.java +++ b/src/main/java/org/eclipse/aether/ant/AntRepoSys.java @@ -61,6 +61,7 @@ import org.eclipse.aether.ant.listeners.AntTransferListener; import org.eclipse.aether.ant.types.Authentication; import org.eclipse.aether.ant.types.Dependencies; import org.eclipse.aether.ant.types.Dependency; +import org.eclipse.aether.ant.types.DependencyContainer; import org.eclipse.aether.ant.types.Exclusion; import org.eclipse.aether.ant.types.LocalRepository; import org.eclipse.aether.ant.types.Mirror; @@ -617,79 +618,99 @@ public class AntRepoSys if ( dependencies != null ) { - List<Exclusion> globalExclusions = dependencies.getExclusions(); - Collection<String> ids = new HashSet<String>(); + populateCollectRequest( collectRequest, task, session, dependencies, Collections.<Exclusion> emptyList() ); + } + + task.getProject().log( "Collecting dependencies", Project.MSG_VERBOSE ); + + CollectResult result; + try + { + result = getSystem().collectDependencies( session, collectRequest ); + } + catch ( DependencyCollectionException e ) + { + throw new BuildException( "Could not collect dependencies: " + e.getMessage(), e ); + } + + return result; + } + + private void populateCollectRequest( CollectRequest collectRequest, Task task, RepositorySystemSession session, + Dependencies dependencies, List<Exclusion> exclusions ) + { + List<Exclusion> globalExclusions = exclusions; + if ( !dependencies.getExclusions().isEmpty() ) + { + globalExclusions = new ArrayList<Exclusion>( exclusions ); + globalExclusions.addAll( dependencies.getExclusions() ); + } + + Collection<String> ids = new HashSet<String>(); - for ( Dependency dep : dependencies.getDependencies() ) + for ( DependencyContainer container : dependencies.getDependencyContainers() ) + { + if ( container instanceof Dependency ) { + Dependency dep = (Dependency) container; ids.add( dep.getVersionlessKey() ); collectRequest.addDependency( ConverterUtils.toDependency( dep, globalExclusions, session ) ); } - - if ( dependencies.getPom() != null ) + else { - Model model = dependencies.getPom().getModel( task ); - for ( org.apache.maven.model.Dependency dep : model.getDependencies() ) - { - Dependency dependency = new Dependency(); - dependency.setArtifactId( dep.getArtifactId() ); - dependency.setClassifier( dep.getClassifier() ); - dependency.setGroupId( dep.getGroupId() ); - dependency.setScope( dep.getScope() ); - dependency.setType( dep.getType() ); - dependency.setVersion( dep.getVersion() ); - if ( ids.contains( dependency.getVersionlessKey() ) ) - { - project.log( "Ignoring dependency " + dependency.getVersionlessKey() + " from " + model.getId() - + ", already declared locally", Project.MSG_VERBOSE ); - continue; - } - if ( dep.getSystemPath() != null && dep.getSystemPath().length() > 0 ) - { - dependency.setSystemPath( task.getProject().resolveFile( dep.getSystemPath() ) ); - } - for ( org.apache.maven.model.Exclusion exc : dep.getExclusions() ) - { - Exclusion exclusion = new Exclusion(); - exclusion.setGroupId( exc.getGroupId() ); - exclusion.setArtifactId( exc.getArtifactId() ); - exclusion.setClassifier( "*" ); - exclusion.setExtension( "*" ); - dependency.addExclusion( exclusion ); - } - collectRequest.addDependency( ConverterUtils.toDependency( dependency, globalExclusions, session ) ); - } + populateCollectRequest( collectRequest, task, session, (Dependencies) container, globalExclusions ); } + } - if ( dependencies.getFile() != null ) + if ( dependencies.getPom() != null ) + { + Model model = dependencies.getPom().getModel( task ); + for ( org.apache.maven.model.Dependency dep : model.getDependencies() ) { - List<Dependency> deps = readDependencies( dependencies.getFile() ); - for ( Dependency dependency : deps ) + Dependency dependency = new Dependency(); + dependency.setArtifactId( dep.getArtifactId() ); + dependency.setClassifier( dep.getClassifier() ); + dependency.setGroupId( dep.getGroupId() ); + dependency.setScope( dep.getScope() ); + dependency.setType( dep.getType() ); + dependency.setVersion( dep.getVersion() ); + if ( ids.contains( dependency.getVersionlessKey() ) ) { - if ( ids.contains( dependency.getVersionlessKey() ) ) - { - project.log( "Ignoring dependency " + dependency.getVersionlessKey() + " from " - + dependencies.getFile() + ", already declared locally", Project.MSG_VERBOSE ); - continue; - } - collectRequest.addDependency( ConverterUtils.toDependency( dependency, globalExclusions, session ) ); + project.log( "Ignoring dependency " + dependency.getVersionlessKey() + " from " + model.getId() + + ", already declared locally", Project.MSG_VERBOSE ); + continue; + } + if ( dep.getSystemPath() != null && dep.getSystemPath().length() > 0 ) + { + dependency.setSystemPath( task.getProject().resolveFile( dep.getSystemPath() ) ); } + for ( org.apache.maven.model.Exclusion exc : dep.getExclusions() ) + { + Exclusion exclusion = new Exclusion(); + exclusion.setGroupId( exc.getGroupId() ); + exclusion.setArtifactId( exc.getArtifactId() ); + exclusion.setClassifier( "*" ); + exclusion.setExtension( "*" ); + dependency.addExclusion( exclusion ); + } + collectRequest.addDependency( ConverterUtils.toDependency( dependency, globalExclusions, session ) ); } } - task.getProject().log( "Collecting dependencies", Project.MSG_VERBOSE ); - - CollectResult result; - try - { - result = getSystem().collectDependencies( session, collectRequest ); - } - catch ( DependencyCollectionException e ) + if ( dependencies.getFile() != null ) { - throw new BuildException( "Could not collect dependencies: " + e.getMessage(), e ); + List<Dependency> deps = readDependencies( dependencies.getFile() ); + for ( Dependency dependency : deps ) + { + if ( ids.contains( dependency.getVersionlessKey() ) ) + { + project.log( "Ignoring dependency " + dependency.getVersionlessKey() + " from " + + dependencies.getFile() + ", already declared locally", Project.MSG_VERBOSE ); + continue; + } + collectRequest.addDependency( ConverterUtils.toDependency( dependency, globalExclusions, session ) ); + } } - - return result; } private List<Dependency> readDependencies( File file ) http://git-wip-us.apache.org/repos/asf/maven-aether/blob/d981a952/src/main/java/org/eclipse/aether/ant/types/Dependencies.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/eclipse/aether/ant/types/Dependencies.java b/src/main/java/org/eclipse/aether/ant/types/Dependencies.java index d26627d..35702ca 100644 --- a/src/main/java/org/eclipse/aether/ant/types/Dependencies.java +++ b/src/main/java/org/eclipse/aether/ant/types/Dependencies.java @@ -25,16 +25,19 @@ import org.apache.tools.ant.types.Reference; */ public class Dependencies extends DataType + implements DependencyContainer { private File file; private Pom pom; - private List<Dependency> dependencies = new ArrayList<Dependency>(); + private List<DependencyContainer> containers = new ArrayList<DependencyContainer>(); private List<Exclusion> exclusions = new ArrayList<Exclusion>(); + private boolean nestedDependencies; + protected Dependencies getRef() { return (Dependencies) getCheckedRef(); @@ -53,16 +56,20 @@ public class Dependencies throw new BuildException( "A <pom> used for dependency resolution has to be backed by a pom.xml file" ); } Map<String, String> ids = new HashMap<String, String>(); - for ( Dependency dependency : dependencies ) + for ( DependencyContainer container : containers ) { - dependency.validate( task ); - String id = dependency.getVersionlessKey(); - String collision = ids.put( id, dependency.getVersion() ); - if ( collision != null ) + container.validate( task ); + if ( container instanceof Dependency ) { - throw new BuildException( "You must not declare multiple <dependency> elements" - + " with the same coordinates but got " + id + " -> " + collision + " vs " - + dependency.getVersion() ); + Dependency dependency = (Dependency) container; + String id = dependency.getVersionlessKey(); + String collision = ids.put( id, dependency.getVersion() ); + if ( collision != null ) + { + throw new BuildException( "You must not declare multiple <dependency> elements" + + " with the same coordinates but got " + id + " -> " + collision + " vs " + + dependency.getVersion() ); + } } } } @@ -70,7 +77,7 @@ public class Dependencies public void setRefid( Reference ref ) { - if ( pom != null || !exclusions.isEmpty() || !dependencies.isEmpty() ) + if ( pom != null || !exclusions.isEmpty() || !containers.isEmpty() ) { throw noChildrenAllowed(); } @@ -130,21 +137,37 @@ public class Dependencies { throw new BuildException( "You must not specify both a text file and a POM to list dependencies" ); } + if ( ( file != null || pom != null ) && nestedDependencies ) + { + throw new BuildException( "You must not specify both a file/POM and nested dependency collections" ); + } } public void addDependency( Dependency dependency ) { checkChildrenAllowed(); - this.dependencies.add( dependency ); + containers.add( dependency ); + } + + public void addDependencies( Dependencies dependencies ) + { + checkChildrenAllowed(); + if ( dependencies == this ) + { + throw circularReference(); + } + containers.add( dependencies ); + nestedDependencies = true; + checkExternalSources(); } - public List<Dependency> getDependencies() + public List<DependencyContainer> getDependencyContainers() { if ( isReference() ) { - return getRef().getDependencies(); + return getRef().getDependencyContainers(); } - return dependencies; + return containers; } public void addExclusion( Exclusion exclusion ) http://git-wip-us.apache.org/repos/asf/maven-aether/blob/d981a952/src/main/java/org/eclipse/aether/ant/types/Dependency.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/eclipse/aether/ant/types/Dependency.java b/src/main/java/org/eclipse/aether/ant/types/Dependency.java index 4343a4a..9ca40bd 100644 --- a/src/main/java/org/eclipse/aether/ant/types/Dependency.java +++ b/src/main/java/org/eclipse/aether/ant/types/Dependency.java @@ -26,6 +26,7 @@ import org.apache.tools.ant.types.Reference; */ public class Dependency extends DataType + implements DependencyContainer { private String groupId; http://git-wip-us.apache.org/repos/asf/maven-aether/blob/d981a952/src/main/java/org/eclipse/aether/ant/types/DependencyContainer.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/eclipse/aether/ant/types/DependencyContainer.java b/src/main/java/org/eclipse/aether/ant/types/DependencyContainer.java new file mode 100644 index 0000000..b05b3e5 --- /dev/null +++ b/src/main/java/org/eclipse/aether/ant/types/DependencyContainer.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2014 Sonatype, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sonatype, Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.aether.ant.types; + +import org.apache.tools.ant.Task; + +/** + */ +public interface DependencyContainer +{ + + void validate( Task task ); + +} http://git-wip-us.apache.org/repos/asf/maven-aether/blob/d981a952/src/test/java/org/eclipse/aether/ant/ResolveTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/eclipse/aether/ant/ResolveTest.java b/src/test/java/org/eclipse/aether/ant/ResolveTest.java index 921f80d..cf3d545 100644 --- a/src/test/java/org/eclipse/aether/ant/ResolveTest.java +++ b/src/test/java/org/eclipse/aether/ant/ResolveTest.java @@ -108,4 +108,16 @@ public class ResolveTest assertThat( "aether-api was resolved as a property", prop, nullValue() ); } + public void testResolveNestedDependencyCollections() + { + executeTarget( "testResolveNestedDependencyCollections" ); + + String prop = getProject().getProperty( "test.resolve.path.org.eclipse.aether:aether-spi:jar" ); + assertThat( "aether-spi was not resolved as a property", prop, notNullValue() ); + prop = getProject().getProperty( "test.resolve.path.org.eclipse.aether:aether-util:jar" ); + assertThat( "aether-util was not resolved as a property", prop, notNullValue() ); + prop = getProject().getProperty( "test.resolve.path.org.eclipse.aether:aether-api:jar" ); + assertThat( "aether-api was resolved as a property", prop, nullValue() ); + } + } http://git-wip-us.apache.org/repos/asf/maven-aether/blob/d981a952/src/test/resources/ant/Resolve/ant.xml ---------------------------------------------------------------------- diff --git a/src/test/resources/ant/Resolve/ant.xml b/src/test/resources/ant/Resolve/ant.xml index e7c4890..4ff378f 100644 --- a/src/test/resources/ant/Resolve/ant.xml +++ b/src/test/resources/ant/Resolve/ant.xml @@ -63,7 +63,7 @@ <target name="testResolveAttachments"> <repo:resolve> <dependencies> - <dependency groupid="org.eclipse.aether" artifactid="aether-impl" version="0.9.0.M3" /> + <dependency groupid="org.eclipse.aether" artifactid="aether-impl" version="0.9.0.v20140226" /> </dependencies> <files dir="${build.dir}/resolve-attachments/" layout="javadoc/{groupId}-{artifactId}-{classifier}.{extension}" attachments="javadoc"/> <files dir="${build.dir}/resolve-attachments/" layout="sources/{groupId}-{artifactId}-{classifier}.{extension}" attachments="sources"/> @@ -87,4 +87,19 @@ </repo:resolve> </target> + <target name="testResolveNestedDependencyCollections"> + <repo:resolve> + <dependencies> + <dependencies> + <dependency groupid="org.eclipse.aether" artifactid="aether-spi" version="0.9.0.v20140226" /> + </dependencies> + <dependencies> + <dependency groupid="org.eclipse.aether" artifactid="aether-util" version="0.9.0.v20140226" /> + </dependencies> + <exclusion coords="org.eclipse.aether:aether-api"/> + </dependencies> + <properties prefix="test.resolve.path" classpath="runtime"/> + </repo:resolve> + </target> + </project>