Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Export-Package: org.apache.ivy;version="2.0.0",
org.apache.ivy.plugins.namespace;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.0.0",
org.apache.ivy.plugins.parser.m2;version="2.6.0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just out of curiousity, is this Eclipse that's doing this for you?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am doing this. If you look at the 2.5.3 manifest, all the versions are stuck at 2.0.0 which is not really proper for OSGi.

org.apache.ivy.plugins.parser.xml;version="2.0.0",
org.apache.ivy.plugins.report;version="2.0.0",
org.apache.ivy.plugins.repository;version="2.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,15 @@
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;
Expand Down Expand Up @@ -72,22 +76,18 @@ public static void write(ModuleDescriptor md, File output, PomWriterOptions opti
throws IOException {
LineNumberReader in;
if (options.getTemplate() == null) {
in = new LineNumberReader(new InputStreamReader(
PomModuleDescriptorWriter.class.getResourceAsStream("pom.template")));
in = new LineNumberReader(new InputStreamReader(PomModuleDescriptorWriter.class.getResourceAsStream("pom.template")));
} else {
in = new LineNumberReader(new InputStreamReader(new FileInputStream(
options.getTemplate())));
in = new LineNumberReader(new InputStreamReader(new FileInputStream(options.getTemplate())));
}

if (output.getParentFile() != null) {
output.getParentFile().mkdirs();
}
PrintWriter out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(output),
StandardCharsets.UTF_8));
try {

try (PrintWriter out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(output), StandardCharsets.UTF_8))) {
IvySettings settings = IvyContext.getContext().getSettings();
IvyVariableContainer variables = new IvyVariableContainerWrapper(
settings.getVariableContainer());
IvyVariableContainer variables = new IvyVariableContainerWrapper(settings.getVariableContainer());

variables.setVariable("ivy.pom.license", SKIP_LINE, true);
variables.setVariable("ivy.pom.header", SKIP_LINE, true);
Expand All @@ -103,53 +103,69 @@ public static void write(ModuleDescriptor md, File output, PomWriterOptions opti
variables.setVariable("ivy.pom.license", options.getLicenseHeader(), true);
}
if (options.isPrintIvyInfo()) {
String header = "<!--\n" + " Apache Maven 2 POM generated by Apache Ivy\n"
+ " " + Ivy.getIvyHomeURL() + "\n" + " Apache Ivy version: "
+ Ivy.getIvyVersion() + " " + Ivy.getIvyDate() + "\n" + "-->";
String header
= "<!--\n" // TODO: replace \n with lineSeparator()
+ " Apache Maven 2 POM generated by Apache Ivy\n"
+ " " + Ivy.getIvyHomeURL() + "\n"
+ " Apache Ivy version: " + Ivy.getIvyVersion() + " " + Ivy.getIvyDate() + "\n"
+ "-->";
variables.setVariable("ivy.pom.header", header, true);
}

setModuleVariables(md, variables, options);

boolean dependencyManagement = false;
boolean dependenciesPrinted = false;
boolean overridesPrinted = false;

int lastIndent = 0;
int indent = 0;
String line = in.readLine();
while (line != null) {
String line;
while ((line = in.readLine()) != null) {
line = IvyPatternHelper.substituteVariables(line, variables);
if (line.contains(SKIP_LINE)) {
// skip this line
line = in.readLine();
continue;
}

if (line.trim().isEmpty()) {
// empty line
out.println(line);
line = in.readLine();
continue;
}
if (!line.trim().isEmpty()) {
lastIndent = indent;
indent = line.indexOf('<');

lastIndent = indent;
indent = line.indexOf('<');
if (line.contains("<dependencyManagement>")) {
dependencyManagement = true;
}

if (!dependenciesPrinted && line.contains("</dependencies>")) {
printDependencies(md, out, options, indent, false);
dependenciesPrinted = true;
}
if (line.contains("</dependencyManagement>")) {
dependencyManagement = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should also check here that any overrides are printed.
This to tackle the case where the template contains an empty <dependencyManagent> element (without <dependencies> subelement)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I suppose that's possible. Was just handling likely scenarios first.

}

if (!dependenciesPrinted && line.contains("</project>")) {
printDependencies(md, out, options, lastIndent, true);
dependenciesPrinted = true;
}
if (line.contains("</dependencies>")) {
if (!dependenciesPrinted && !dependencyManagement) {
printDependencies(md, out, options, indent, false);
dependenciesPrinted = true;
}
if (!overridesPrinted && dependencyManagement) {
printOverrides(md, out, indent, false);
overridesPrinted = true;
}
}

if (line.contains("</project>")) {
if (!dependenciesPrinted) {
printDependencies(md, out, options, lastIndent, true);
dependenciesPrinted = true;
}
if (!overridesPrinted) {
printOverrides(md, out, lastIndent, true);
overridesPrinted = true;
}
}
}
out.println(line);
line = in.readLine();
}
} finally {
in.close();
out.close();
}
}

Expand Down Expand Up @@ -343,8 +359,51 @@ private static void printExclusions(ExcludeRule[] exclusions, PrintWriter out, i
out.println("</exclusions>");
}

private static DependencyDescriptor[] getDependencies(ModuleDescriptor md,
PomWriterOptions options) {
private static void printOverrides(ModuleDescriptor md, PrintWriter out, int indent, boolean container) {
ModuleRules<DependencyDescriptorMediator> mr = md.getAllDependencyDescriptorMediators();
if (mr.getAllRules().isEmpty()) {
return;
}
Copy link
Contributor

@maartenc maartenc Aug 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps also return here if none of the rules are an instance of non-wildcard OverrideDependencyDescriptorMediator.
This way, we avoid an empty <dependencyManagement>/<dependencies>-construct if container was true.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure -- I tried to keep it simple instead of building up a filtered collection.


if (container) {
indent(out, indent);
out.println("<dependencyManagement>");
indent(out, indent * 2);
out.println("<dependencies>");
} else {
indent /= 3; // <dependency> is third-level child of <project>
}

for (Map.Entry<MapMatcher, DependencyDescriptorMediator> 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("<dependency>");
indent(out, indent * 4);
out.println("<groupId>" + groupId + "</groupId>");
indent(out, indent * 4);
out.println("<artifactId>" + artifactId + "</artifactId>");
indent(out, indent * 4);
out.println("<version>" + version + "</version>");
indent(out, indent * 3);
out.println("</dependency>");
}
}

if (container) {
indent(out, indent * 2);
out.println("</dependencies>");
indent(out, indent);
out.println("</dependencyManagement>");
}
}

private static DependencyDescriptor[] getDependencies(ModuleDescriptor md, PomWriterOptions options) {
String[] confs = ConfigurationUtils.replaceWildcards(options.getConfs(), md);

List<DependencyDescriptor> result = new ArrayList<>();
Expand Down
Loading