This is an automated email from the ASF dual-hosted git repository.
maartenc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ant-ivy.git
The following commit(s) were added to refs/heads/master by this push:
new 934bf192 IVY-1485, IVY-1661 : reverted old change causing issues with
replacing dynamic revisions on deliver when there were multiple configurations.
934bf192 is described below
commit 934bf1923392ebd1148d7fe3f56febe8fb86bd93
Author: Maarten Coene <[email protected]>
AuthorDate: Sun Aug 31 12:32:47 2025 +0200
IVY-1485, IVY-1661 : reverted old change causing issues with replacing
dynamic revisions on deliver when there were multiple configurations.
---
asciidoc/release-notes.adoc | 3 +
asciidoc/use/deliver.adoc | 2 +-
.../org/apache/ivy/core/resolve/ResolveEngine.java | 107 +++++--------
test/java/org/apache/ivy/ant/IvyDeliverTest.java | 172 +++++++++++++++------
.../org/apache/ivy/core/resolve/ResolveTest.java | 65 --------
.../IVY-1485/ivy-overlap-transitive-newer.xml | 32 ++++
.../IVY-1485/ivy-overlap-transitive-older.xml | 32 ++++
test/repositories/IVY-1485/ivy-simple.xml | 31 ++++
test/repositories/IVY-1485/ivysettings.xml | 27 ++++
.../IVY-1485/overlap-newer/modA/1/ivy.xml | 26 ++++
.../IVY-1485/overlap-newer/modA/5/ivy.xml | 26 ++++
.../IVY-1485/overlap-newer/modB/1/ivy.xml | 29 ++++
.../IVY-1485/overlap-older/modA/1/ivy.xml | 26 ++++
.../IVY-1485/overlap-older/modA/5/ivy.xml | 26 ++++
.../IVY-1485/overlap-older/modB/1/ivy.xml | 29 ++++
test/repositories/IVY-1485/simple/modA/1/ivy.xml | 26 ++++
test/repositories/IVY-1485/simple/modA/5/ivy.xml | 26 ++++
test/repositories/IVY-1485/simple/modB/1/ivy.xml | 29 ++++
18 files changed, 539 insertions(+), 175 deletions(-)
diff --git a/asciidoc/release-notes.adoc b/asciidoc/release-notes.adoc
index d6c1a6ab..25f94d8f 100644
--- a/asciidoc/release-notes.adoc
+++ b/asciidoc/release-notes.adoc
@@ -56,6 +56,9 @@ Note, if you have resolved dependencies with version of Ivy
prior to 2.6.0, you
- IMPROVEMENT: use Apache Commons Compress for pack200 handling to avoid
issues on Java 14 and later. If pack200 is needed, make sure to add Apache
Commons Compress to your classpath. (IVY-1652)
- FIX: improved Maven dependencyManagement matching for dependencies with a
non-default type or classifier (IVY-1654) (Thanks to Mark Kittisopikul)
- FIX: the `ivy:retrieve` task failed when the retrieve pattern contained some
text in parentheses before the first token, for instance: `/jobs/lib (JDK
17)/[artifact].[ext]` (IVY-1660)
+- FIX: when the `ivy:deliver` task is configured to replace dynamic revisions,
it now replaces these revisions to the resolved revision before any conflict
resolution was done, which was the original behavior before Ivy 2.3.0.
+This way, the delivered ivy.xml can be used to have reproducible dependency
resolution, especially when multiple configurations are used.
+It also fixes issues where the dynamic revisions were replaced by versions
from other configurations. (IVY-1485, IVY-1661)
== Committers and Contributors
diff --git a/asciidoc/use/deliver.adoc b/asciidoc/use/deliver.adoc
index 411c271d..f944e9f9 100644
--- a/asciidoc/use/deliver.adoc
+++ b/asciidoc/use/deliver.adoc
@@ -27,7 +27,7 @@ This task generates a resolved descriptor of the current
module, based upon the
Moreover, all included configurations' files are included in the Ivy file, and
variables are replaced by their values.
-Finally, in the resolved Ivy file, dynamic revisions are replaced by the
static ones that have been found during the resolve step, so the Ivy file can
be used later safely to obtain the same dependencies (providing that a revision
uniquely identifies a module, which should be the case for proper Ivy use).
+Finally, in the resolved Ivy file, dynamic revisions are replaced by the
static ones that have been found during the resolve step, so the Ivy file can
be used later safely to obtain the same dependencies (providing that a revision
uniquely identifies a module, which should be the case for proper Ivy use).
Note that this replacement is done before any conflict resolution happens. This
can cause differences between the selected versions in the delivered ivy.xml
file and the ones that are a [...]
(*__since 1.3__*) The replacement of dynamic revisions by static ones can be
turned off, so that dynamic revisions are kept in the Ivy file. This is an
exception to the recommended standard that published module descriptors be
fully resolved, so use it with caution.
diff --git a/src/java/org/apache/ivy/core/resolve/ResolveEngine.java
b/src/java/org/apache/ivy/core/resolve/ResolveEngine.java
index d746bb07..75785434 100644
--- a/src/java/org/apache/ivy/core/resolve/ResolveEngine.java
+++ b/src/java/org/apache/ivy/core/resolve/ResolveEngine.java
@@ -22,18 +22,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
+import java.util.*;
import org.apache.ivy.Ivy;
import org.apache.ivy.core.IvyContext;
@@ -278,65 +267,51 @@ public class ResolveEngine {
}
IvyNode root = dependencies[0].getRoot();
-
- Map<ModuleId, IvyNode> topLevelDeps = new HashMap<>();
for (IvyNode dependency : dependencies) {
- if (!dependency.hasProblem()) {
- DependencyDescriptor dd =
dependency.getDependencyDescriptor(root);
- if (dd != null) {
- ModuleId orgMod = dependency.getModuleId();
- topLevelDeps.put(orgMod, dependency);
- }
+ if (dependency.hasProblem()) {
+ // skip dependencies with problems
+ continue;
}
- }
- for (IvyNode dependency : dependencies) {
- if (!dependency.hasProblem() &&
!dependency.isCompletelyEvicted()) {
- DependencyDescriptor dd =
dependency.getDependencyDescriptor(root);
- if (dd == null) {
- ModuleId mid = dependency.getModuleId();
- IvyNode tlDep = topLevelDeps.get(mid);
- if (tlDep != null) {
- dd = tlDep.getDependencyDescriptor(root);
- }
- }
- if (dd != null) {
- ModuleRevisionId depResolvedId =
dependency.getResolvedId();
- ModuleDescriptor depDescriptor =
dependency.getDescriptor();
- ModuleRevisionId depRevisionId =
dd.getDependencyRevisionId();
- ModuleRevisionId forcedRevisionId =
forcedRevisions.get(dependency
- .getModuleId());
-
- if (dependency.getModuleRevision() != null
- && dependency.getModuleRevision().isForce()
- && !depResolvedId.equals(depRevisionId)
- &&
!settings.getVersionMatcher().isDynamic(depRevisionId)) {
- // if we were forced to this revision and we
- // are not a dynamic revision, reset to the
- // asked revision
- depResolvedId = depRevisionId;
- depDescriptor = null;
- }
+ DependencyDescriptor dd =
dependency.getDependencyDescriptor(root);
+ if (dd == null) {
+ // we are only interested in direct dependencies
+ continue;
+ }
- if (depResolvedId == null) {
- throw new
NullPointerException("getResolvedId() is null for "
- + dependency.toString());
- }
- if (depRevisionId == null) {
- throw new
NullPointerException("getDependencyRevisionId() "
- + "is null for " + dd.toString());
- }
- String rev = depResolvedId.getRevision();
- String forcedRev = forcedRevisionId == null ? rev
: forcedRevisionId
- .getRevision();
-
- // The evicted modules have no description, so we
can't put the status
- String status = depDescriptor == null ? "?" :
depDescriptor.getStatus();
- Message.debug("storing dependency " +
depResolvedId + " in props");
- props.put(depRevisionId.encodeToString(), rev + "
" + status + " "
- + forcedRev + " " +
depResolvedId.getBranch());
- }
+ ModuleRevisionId depResolvedId =
dependency.getResolvedId();
+ ModuleDescriptor depDescriptor =
dependency.getDescriptor();
+ ModuleRevisionId depRevisionId =
dd.getDependencyRevisionId();
+ ModuleRevisionId forcedRevisionId =
forcedRevisions.get(dependency.getModuleId());
+
+ if (dependency.getModuleRevision() != null
+ && dependency.getModuleRevision().isForce()
+ && !depResolvedId.equals(depRevisionId)
+ &&
!settings.getVersionMatcher().isDynamic(depRevisionId)) {
+ // if we were forced to this revision and we
+ // are not a dynamic revision, reset to the
+ // asked revision
+ depResolvedId = depRevisionId;
+ depDescriptor = null;
+ }
+
+ if (depResolvedId == null) {
+ throw new NullPointerException("getResolvedId() is
null for "
+ + dependency.toString());
+ }
+ if (depRevisionId == null) {
+ throw new
NullPointerException("getDependencyRevisionId() "
+ + "is null for " + dd.toString());
}
+ String rev = depResolvedId.getRevision();
+ String forcedRev = forcedRevisionId == null ? rev :
forcedRevisionId
+ .getRevision();
+
+ // The evicted modules have no description, so we can't
put the status
+ String status = depDescriptor == null ? "?" :
depDescriptor.getStatus();
+ Message.debug("storing dependency " + depResolvedId + " in
props");
+ props.put(depRevisionId.encodeToString(), rev + " " +
status + " "
+ + forcedRev + " " + depResolvedId.getBranch());
}
}
FileOutputStream out = new FileOutputStream(ivyPropertiesInCache);
diff --git a/test/java/org/apache/ivy/ant/IvyDeliverTest.java
b/test/java/org/apache/ivy/ant/IvyDeliverTest.java
index acb403ab..0c29614e 100644
--- a/test/java/org/apache/ivy/ant/IvyDeliverTest.java
+++ b/test/java/org/apache/ivy/ant/IvyDeliverTest.java
@@ -22,9 +22,7 @@ import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
-import java.util.Arrays;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Map;
import org.apache.ivy.TestHelper;
@@ -396,6 +394,133 @@ public class IvyDeliverTest {
dds[0].getDependencyRevisionId());
}
+ /**
+ * Test case for IVY-1300.
+ *
+ * @throws Exception if something goes wrong
+ * @see <a
href="https://issues.apache.org/jira/browse/IVY-1300">IVY-1300</a>
+ */
+ @Test
+ public void testIVY1300() throws Exception {
+ project.setProperty("ivy.settings.file",
"test/repositories/IVY-1300/ivysettings.xml");
+ project.setProperty("ivy.dep.file",
"test/repositories/IVY-1300/assembly-ivy.xml");
+ IvyResolve res = new IvyResolve();
+ res.setValidate(false);
+ res.setProject(project);
+ res.execute();
+
+ deliver.setPubrevision("1");
+ deliver.setDeliverpattern("build/test/deliver/ivy-[revision].xml");
+ deliver.setStatus("release");
+ deliver.setValidate(false);
+ deliver.execute();
+
+ // verify that the dynamic revisions have been replaced by the
resolved ones (before conflict resolution)
+ File deliveredIvyFile = new File("build/test/deliver/ivy-1.xml");
+ assertTrue(deliveredIvyFile.exists());
+ ModuleDescriptor md =
XmlModuleDescriptorParser.getInstance().parseDescriptor(
+ new IvySettings(), deliveredIvyFile.toURI().toURL(), false);
+ DependencyDescriptor[] dds = md.getDependencies();
+ assertEquals(2, dds.length);
+ assertEquals(ModuleRevisionId.newInstance("myorg", "modA",
"releasebranch", "1"),
+ dds[0].getDependencyRevisionId());
+ assertEquals(ModuleRevisionId.newInstance("myorg", "modB",
"releasebranch", "1"),
+ dds[1].getDependencyRevisionId());
+ }
+
+ /**
+ * Test case for IVY-1485.
+ *
+ * @see <a
href="https://issues.apache.org/jira/browse/IVY-1485">IVY-1485</a>
+ */
+ @Test
+ public void testDeliverWithTransitiveDepsInDifferentConfs() throws
Exception {
+ project.setProperty("ivy.settings.file",
"test/repositories/IVY-1485/ivysettings.xml");
+ project.setProperty("ivy.dep.file",
"test/repositories/IVY-1485/ivy-simple.xml");
+ IvyResolve res = new IvyResolve();
+ res.setValidate(false);
+ res.setProject(project);
+ res.execute();
+
+ deliver.setPubrevision("1");
+ deliver.setDeliverpattern("build/test/deliver/ivy-[revision].xml");
+ deliver.setStatus("release");
+ deliver.setValidate(false);
+ deliver.execute();
+
+ // now check that the transitive dependency didn't override the direct
ones
+ File deliveredIvyFile = new File("build/test/deliver/ivy-1.xml");
+ assertTrue(deliveredIvyFile.exists());
+ ModuleDescriptor md =
XmlModuleDescriptorParser.getInstance().parseDescriptor(
+ new IvySettings(), deliveredIvyFile.toURL(), false);
+ DependencyDescriptor[] dds = md.getDependencies();
+ assertEquals(2, dds.length);
+ assertEquals(ModuleRevisionId.newInstance("simple", "modA", "5"),
dds[0].getDependencyRevisionId());
+ assertEquals(ModuleRevisionId.newInstance("simple", "modB", "1"),
dds[1].getDependencyRevisionId());
+ }
+
+ /**
+ * Test case for IVY-1485.
+ *
+ * @see <a
href="https://issues.apache.org/jira/browse/IVY-1485">IVY-1485</a>
+ */
+ @Test
+ public void
testDeliverWithTransitiveDepsInOverlappingConfsTransitiveNewer() throws
Exception {
+ project.setProperty("ivy.settings.file",
"test/repositories/IVY-1485/ivysettings.xml");
+ project.setProperty("ivy.dep.file",
"test/repositories/IVY-1485/ivy-overlap-transitive-newer.xml");
+ IvyResolve res = new IvyResolve();
+ res.setValidate(false);
+ res.setProject(project);
+ res.execute();
+
+ deliver.setPubrevision("1");
+ deliver.setDeliverpattern("build/test/deliver/ivy-[revision].xml");
+ deliver.setStatus("release");
+ deliver.setValidate(false);
+ deliver.execute();
+
+ // now check that the transitive dependency didn't override the direct
ones
+ File deliveredIvyFile = new File("build/test/deliver/ivy-1.xml");
+ assertTrue(deliveredIvyFile.exists());
+ ModuleDescriptor md =
XmlModuleDescriptorParser.getInstance().parseDescriptor(
+ new IvySettings(), deliveredIvyFile.toURL(), false);
+ DependencyDescriptor[] dds = md.getDependencies();
+ assertEquals(2, dds.length);
+ assertEquals(ModuleRevisionId.newInstance("overlap-newer", "modA",
"1"), dds[0].getDependencyRevisionId());
+ assertEquals(ModuleRevisionId.newInstance("overlap-newer", "modB",
"1"), dds[1].getDependencyRevisionId());
+ }
+
+ /**
+ * Test case for IVY-1485.
+ *
+ * @see <a
href="https://issues.apache.org/jira/browse/IVY-1485">IVY-1485</a>
+ */
+ @Test
+ public void
testDeliverWithTransitiveDepsInOverlappingConfsTransitiveOlder() throws
Exception {
+ project.setProperty("ivy.settings.file",
"test/repositories/IVY-1485/ivysettings.xml");
+ project.setProperty("ivy.dep.file",
"test/repositories/IVY-1485/ivy-overlap-transitive-older.xml");
+ IvyResolve res = new IvyResolve();
+ res.setValidate(false);
+ res.setProject(project);
+ res.execute();
+
+ deliver.setPubrevision("1");
+ deliver.setDeliverpattern("build/test/deliver/ivy-[revision].xml");
+ deliver.setStatus("release");
+ deliver.setValidate(false);
+ deliver.execute();
+
+ // now check that the transitive dependency didn't override the direct
ones
+ File deliveredIvyFile = new File("build/test/deliver/ivy-1.xml");
+ assertTrue(deliveredIvyFile.exists());
+ ModuleDescriptor md =
XmlModuleDescriptorParser.getInstance().parseDescriptor(
+ new IvySettings(), deliveredIvyFile.toURL(), false);
+ DependencyDescriptor[] dds = md.getDependencies();
+ assertEquals(2, dds.length);
+ assertEquals(ModuleRevisionId.newInstance("overlap-older", "modA",
"5"), dds[0].getDependencyRevisionId());
+ assertEquals(ModuleRevisionId.newInstance("overlap-older", "modB",
"1"), dds[1].getDependencyRevisionId());
+ }
+
@Test
public void testWithDynEvicted() throws Exception {
project.setProperty("ivy.dep.file",
"test/java/org/apache/ivy/ant/ivy-dyn-evicted.xml");
@@ -418,27 +543,8 @@ public class IvyDeliverTest {
md.getModuleRevisionId());
DependencyDescriptor[] dds = md.getDependencies();
assertEquals(2, dds.length);
- assertEquals(ModuleRevisionId.newInstance("org1", "mod1.2", "2.2"),
+ assertEquals(ModuleRevisionId.newInstance("org1", "mod1.2", "1.1"),
dds[0].getDependencyRevisionId());
-
- IvyRetrieve ret = new IvyRetrieve();
- ret.setProject(project);
- ret.setPattern("build/test/retrieve/[artifact]-[revision].[ext]");
- ret.execute();
-
- File list = new File("build/test/retrieve");
- String[] files = list.list();
- HashSet<String> actualFileSet = new HashSet<>(Arrays.asList(files));
- HashSet<String> expectedFileSet = new HashSet<>();
- for (DependencyDescriptor dd : dds) {
- String name = dd.getDependencyId().getName();
- String rev = dd.getDependencyRevisionId().getRevision();
- String ext = "jar";
- String artifact = name + "-" + rev + "." + ext;
- expectedFileSet.add(artifact);
- }
- assertEquals("Delivered Ivy descriptor inconsistent with retrieved
artifacts",
- expectedFileSet, actualFileSet);
}
/**
@@ -470,28 +576,8 @@ public class IvyDeliverTest {
md.getModuleRevisionId());
DependencyDescriptor[] dds = md.getDependencies();
assertEquals(2, dds.length);
- assertEquals(ModuleRevisionId.newInstance("org1", "mod1.2", "2.2"),
+ assertEquals(ModuleRevisionId.newInstance("org1", "mod1.2", "1.1"),
dds[1].getDependencyRevisionId());
-
- IvyRetrieve ret = new IvyRetrieve();
- ret.setProject(project);
- ret.setPattern("build/test/retrieve/[artifact]-[revision].[ext]");
- ret.execute();
-
- File list = new File("build/test/retrieve");
- String[] files = list.list();
- HashSet<String> actualFileSet = new HashSet<>(Arrays.asList(files));
- HashSet<String> expectedFileSet = new HashSet<>();
- for (DependencyDescriptor dd : dds) {
- String name = dd.getDependencyId().getName();
- String rev = dd.getDependencyRevisionId().getRevision();
- String ext = "jar";
- String artifact = name + "-" + rev + "." + ext;
- expectedFileSet.add(artifact);
- }
- assertEquals("Delivered Ivy descriptor inconsistent with retrieved
artifacts",
- expectedFileSet, actualFileSet);
- list.delete();
}
@Test
diff --git a/test/java/org/apache/ivy/core/resolve/ResolveTest.java
b/test/java/org/apache/ivy/core/resolve/ResolveTest.java
index 08f9900b..53631de8 100644
--- a/test/java/org/apache/ivy/core/resolve/ResolveTest.java
+++ b/test/java/org/apache/ivy/core/resolve/ResolveTest.java
@@ -6261,71 +6261,6 @@ public class ResolveTest {
ivy.deliver(pubrev, deliveryPattern, dopts);
}
- /**
- * Test case for IVY-1300.
- *
- * @throws Exception if something goes wrong
- * @see <a
href="https://issues.apache.org/jira/browse/IVY-1300">IVY-1300</a>
- */
- @Test
- public void testIVY1300() throws Exception {
- ivy = Ivy.newInstance();
- ivy.configure(new File("test/repositories/IVY-1300/ivysettings.xml"));
-
- ResolveOptions opts = new ResolveOptions();
- opts.setConfs(new String[] {"*"});
- opts.setResolveId("resolveid");
- opts.setTransitive(true);
-
- ResolveReport report = ivy.resolve(new
File("test/repositories/IVY-1300/assembly-ivy.xml"),
- opts);
- assertFalse(report.hasError());
-
- ModuleRevisionId modAExpectedRevId =
ModuleRevisionId.newInstance("myorg", "modA", "trunk",
- "5");
- ModuleRevisionId modBExpectedRevId =
ModuleRevisionId.newInstance("myorg", "modB",
- "releasebranch", "1");
-
- // check that the resolve report has the expected results, namely that
- // trunk/5 is considered later than branch/1 purely because 5>1. Of
- // course it is more likely that we would want to consider this a
- // 'bad comparison', but this Unit Test is not about that. It is about
- // inconsistency of results between the resolve report and the
- // delivered descriptor. In fact the delivered descriptor is out of
- // step, because retrieve and the report both agree that trunk/5 is
- // selected. Deliver begs to differ.
-
- Set<ModuleRevisionId> reportMrids =
report.getConfigurationReport("default")
- .getModuleRevisionIds();
- assertEquals(
- new HashSet<>(Arrays.asList(modAExpectedRevId,
modBExpectedRevId)),
- reportMrids);
-
- DeliverOptions dopts = new DeliverOptions();
- dopts.setGenerateRevConstraint(true);
- dopts.setConfs(new String[] {"*"});
- dopts.setStatus("release");
- dopts.setPubdate(new Date());
- dopts.setResolveId("resolveid");
- String pubrev = "1";
- String deliveryPattern = "build/test/deliver/assembly-[revision].xml";
-
- ivy.deliver(pubrev, deliveryPattern, dopts);
-
- // now check that the resolve report has the same info as the
delivered descriptor
-
- File deliveredIvyFile = new File("build/test/deliver/assembly-1.xml");
- assertTrue(deliveredIvyFile.exists());
- ModuleDescriptor md =
XmlModuleDescriptorParser.getInstance().parseDescriptor(
- ivy.getSettings(), deliveredIvyFile.toURI().toURL(), false);
- DependencyDescriptor[] dds = md.getDependencies();
- assertEquals(2, dds.length);
- assertEquals(ModuleRevisionId.newInstance("myorg", "modB",
"releasebranch", "1"),
- dds[1].getDependencyRevisionId());
- assertEquals(ModuleRevisionId.newInstance("myorg", "modA", "trunk",
"5"),
- dds[0].getDependencyRevisionId());
- }
-
@Test
public void testUseCacheOnly() throws Exception {
ResolveOptions option = getResolveOptions(new String[]
{"*"}).setValidate(false);
diff --git a/test/repositories/IVY-1485/ivy-overlap-transitive-newer.xml
b/test/repositories/IVY-1485/ivy-overlap-transitive-newer.xml
new file mode 100644
index 00000000..28904a35
--- /dev/null
+++ b/test/repositories/IVY-1485/ivy-overlap-transitive-newer.xml
@@ -0,0 +1,32 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<ivy-module version="2.0">
+ <info organisation="overlap-newer" module="projectassembly" revision="1"/>
+ <configurations>
+ <conf name="conf1"/>
+ <conf name="conf2"/>
+ <conf name="conf3"/>
+ </configurations>
+ <publications>
+ </publications>
+ <dependencies>
+ <dependency name="modA" rev="1" conf="conf1,conf2->default"/>
+ <dependency name="modB" rev="1" conf="conf2,conf3->default"/>
+ </dependencies>
+</ivy-module>
diff --git a/test/repositories/IVY-1485/ivy-overlap-transitive-older.xml
b/test/repositories/IVY-1485/ivy-overlap-transitive-older.xml
new file mode 100644
index 00000000..9ce21075
--- /dev/null
+++ b/test/repositories/IVY-1485/ivy-overlap-transitive-older.xml
@@ -0,0 +1,32 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<ivy-module version="2.0">
+ <info organisation="overlap-older" module="projectassembly" revision="1"/>
+ <configurations>
+ <conf name="conf1"/>
+ <conf name="conf2"/>
+ <conf name="conf3"/>
+ </configurations>
+ <publications>
+ </publications>
+ <dependencies>
+ <dependency name="modA" rev="5" conf="conf1,conf2->default"/>
+ <dependency name="modB" rev="1" conf="conf2,conf3->default"/>
+ </dependencies>
+</ivy-module>
diff --git a/test/repositories/IVY-1485/ivy-simple.xml
b/test/repositories/IVY-1485/ivy-simple.xml
new file mode 100644
index 00000000..ea462993
--- /dev/null
+++ b/test/repositories/IVY-1485/ivy-simple.xml
@@ -0,0 +1,31 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<ivy-module version="2.0">
+ <info organisation="simple" module="projectassembly" revision="1"/>
+ <configurations>
+ <conf name="conf1"/>
+ <conf name="conf2"/>
+ </configurations>
+ <publications>
+ </publications>
+ <dependencies>
+ <dependency name="modA" rev="5" conf="conf1->default"/>
+ <dependency name="modB" rev="1" conf="conf1,conf2->default"/>
+ </dependencies>
+</ivy-module>
diff --git a/test/repositories/IVY-1485/ivysettings.xml
b/test/repositories/IVY-1485/ivysettings.xml
new file mode 100644
index 00000000..869eabb3
--- /dev/null
+++ b/test/repositories/IVY-1485/ivysettings.xml
@@ -0,0 +1,27 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<ivysettings>
+ <settings defaultResolver="local" />
+ <resolvers>
+ <filesystem name="local" checkmodified="true" local="true">
+ <ivy
pattern="${ivy.settings.dir}/[organisation]/[module]/[revision]/ivy.xml"/>
+ <artifact
pattern="${ivy.settings.dir}/[organisation]/[module]/[revision]/[artifact].[ext]"/>
+ </filesystem>
+ </resolvers>
+</ivysettings>
diff --git a/test/repositories/IVY-1485/overlap-newer/modA/1/ivy.xml
b/test/repositories/IVY-1485/overlap-newer/modA/1/ivy.xml
new file mode 100644
index 00000000..d24d993f
--- /dev/null
+++ b/test/repositories/IVY-1485/overlap-newer/modA/1/ivy.xml
@@ -0,0 +1,26 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<ivy-module version="2.0">
+ <info organisation="overlap-newer" module="modA" revision="1" />
+ <configurations>
+ <conf name="default"/>
+ </configurations>
+ <publications>
+ </publications>
+</ivy-module>
diff --git a/test/repositories/IVY-1485/overlap-newer/modA/5/ivy.xml
b/test/repositories/IVY-1485/overlap-newer/modA/5/ivy.xml
new file mode 100644
index 00000000..d3e0794a
--- /dev/null
+++ b/test/repositories/IVY-1485/overlap-newer/modA/5/ivy.xml
@@ -0,0 +1,26 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<ivy-module version="2.0">
+ <info organisation="overlap-newer" module="modA" revision="5" />
+ <configurations>
+ <conf name="default"/>
+ </configurations>
+ <publications>
+ </publications>
+</ivy-module>
diff --git a/test/repositories/IVY-1485/overlap-newer/modB/1/ivy.xml
b/test/repositories/IVY-1485/overlap-newer/modB/1/ivy.xml
new file mode 100644
index 00000000..66de5d7c
--- /dev/null
+++ b/test/repositories/IVY-1485/overlap-newer/modB/1/ivy.xml
@@ -0,0 +1,29 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<ivy-module version="2.0">
+ <info organisation="overlap-newer" module="modB" revision="1" />
+ <configurations>
+ <conf name="default"/>
+ </configurations>
+ <publications>
+ </publications>
+ <dependencies>
+ <dependency org="overlap-newer" name="modA" rev="5"
conf="default->default"/>
+ </dependencies>
+</ivy-module>
diff --git a/test/repositories/IVY-1485/overlap-older/modA/1/ivy.xml
b/test/repositories/IVY-1485/overlap-older/modA/1/ivy.xml
new file mode 100644
index 00000000..1372d9da
--- /dev/null
+++ b/test/repositories/IVY-1485/overlap-older/modA/1/ivy.xml
@@ -0,0 +1,26 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<ivy-module version="2.0">
+ <info organisation="overlap-older" module="modA" revision="1" />
+ <configurations>
+ <conf name="default"/>
+ </configurations>
+ <publications>
+ </publications>
+</ivy-module>
diff --git a/test/repositories/IVY-1485/overlap-older/modA/5/ivy.xml
b/test/repositories/IVY-1485/overlap-older/modA/5/ivy.xml
new file mode 100644
index 00000000..ddb9be0a
--- /dev/null
+++ b/test/repositories/IVY-1485/overlap-older/modA/5/ivy.xml
@@ -0,0 +1,26 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<ivy-module version="2.0">
+ <info organisation="overlap-older" module="modA" revision="5" />
+ <configurations>
+ <conf name="default"/>
+ </configurations>
+ <publications>
+ </publications>
+</ivy-module>
diff --git a/test/repositories/IVY-1485/overlap-older/modB/1/ivy.xml
b/test/repositories/IVY-1485/overlap-older/modB/1/ivy.xml
new file mode 100644
index 00000000..b18f9cec
--- /dev/null
+++ b/test/repositories/IVY-1485/overlap-older/modB/1/ivy.xml
@@ -0,0 +1,29 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<ivy-module version="2.0">
+ <info organisation="overlap-older" module="modB" revision="1" />
+ <configurations>
+ <conf name="default"/>
+ </configurations>
+ <publications>
+ </publications>
+ <dependencies>
+ <dependency org="overlap-older" name="modA" rev="1"
conf="default->default"/>
+ </dependencies>
+</ivy-module>
diff --git a/test/repositories/IVY-1485/simple/modA/1/ivy.xml
b/test/repositories/IVY-1485/simple/modA/1/ivy.xml
new file mode 100644
index 00000000..701473d2
--- /dev/null
+++ b/test/repositories/IVY-1485/simple/modA/1/ivy.xml
@@ -0,0 +1,26 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<ivy-module version="2.0">
+ <info organisation="simple" module="modA" revision="1" />
+ <configurations>
+ <conf name="default"/>
+ </configurations>
+ <publications>
+ </publications>
+</ivy-module>
diff --git a/test/repositories/IVY-1485/simple/modA/5/ivy.xml
b/test/repositories/IVY-1485/simple/modA/5/ivy.xml
new file mode 100644
index 00000000..262680c2
--- /dev/null
+++ b/test/repositories/IVY-1485/simple/modA/5/ivy.xml
@@ -0,0 +1,26 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<ivy-module version="2.0">
+ <info organisation="simple" module="modA" revision="5" />
+ <configurations>
+ <conf name="default"/>
+ </configurations>
+ <publications>
+ </publications>
+</ivy-module>
diff --git a/test/repositories/IVY-1485/simple/modB/1/ivy.xml
b/test/repositories/IVY-1485/simple/modB/1/ivy.xml
new file mode 100644
index 00000000..23a57679
--- /dev/null
+++ b/test/repositories/IVY-1485/simple/modB/1/ivy.xml
@@ -0,0 +1,29 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<ivy-module version="2.0">
+ <info organisation="simple" module="modB" revision="1" />
+ <configurations>
+ <conf name="default"/>
+ </configurations>
+ <publications>
+ </publications>
+ <dependencies>
+ <dependency org="simple" name="modA" rev="1" conf="default->default"/>
+ </dependencies>
+</ivy-module>