merge of r1342465 and r1342466:

IVY-1300: Delivered ivy descriptor inconsistent with resolve report / retrieve and other post-resolve actions (thanks to Ed Burcher)


git-svn-id: https://svn.apache.org/repos/asf/ant/ivy/core/branches/2.3.x@1342467 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nicolas Lalevee 2012-05-24 22:35:56 +00:00
parent b9059448ca
commit ec4e0bf4dd
5 changed files with 165 additions and 20 deletions

View File

@ -31,6 +31,7 @@ for detailed view of each issue, please consult http://issues.apache.org/jira/br
Matthieu Brouillard
Carlton Brown
Mirko Bulovic
Ed Burcher
Jamie Burns
Chris Chilvers
Kristian Cibulskis
@ -126,6 +127,7 @@ for detailed view of each issue, please consult http://issues.apache.org/jira/br
2.3.x
=====================================
- FIX: NullPointerExeption in AbstractOSGiResolver (IVY-1343) (thanks to Thomas Kurpick)
- FIX: Delivered ivy descriptor inconsistent with resolve report / retrieve and other post-resolve actions (IVY-1300) (thanks to Ed Burcher)
2.3.0-rc1
=====================================

View File

@ -131,6 +131,7 @@ public class DeliverEngine {
// 2) parse resolvedRevisions From properties file
Map resolvedRevisions = new HashMap(); // Map (ModuleId -> String revision)
Map resolvedBranches = new HashMap(); // Map (ModuleId -> String branch)
Map dependenciesStatus = new HashMap(); // Map (ModuleId -> String status)
File ivyProperties = getCache().getResolvedIvyPropertiesInCache(mrid);
if (!ivyProperties.exists()) {
@ -148,6 +149,11 @@ public class DeliverEngine {
ModuleRevisionId decodedMrid = ModuleRevisionId.decode(depMridStr);
if (options.isResolveDynamicRevisions()) {
resolvedRevisions.put(decodedMrid, parts[0]);
if (parts.length >= 4) {
if (parts[3] != null && !"null".equals(parts[3])) {
resolvedBranches.put(decodedMrid, parts[3]);
}
}
}
dependenciesStatus.put(decodedMrid, parts[1]);
@ -171,14 +177,24 @@ public class DeliverEngine {
if (rev == null) {
rev = dependencies[i].getDependencyRevisionId().getRevision();
}
String bra = (String) resolvedBranches.get(dependencies[i].getDependencyRevisionId());
if (bra == null || "null".equals(bra)) {
bra = dependencies[i].getDependencyRevisionId().getBranch();
}
String depStatus = (String) dependenciesStatus.get(dependencies[i]
.getDependencyRevisionId());
ModuleRevisionId mrid2 = null;
if (bra == null) {
mrid2 = ModuleRevisionId.newInstance(dependencies[i].getDependencyRevisionId(), rev);
}
else {
mrid2 = ModuleRevisionId.newInstance(dependencies[i].getDependencyRevisionId(), bra, rev);
}
resolvedDependencies.put(dependencies[i].getDependencyRevisionId(), options
.getPdrResolver().resolve(
md,
options.getStatus(),
ModuleRevisionId
.newInstance(dependencies[i].getDependencyRevisionId(), rev),
mrid2,
depStatus));
}
@ -194,19 +210,22 @@ public class DeliverEngine {
confsToRemove.removeAll(Arrays.asList(confs));
try {
XmlModuleDescriptorUpdater.update(ivyFileURL, publishedIvy,
new UpdateOptions()
.setSettings(settings)
.setResolvedRevisions(resolvedDependencies)
.setStatus(options.getStatus())
.setRevision(revision)
.setBranch(options.getPubBranch())
.setPubdate(options.getPubdate())
.setGenerateRevConstraint(options.isGenerateRevConstraint())
.setMerge(options.isMerge())
.setMergedDescriptor(md)
.setConfsToExclude((String[]) confsToRemove
.toArray(new String[confsToRemove.size()])));
UpdateOptions opts = new UpdateOptions()
.setSettings(settings)
.setResolvedRevisions(resolvedDependencies)
.setStatus(options.getStatus())
.setRevision(revision)
.setBranch(options.getPubBranch())
.setPubdate(options.getPubdate())
.setGenerateRevConstraint(options.isGenerateRevConstraint())
.setMerge(options.isMerge())
.setMergedDescriptor(md)
.setConfsToExclude((String[]) confsToRemove
.toArray(new String[confsToRemove.size()]));
if (!resolvedBranches.isEmpty()) {
opts = opts.setResolvedBranches(resolvedBranches);
}
XmlModuleDescriptorUpdater.update(ivyFileURL, publishedIvy, opts);
} catch (SAXException ex) {
throw new RuntimeException("bad ivy file in cache for " + mrid
+ ": please clean '" + ivyFile + "' and resolve again", ex);

View File

@ -52,6 +52,7 @@ import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor;
import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor;
import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
import org.apache.ivy.core.module.id.ModuleId;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.report.ArtifactDownloadReport;
import org.apache.ivy.core.report.ConfigurationResolveReport;
@ -258,11 +259,31 @@ public class ResolveEngine {
forcedRevisions.put(dependencies[i].getModuleId(), dependencies[i].getResolvedId());
}
}
IvyNode root = dependencies[0].getRoot();
// <ModuleId,IvyNode>();
Map topLevelDeps = new HashMap(); //
for (int i = 0; i < dependencies.length; i++) {
if (!dependencies[i].hasProblem()) {
DependencyDescriptor dd = dependencies[i].getDependencyDescriptor(root);
if (dd != null) {
ModuleId orgMod = dependencies[i].getModuleId();
topLevelDeps.put(orgMod, dependencies[i]);
}
}
}
for (int i = 0; i < dependencies.length; i++) {
if (!dependencies[i].hasProblem() && !dependencies[i].isCompletelyEvicted()) {
DependencyDescriptor dd = dependencies[i].getDependencyDescriptor(root);
if (dd == null) {
ModuleId mid = dependencies[i].getModuleId();
IvyNode tlDep = (IvyNode)topLevelDeps.get(mid);
if (tlDep != null) {
dd = tlDep.getDependencyDescriptor(root);
}
}
if (dd != null) {
ModuleRevisionId depResolvedId = dependencies[i].getResolvedId();
ModuleDescriptor depDescriptor = dependencies[i].getDescriptor();
@ -294,7 +315,8 @@ public class ResolveEngine {
// The evicted modules have no description, so we can't put the status
String status = depDescriptor == null ? "?" : depDescriptor.getStatus();
props.put(depRevisionId.encodeToString(), rev + " " + status + " " + forcedRev);
Message.debug("storing dependency " + depResolvedId + " in props");
props.put(depRevisionId.encodeToString(), rev + " " + status + " " + forcedRev + " " + depResolvedId.getBranch());
}
}
}

View File

@ -23,7 +23,9 @@ import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.ParseException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import junit.framework.TestCase;
@ -46,6 +48,7 @@ public class IvyDeliverTest extends TestCase {
protected void setUp() throws Exception {
cleanTestDir();
cleanRetrieveDir();
cleanRep();
createCache();
project = new Project();
@ -66,6 +69,7 @@ public class IvyDeliverTest extends TestCase {
protected void tearDown() throws Exception {
cleanCache();
cleanTestDir();
cleanRetrieveDir();
cleanRep();
}
@ -83,6 +87,13 @@ public class IvyDeliverTest extends TestCase {
del.execute();
}
private void cleanRetrieveDir() {
Delete del = new Delete();
del.setProject(new Project());
del.setDir(new File("build/test/retrieve"));
del.execute();
}
private void cleanRep() {
Delete del = new Delete();
del.setProject(new Project());
@ -394,8 +405,28 @@ public class IvyDeliverTest extends TestCase {
md.getModuleRevisionId());
DependencyDescriptor[] dds = md.getDependencies();
assertEquals(2, dds.length);
assertEquals(ModuleRevisionId.newInstance("org1", "mod1.2", "1.1"),
assertEquals(ModuleRevisionId.newInstance("org1", "mod1.2", "2.2"),
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 actualFileSet = new HashSet(Arrays.asList(files));
HashSet expectedFileSet = new HashSet();
for (int i = 0; i < dds.length; i++) {
DependencyDescriptor dd = dds[i];
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);
}
public void testWithDynEvicted2() throws Exception {
@ -421,10 +452,31 @@ public class IvyDeliverTest extends TestCase {
md.getModuleRevisionId());
DependencyDescriptor[] dds = md.getDependencies();
assertEquals(2, dds.length);
assertEquals(ModuleRevisionId.newInstance("org1", "mod1.2", "1.1"),
assertEquals(ModuleRevisionId.newInstance("org1", "mod1.2", "2.2"),
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 actualFileSet = new HashSet(Arrays.asList(files));
HashSet expectedFileSet = new HashSet();
for (int i = 0; i < dds.length; i++) {
DependencyDescriptor dd = dds[i];
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();
}
public void testReplaceImportedConfigurations() throws Exception {
project.setProperty("ivy.dep.file", "test/java/org/apache/ivy/ant/ivy-import-confs.xml");
IvyResolve res = new IvyResolve();

View File

@ -5285,6 +5285,56 @@ public class ResolveTest extends TestCase {
ivy.deliver(pubrev, deliveryPattern, dopts);
}
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").toURL(), 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 reportMrids = report.getConfigurationReport("default").getModuleRevisionIds();
assertEquals(
new HashSet(Arrays.asList(new ModuleRevisionId[] { 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.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());
}
public void testUseCacheOnly() throws Exception {
ResolveOptions option = getResolveOptions(new String[] {"*"}).setValidate(false);
URL url = new File("test/repositories/1/usecacheonly/mod1/ivys/ivy-1.0.xml").toURI()