Merge pull request #111 from eric-milles/IVY-1658

IVY-1658: merge `ivy-module` namespaces
This commit is contained in:
Maarten Coene 2026-06-17 20:19:22 +02:00 committed by GitHub
commit 648768b130
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 155 additions and 109 deletions

View File

@ -88,7 +88,7 @@ Export-Package: org.apache.ivy;version="2.0.0",
org.apache.ivy.plugins.pack;version="2.6.0",
org.apache.ivy.plugins.parser;version="2.0.0",
org.apache.ivy.plugins.parser.m2;version="2.6.0",
org.apache.ivy.plugins.parser.xml;version="2.0.0",
org.apache.ivy.plugins.parser.xml;version="2.6.0",
org.apache.ivy.plugins.report;version="2.0.0",
org.apache.ivy.plugins.repository;version="2.0.0",
org.apache.ivy.plugins.repository.file;version="2.0.0",

View File

@ -110,6 +110,9 @@
<property name="allowUnchecked" value="true"/>
</module>
-->
<module name="OneStatementPerLine">
<property name="treatTryResourcesAsStatement" value="true"/>
</module>
<module name="SimplifyBooleanExpression"/>
<module name="SimplifyBooleanReturn"/>

View File

@ -83,6 +83,7 @@ import org.apache.ivy.util.FileUtil;
import org.apache.ivy.util.Message;
import org.apache.ivy.util.XMLHelper;
import org.apache.ivy.util.extendable.ExtendableItemHelper;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
@ -548,37 +549,30 @@ public class XmlModuleDescriptorParser extends AbstractModuleDescriptorParser {
* @param parent
* a given parent module descriptor
*/
protected void mergeWithOtherModuleDescriptor(List<String> extendTypes,
ModuleDescriptor parent) {
protected void mergeWithOtherModuleDescriptor(List<String> extendTypes, ModuleDescriptor parent) {
if (extendTypes.contains("all")) {
mergeAll(parent);
} else {
if (extendTypes.contains("info")) {
mergeInfo(parent);
}
if (extendTypes.contains("configurations")) {
mergeConfigurations(parent);
}
if (extendTypes.contains("dependencies")) {
mergeDependencies(parent.getDependencies());
}
if (extendTypes.contains("description")) {
mergeDescription(parent.getDescription());
}
if (extendTypes.contains("licenses")) {
mergeLicenses(parent.getLicenses());
}
if (extendTypes.contains("excludes")) {
mergeExcludes(parent.getAllExcludeRules());
}
}
mergeNamespaces(parent.getExtraAttributesNamespaces()); // IVY-1658
}
/**
@ -722,6 +716,17 @@ public class XmlModuleDescriptorParser extends AbstractModuleDescriptorParser {
}
}
private void mergeNamespaces(Map<String, String> namespaces) {
if (namespaces != null && !namespaces.isEmpty()) {
for (Map.Entry<String, String> entry : namespaces.entrySet()) {
Message.debug("Merging extra attribute namesapce: " + entry);
if (getMd().getExtraAttributesNamespaces().get(entry.getKey()) == null) {
getMd().addExtraAttributeNamespace(entry.getKey(), entry.getValue());
}
}
}
}
/**
* Returns the parent module using the location attribute (for dev purpose).
*
@ -1455,5 +1460,4 @@ public class XmlModuleDescriptorParser extends AbstractModuleDescriptorParser {
public String toString() {
return "ivy parser";
}
}

View File

@ -59,6 +59,7 @@ import org.apache.ivy.util.DateUtil;
import org.apache.ivy.util.Message;
import org.apache.ivy.util.XMLHelper;
import org.apache.ivy.util.extendable.ExtendableItemHelper;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
@ -409,13 +410,24 @@ public final class XmlModuleDescriptorUpdater {
// copy
write("<" + qName);
for (int i = 0; i < attributes.getLength(); i++) {
write(" " + attributes.getQName(i) + "=\""
+ substitute(settings, attributes.getValue(i)) + "\"");
if (options.isMerge() && path.equals("ivy-module")) {
for (int i = 0, n = attributes.getLength(); i < n; i += 1) {
if (attributes.getQName(i).startsWith("xmlns:")) {
continue; // written next from namespace map
}
write(" " + attributes.getQName(i) + "=\"" + substitute(settings, attributes.getValue(i)) + "\"");
}
Map<String, String> namespaces = options.getMergedDescriptor().getExtraAttributesNamespaces();
for (Map.Entry<String, String> namespace : namespaces.entrySet()) {
write(" xmlns:" + namespace.getKey() + "=\"" + substitute(settings, namespace.getValue()) + "\"");
}
} else {
for (int i = 0, n = attributes.getLength(); i < n; i += 1) {
write(" " + attributes.getQName(i) + "=\"" + substitute(settings, attributes.getValue(i)) + "\"");
}
}
}
justOpen = qName;
// indent.append("\t");
}
private void startExtends(Attributes attributes) {

View File

@ -17,79 +17,35 @@
*/
package org.apache.ivy.core.deliver;
import org.apache.ivy.TestHelper;
import org.apache.ivy.ant.IvyDeliver;
import org.apache.ivy.ant.IvyResolve;
import org.apache.ivy.util.FileUtil;
import org.apache.tools.ant.Project;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.URI;
import static org.junit.Assert.assertFalse;
import org.apache.ivy.TestHelper;
import org.apache.ivy.ant.IvyDeliver;
import org.apache.ivy.ant.IvyResolve;
import org.apache.ivy.util.FileUtil;
import org.apache.commons.io.FileUtils;
import org.apache.tools.ant.Project;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
public class DeliverTest {
private File cache;
private File cacheDir;
private File deliverDir;
private IvyDeliver ivyDeliver;
@Before
public void setUp() {
cache = new File("build/cache");
System.setProperty("ivy.cache.dir", cache.getAbsolutePath());
createCache();
deliverDir = new File("build/test/deliver");
deliverDir.mkdirs();
Project project = TestHelper.newProject();
project.init();
ivyDeliver = new IvyDeliver();
ivyDeliver.setProject(project);
ivyDeliver.setDeliverpattern(deliverDir.getAbsolutePath()
+ "/[type]s/[artifact]-[revision](-[classifier]).[ext]");
}
@After
public void tearDown() {
FileUtil.forceDelete(cache);
FileUtil.forceDelete(deliverDir);
}
private void createCache() {
cache.mkdirs();
}
/**
* Test case for IVY-1111.
*
* @throws Exception if something goes wrong
* @see <a href="https://issues.apache.org/jira/browse/IVY-1111">IVY-1111</a>
*/
@Test
public void testIVY1111() throws Exception {
Project project = ivyDeliver.getProject();
project.setProperty("ivy.settings.file", "test/repositories/IVY-1111/ivysettings.xml");
File ivyFile = new File(new URI(DeliverTest.class.getResource("ivy-1111.xml").toString()));
resolve(ivyFile);
ivyDeliver.setReplacedynamicrev(true);
ivyDeliver.doExecute();
String deliverContent = readFile(deliverDir.getAbsolutePath() + "/ivys/ivy-1.0.xml");
assertFalse(deliverContent.contains("rev=\"latest.integration\""));
assertTrue(deliverContent.contains("name=\"b\" rev=\"1.5\""));
cacheDir.mkdirs();
}
/**
@ -120,16 +76,113 @@ public class DeliverTest {
private String readFile(String fileName) throws IOException {
StringBuilder retval = new StringBuilder();
File ivyFile = new File(fileName);
BufferedReader reader = new BufferedReader(new FileReader(ivyFile));
String line = null;
while ((line = reader.readLine()) != null) {
retval.append(line).append("\n");
File file = new File(fileName);
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line = null;
while ((line = reader.readLine()) != null) {
retval.append(line).append("\n");
}
}
reader.close();
return retval.toString();
}
private File writeFile(String fileText) throws IOException {
File file = File.createTempFile("ivy", ".xml");
file.deleteOnExit();
FileUtils.write(file, fileText, "UTF-8");
return file;
}
@Before
public void setUp() {
cacheDir = new File("build/cache");
System.setProperty("ivy.cache.dir", cacheDir.getAbsolutePath());
createCache();
deliverDir = new File("build/test/deliver");
deliverDir.mkdirs();
Project project = TestHelper.newProject();
project.init();
ivyDeliver = new IvyDeliver();
ivyDeliver.setProject(project);
ivyDeliver.setDeliverpattern(deliverDir.getAbsolutePath() + "/[type]s/[artifact]-[revision](-[classifier]).[ext]");
}
@After
public void tearDown() {
FileUtil.forceDelete(cacheDir);
FileUtil.forceDelete(deliverDir);
}
/**
* Test case for <a href="https://issues.apache.org/jira/browse/IVY-1111">IVY-1111</a>.
*/
@Test
public void testDeliver1111() throws Exception {
ivyDeliver.getProject().setProperty("ivy.settings.file", "test/repositories/IVY-1111/ivysettings.xml");
String ivyFile
= "<ivy-module version='1.0' xmlns:e='http://ant.apache.org/ivy/extra'>\n"
+ " <info organisation='apache' module='IVY-1111' revision='1.0' e:att='att'/>\n"
+ " <dependencies>\n"
+ " <dependency org='test' name='a' rev='latest.integration'/>\n"
+ " <dependency org='test' name='b' rev='latest.integration' e:att='att'/>\n"
+ " <dependency org='junit' name='junit' rev='latest.integration'/>\n"
+ " </dependencies>\n"
+ "</ivy-module>\n";
resolve(writeFile(ivyFile));
ivyDeliver.setReplacedynamicrev(true);
ivyDeliver.doExecute();
ivyFile = readFile(deliverDir.getAbsolutePath() + "/ivys/ivy-1.0.xml");
assertTrue(ivyFile.contains("org=\"test\" name=\"a\" rev=\"1\" revConstraint=\"latest.integration\""));
assertTrue(ivyFile.contains("org=\"test\" name=\"b\" rev=\"1.5\" revConstraint=\"latest.integration\" e:att=\"att\""));
assertTrue(ivyFile.contains("org=\"junit\" name=\"junit\" rev=\"4.4\" revConstraint=\"latest.integration\""));
}
/**
* Test case for <a href="https://issues.apache.org/jira/browse/IVY-1658">IVY-1658</a>.
*/
@Test
public void testDeliver1658() throws Exception {
String ivyFile
= "<ivy-module version='2.0'\n"
+ " xmlns:m='http://ant.apache.org/ivy/maven'\n"
+ " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'\n"
+ " xsi:noNamespaceSchemaLocation='http://ant.apache.org/ivy/schemas/ivy.xsd'>\n"
+ " <info module='xxx' organisation='zzz'/>\n"
+ " <dependencies>\n"
+ " <dependency name='groovy' org='org.codehaus.groovy' rev='3.0.25' transitive='false'>\n"
+ " <artifact name='groovy' m:classifier='indy'/>\n"
+ " </dependency>\n"
+ " </dependencies>\n"
+ "</ivy-module>\n";
ivyFile
= "<ivy-module version='2.0'\n"
+ " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'\n"
+ " xsi:noNamespaceSchemaLocation='http://ant.apache.org/ivy/schemas/ivy.xsd'>\n"
+ " <info module='yyy' organisation='zzz' revision='1.0'>\n"
+ " <extends module='xxx' organisation='zzz' extendType='dependencies'\n"
+ " location='" + writeFile(ivyFile).getName() + "' revision='latest'/>\n"
+ " </info>\n"
+ " <dependencies>\n"
+ " </dependencies>\n"
+ "</ivy-module>\n";
resolve(writeFile(ivyFile));
ivyDeliver.doExecute();
ivyFile = readFile(deliverDir.getAbsolutePath() + "/ivys/ivy-1.0.xml");
assertTrue(ivyFile.contains(" version=\"2.0\""));
assertTrue(ivyFile.contains(" xmlns:m=\"http://ant.apache.org/ivy/maven\""));
assertTrue(ivyFile.contains(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""));
assertTrue(ivyFile.contains(" xsi:noNamespaceSchemaLocation=\"http://ant.apache.org/ivy/schemas/ivy.xsd\""));
}
}

View File

@ -1,26 +0,0 @@
<!--
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="1.0" xmlns:e="http://ant.apache.org/ivy/extra">
<info organisation="apache" module="IVY-1111" revision="1.0" e:att="att"/>
<dependencies>
<dependency org="test" name="a" rev="latest.integration"/>
<dependency org="test" name="b" rev="latest.integration" e:att="att"/>
<dependency org="junit" name="junit" rev="latest.integration"/>
</dependencies>
</ivy-module>