From 0ccdad9b8cf51eedc6e7011d42e50a86ef15b7f4 Mon Sep 17 00:00:00 2001 From: Eric Milles Date: Tue, 16 Jun 2026 08:42:35 -0500 Subject: [PATCH 1/5] IVY-1653: makepom: write overrides to Maven dependencyManagement section --- .../parser/m2/PomModuleDescriptorWriter.java | 76 ++++++++- .../module/descriptor/IvyMakePomTest.java | 153 ++++++++++++++++++ 2 files changed, 221 insertions(+), 8 deletions(-) diff --git a/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorWriter.java b/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorWriter.java index 05f69704..b1f6f186 100644 --- a/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorWriter.java +++ b/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorWriter.java @@ -38,11 +38,15 @@ import org.apache.ivy.core.IvyPatternHelper; import org.apache.ivy.core.module.descriptor.Artifact; import org.apache.ivy.core.module.descriptor.DependencyArtifactDescriptor; import org.apache.ivy.core.module.descriptor.DependencyDescriptor; +import org.apache.ivy.core.module.descriptor.DependencyDescriptorMediator; import org.apache.ivy.core.module.descriptor.ExcludeRule; import org.apache.ivy.core.module.descriptor.ModuleDescriptor; +import org.apache.ivy.core.module.descriptor.OverrideDependencyDescriptorMediator; import org.apache.ivy.core.module.id.ModuleRevisionId; +import org.apache.ivy.core.module.id.ModuleRules; import org.apache.ivy.core.settings.IvySettings; import org.apache.ivy.core.settings.IvyVariableContainer; +import org.apache.ivy.plugins.matcher.MapMatcher; import org.apache.ivy.plugins.parser.m2.PomWriterOptions.ConfigurationScopeMapping; import org.apache.ivy.plugins.parser.m2.PomWriterOptions.ExtraDependency; import org.apache.ivy.util.ConfigurationUtils; @@ -112,6 +116,7 @@ public final class PomModuleDescriptorWriter { boolean dependencyManagement = false; boolean dependenciesPrinted = false; + boolean overridesPrinted = false; int lastIndent = 0; int indent = 0; @@ -135,14 +140,26 @@ public final class PomModuleDescriptorWriter { dependencyManagement = false; } - if (line.contains("") && !dependenciesPrinted && !dependencyManagement) { - printDependencies(md, out, options, indent, false); - dependenciesPrinted = true; + if (line.contains("")) { + if (!dependenciesPrinted && !dependencyManagement) { + printDependencies(md, out, options, indent, false); + dependenciesPrinted = true; + } + if (!overridesPrinted && dependencyManagement) { + printOverrides(md, out, indent, false); + overridesPrinted = true; + } } - if (line.contains("") && !dependenciesPrinted) { - printDependencies(md, out, options, lastIndent, true); - dependenciesPrinted = true; + if (line.contains("")) { + if (!dependenciesPrinted) { + printDependencies(md, out, options, lastIndent, true); + dependenciesPrinted = true; + } + if (!overridesPrinted) { + printOverrides(md, out, lastIndent, true); + overridesPrinted = true; + } } } out.println(line); @@ -342,8 +359,51 @@ public final class PomModuleDescriptorWriter { out.println(""); } - private static DependencyDescriptor[] getDependencies(ModuleDescriptor md, - PomWriterOptions options) { + private static void printOverrides(ModuleDescriptor md, PrintWriter out, int indent, boolean container) { + ModuleRules mr = md.getAllDependencyDescriptorMediators(); + if (mr.getAllRules().isEmpty()) { + return; + } + + if (container) { + indent(out, indent); + out.println(""); + indent(out, indent * 2); + out.println(""); + } else { + indent /= 2; // is second-level child of + } + + for (Map.Entry entry : mr.getAllRules().entrySet()) { + if (entry.getValue() instanceof OverrideDependencyDescriptorMediator) { + String artifactId = entry.getKey().getAttributes().get("module"); + String groupId = entry.getKey().getAttributes().get("organisation"); + String version = ((OverrideDependencyDescriptorMediator) entry.getValue()).getVersion(); + + if (artifactId == null || artifactId.equals("*") || groupId == null || groupId.equals("*")) continue; + + indent(out, indent * 3); + out.println(""); + indent(out, indent * 4); + out.println("" + groupId + ""); + indent(out, indent * 4); + out.println("" + artifactId + ""); + indent(out, indent * 4); + out.println("" + version + ""); + indent(out, indent * 3); + out.println(""); + } + } + + if (container) { + indent(out, indent * 2); + out.println(""); + indent(out, indent); + out.println(""); + } + } + + private static DependencyDescriptor[] getDependencies(ModuleDescriptor md, PomWriterOptions options) { String[] confs = ConfigurationUtils.replaceWildcards(options.getConfs(), md); List result = new ArrayList<>(); diff --git a/test/java/org/apache/ivy/core/module/descriptor/IvyMakePomTest.java b/test/java/org/apache/ivy/core/module/descriptor/IvyMakePomTest.java index 430f4dbd..1d932da4 100644 --- a/test/java/org/apache/ivy/core/module/descriptor/IvyMakePomTest.java +++ b/test/java/org/apache/ivy/core/module/descriptor/IvyMakePomTest.java @@ -100,6 +100,73 @@ public class IvyMakePomTest { assertTrue("Some expected dependencies " + expectedPomArtifactIds + " were not found in the generated POM file", expectedPomArtifactIds.isEmpty()); } + /** + * Test case for IVY-1653. + */ + @Test + public void testMakePom1653() throws Exception { + File ivyFile = workdir.newFile("ivy-1653.xml"); + writeLines(ivyFile, "UTF-8", Arrays.asList( + "", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + "" + )); + + File pomFile = workdir.newFile("ivy-1653.pom"); + + IvyMakePom task = new IvyMakePom(); + task.setIvyFile(ivyFile); + task.setPomFile(pomFile); + task.setPrintIvyInfo(false); + task.setProject(project); + + IvyMakePom.Mapping mapping = task.createMapping(); + mapping.setConf("default"); + mapping.setScope("compile"); + + task.execute(); + + String[] expect = { + "", + "", + "", + " 4.0.0", + " org", + " name", + " jar", + " 1.0.0-SNAPSHOT", + " ", + " ", + " org.springframework", + " spring-aop", + " 6.2.9", + " compile", + " ", + " ", + " ", + " ", + " ", + " org.aspectj", + " aspectjrt", + " 1.9.24", + " ", + " ", + " ", + "", + "" + }; + + assertEquals(String.join(System.lineSeparator(), expect), readFileToString(pomFile, "UTF-8")); + } + @Test public void testMakePomWithTemplate() throws Exception { File ivyFile = workdir.newFile("ivy.xml"); @@ -173,6 +240,92 @@ public class IvyMakePomTest { assertEquals(String.join(System.lineSeparator(), expect), readFileToString(pomFile, "UTF-8")); } + /** + * Test case for IVY-1653. + */ + @Test + public void testMakePomWithTemplate1653() throws Exception { + File ivyFile = workdir.newFile("ivy.xml"); + writeLines(ivyFile, "UTF-8", Arrays.asList( + "", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + "" + )); + + File pomFile = workdir.newFile("ivy.pom"); + + File templateFile = workdir.newFile("the.pom"); + writeLines(templateFile, "UTF-8", Arrays.asList( + "", + " ${ivy.pom.groupId}", + " ${ivy.pom.artifactId}", + " ${ivy.pom.version}", + " ", + " ", + " ", + " org.aspectj", + " aspectjrt", + " 1.9.24", + " ", + " ", + " ", + "" + )); + + IvyMakePom task = new IvyMakePom(); + task.setIvyFile(ivyFile); + task.setPomFile(pomFile); + task.setPrintIvyInfo(false); + task.setProject(project); + task.setTemplateFile(templateFile); + + IvyMakePom.Mapping mapping = task.createMapping(); + mapping.setConf("default"); + mapping.setScope("compile"); + + task.execute(); + + String[] expect = { + "", + " org", + " name", + " 1.0.0-SNAPSHOT", + " ", + " ", + " ", + " org.aspectj", + " aspectjrt", + " 1.9.24", + " ", + " ", + " org.springframework", + " spring-core", + " 6.2.19", + " ", + " ", + " ", + " ", + " ", + " org.springframework", + " spring-aop", + " 6.2.9", + " compile", + " ", + " ", + "", + "" + }; + + assertEquals(String.join(System.lineSeparator(), expect), readFileToString(pomFile, "UTF-8")); + } + /** * Test case for IVY-1667. */ From 1bc11cd09c2b47694a316d07610390380ba2414b Mon Sep 17 00:00:00 2001 From: Eric Milles Date: Tue, 16 Jun 2026 12:52:59 -0500 Subject: [PATCH 2/5] next line continue --- .../ivy/plugins/parser/m2/PomModuleDescriptorWriter.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorWriter.java b/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorWriter.java index b1f6f186..ce223f9c 100644 --- a/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorWriter.java +++ b/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorWriter.java @@ -380,7 +380,9 @@ public final class PomModuleDescriptorWriter { String groupId = entry.getKey().getAttributes().get("organisation"); String version = ((OverrideDependencyDescriptorMediator) entry.getValue()).getVersion(); - if (artifactId == null || artifactId.equals("*") || groupId == null || groupId.equals("*")) continue; + if (artifactId == null || artifactId.equals("*") || groupId == null || groupId.equals("*")) { + continue; + } indent(out, indent * 3); out.println(""); From 866fddeb1868fac8af9b79d96ffb729432c71ed1 Mon Sep 17 00:00:00 2001 From: Eric Milles Date: Tue, 16 Jun 2026 14:12:52 -0500 Subject: [PATCH 3/5] dependencyManagement before dependencies when missing form template --- .../parser/m2/PomModuleDescriptorWriter.java | 16 ++++++++-------- .../core/module/descriptor/IvyMakePomTest.java | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorWriter.java b/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorWriter.java index ce223f9c..5b7741a6 100644 --- a/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorWriter.java +++ b/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorWriter.java @@ -141,25 +141,25 @@ public final class PomModuleDescriptorWriter { } if (line.contains("")) { - if (!dependenciesPrinted && !dependencyManagement) { - printDependencies(md, out, options, indent, false); - dependenciesPrinted = true; - } if (!overridesPrinted && dependencyManagement) { printOverrides(md, out, indent, false); overridesPrinted = true; } + if (!dependenciesPrinted && !dependencyManagement) { + printDependencies(md, out, options, indent, false); + dependenciesPrinted = true; + } } if (line.contains("")) { - if (!dependenciesPrinted) { - printDependencies(md, out, options, lastIndent, true); - dependenciesPrinted = true; - } if (!overridesPrinted) { printOverrides(md, out, lastIndent, true); overridesPrinted = true; } + if (!dependenciesPrinted) { + printDependencies(md, out, options, lastIndent, true); + dependenciesPrinted = true; + } } } out.println(line); diff --git a/test/java/org/apache/ivy/core/module/descriptor/IvyMakePomTest.java b/test/java/org/apache/ivy/core/module/descriptor/IvyMakePomTest.java index 1d932da4..0395d527 100644 --- a/test/java/org/apache/ivy/core/module/descriptor/IvyMakePomTest.java +++ b/test/java/org/apache/ivy/core/module/descriptor/IvyMakePomTest.java @@ -143,14 +143,6 @@ public class IvyMakePomTest { " name", " jar", " 1.0.0-SNAPSHOT", - " ", - " ", - " org.springframework", - " spring-aop", - " 6.2.9", - " compile", - " ", - " ", " ", " ", " ", @@ -160,6 +152,14 @@ public class IvyMakePomTest { " ", " ", " ", + " ", + " ", + " org.springframework", + " spring-aop", + " 6.2.9", + " compile", + " ", + " ", "", "" }; From 87319046c24c22b41e529156ec565b4b185467b8 Mon Sep 17 00:00:00 2001 From: Eric Milles Date: Tue, 16 Jun 2026 14:32:52 -0500 Subject: [PATCH 4/5] do not write empty dependencyManagement block --- .../parser/m2/PomModuleDescriptorWriter.java | 48 +++++++++++-------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorWriter.java b/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorWriter.java index 5b7741a6..72bac057 100644 --- a/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorWriter.java +++ b/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorWriter.java @@ -361,7 +361,19 @@ public final class PomModuleDescriptorWriter { private static void printOverrides(ModuleDescriptor md, PrintWriter out, int indent, boolean container) { ModuleRules mr = md.getAllDependencyDescriptorMediators(); - if (mr.getAllRules().isEmpty()) { + Map m = new LinkedHashMap<>(mr.getAllRules()); + + m.values().removeIf(value -> !(value instanceof OverrideDependencyDescriptorMediator)); + m.keySet().removeIf(key -> { + String artifactId = key.getAttributes().get("module"); + return artifactId == null || artifactId.equals("*"); + }); + m.keySet().removeIf(key -> { + String groupId = key.getAttributes().get("organisation"); + return groupId == null || groupId.equals("*"); + }); + + if (m.isEmpty()) { return; } @@ -374,27 +386,21 @@ public final class PomModuleDescriptorWriter { indent /= 2; // is second-level child of } - for (Map.Entry entry : mr.getAllRules().entrySet()) { - if (entry.getValue() instanceof OverrideDependencyDescriptorMediator) { - String artifactId = entry.getKey().getAttributes().get("module"); - String groupId = entry.getKey().getAttributes().get("organisation"); - String version = ((OverrideDependencyDescriptorMediator) entry.getValue()).getVersion(); + for (Map.Entry entry : m.entrySet()) { + String artifactId = entry.getKey().getAttributes().get("module"); + String groupId = entry.getKey().getAttributes().get("organisation"); + String version = ((OverrideDependencyDescriptorMediator) entry.getValue()).getVersion(); - if (artifactId == null || artifactId.equals("*") || groupId == null || groupId.equals("*")) { - continue; - } - - indent(out, indent * 3); - out.println(""); - indent(out, indent * 4); - out.println("" + groupId + ""); - indent(out, indent * 4); - out.println("" + artifactId + ""); - indent(out, indent * 4); - out.println("" + version + ""); - indent(out, indent * 3); - out.println(""); - } + indent(out, indent * 3); + out.println(""); + indent(out, indent * 4); + out.println("" + groupId + ""); + indent(out, indent * 4); + out.println("" + artifactId + ""); + indent(out, indent * 4); + out.println("" + version + ""); + indent(out, indent * 3); + out.println(""); } if (container) { From 37ad05cf608abc496998e277ffd65ffab2881c5a Mon Sep 17 00:00:00 2001 From: Eric Milles Date: Tue, 16 Jun 2026 14:40:34 -0500 Subject: [PATCH 5/5] PomModuleDescriptorWriter has indents between 2 and 5 --- src/etc/checkstyle/checkstyle-suppress.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/etc/checkstyle/checkstyle-suppress.xml b/src/etc/checkstyle/checkstyle-suppress.xml index c8c2db08..726eb29a 100644 --- a/src/etc/checkstyle/checkstyle-suppress.xml +++ b/src/etc/checkstyle/checkstyle-suppress.xml @@ -21,5 +21,5 @@ under the License. --> - +