You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2025/02/07 12:49:16 UTC
(camel) 01/01: CAMEL-21729: camel-jbang: dependency update pom.xml that can automatic add new Camel JARs
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch du
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 3196b08a86179e4c97cfd5232578da94f5239574
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Fri Feb 7 13:48:57 2025 +0100
CAMEL-21729: camel-jbang: dependency update pom.xml that can automatic add new Camel JARs
---
.../dsl/jbang/core/commands/DependencyList.java | 9 +
.../dsl/jbang/core/commands/DependencyUpdate.java | 205 +++++++++++++++++++--
.../org/apache/camel/tooling/maven/MavenGav.java | 23 +++
3 files changed, 220 insertions(+), 17 deletions(-)
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/DependencyList.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/DependencyList.java
index 2c4565a4e4c..c2c8a3d4ae6 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/DependencyList.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/DependencyList.java
@@ -88,6 +88,15 @@ public class DependencyList extends Export {
String quarkusVersion = null;
for (int i = 0; i < nl.getLength(); i++) {
Element node = (Element) nl.item(i);
+
+ // must be child at <project/dependencyManagement> or <project/dependencies>
+ String p = node.getParentNode().getNodeName();
+ String p2 = node.getParentNode().getParentNode().getNodeName();
+ boolean accept = "project".equals(p2) && (p.equals("dependencyManagement") || p.equals("dependencies"));
+ if (!accept) {
+ continue;
+ }
+
String g = node.getElementsByTagName("groupId").item(0).getTextContent();
String a = node.getElementsByTagName("artifactId").item(0).getTextContent();
String v = null;
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/DependencyUpdate.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/DependencyUpdate.java
index d4b8f0dbf33..bf932b5f031 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/DependencyUpdate.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/DependencyUpdate.java
@@ -17,31 +17,40 @@
package org.apache.camel.dsl.jbang.core.commands;
import java.io.File;
+import java.io.FileInputStream;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.StringJoiner;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
import org.apache.camel.tooling.maven.MavenGav;
import org.apache.camel.util.IOHelper;
+import org.apache.camel.util.StringHelper;
+import org.apache.camel.util.xml.XmlLineNumberParser;
+import org.apache.logging.log4j.util.Strings;
import picocli.CommandLine;
@CommandLine.Command(name = "update",
- description = "Updates JBang style dependencies in source file", sortOptions = false,
+ description = "Updates dependencies in Maven pom.xml or Java source file (JBang style)",
+ sortOptions = false,
showDefaultValues = true)
public class DependencyUpdate extends DependencyList {
- @CommandLine.Option(names = { "--source" },
- description = "Camel source such as .java file to have dependencies updated (//DEPS)",
- required = true)
- protected String source;
+ @CommandLine.Parameters(description = "Maven pom.xml or Java source files (JBang Style with //DEPS) to have dependencies updated", arity = "1")
+ public File file;
@CommandLine.Option(names = { "--clean" },
- description = "Regenerate list of dependencies (do not keep existing dependencies)")
+ description = "Regenerate list of dependencies (do not keep existing dependencies). Not supported for pom.xml")
protected boolean clean;
private final List<String> deps = new ArrayList<>();
- private File target;
+ private final List<MavenGav> gavs = new ArrayList<>();
public DependencyUpdate(CamelJBangMain main) {
super(main);
@@ -50,15 +59,16 @@ public class DependencyUpdate extends DependencyList {
@Override
public Integer doCall() throws Exception {
// source file must exist
- target = new File(source);
- if (!target.exists()) {
- printer().printErr("Source file does not exist: " + target);
+ if (!file.exists()) {
+ printer().printErr("Source file does not exist: " + file);
return -1;
}
- if (clean) {
+ boolean maven = "pom.xml".equals(file.getName());
+
+ if (clean && !maven) {
// remove DEPS in source file first
- updateSource();
+ updateJBangSource();
}
return super.doCall();
@@ -66,6 +76,28 @@ public class DependencyUpdate extends DependencyList {
@Override
protected void outputGav(MavenGav gav, int index, int total) {
+ try {
+ boolean maven = "pom.xml".equals(file.getName());
+ if (maven) {
+ outputGavMaven(gav, index, total);
+ } else {
+ outputGavJBang(gav, index, total);
+ }
+ } catch (Exception e) {
+ printer().printErr("Cannot update dependencies due to " + e.getMessage(), e);
+ }
+ }
+
+ protected void outputGavMaven(MavenGav gav, int index, int total) throws Exception {
+ gavs.add(gav);
+
+ boolean last = total - index <= 1;
+ if (last) {
+ updateMavenSource();
+ }
+ }
+
+ protected void outputGavJBang(MavenGav gav, int index, int total) {
if (index == 0) {
deps.add("//DEPS org.apache.camel:camel-bom:" + gav.getVersion() + "@pom");
}
@@ -79,13 +111,13 @@ public class DependencyUpdate extends DependencyList {
}
boolean last = total - index <= 1;
if (last) {
- updateSource();
+ updateJBangSource();
}
}
- private void updateSource() {
+ private void updateJBangSource() {
try {
- List<String> lines = Files.readAllLines(target.toPath());
+ List<String> lines = Files.readAllLines(file.toPath());
List<String> answer = new ArrayList<>();
// find position of where the old DEPS was
@@ -117,9 +149,148 @@ public class DependencyUpdate extends DependencyList {
}
String text = String.join(System.lineSeparator(), answer);
- IOHelper.writeText(text, target);
+ IOHelper.writeText(text, file);
} catch (Exception e) {
- printer().printErr("Error updating source file: " + target + " due to: " + e.getMessage());
+ printer().printErr("Error updating source file: " + file + " due to: " + e.getMessage());
+ }
+ }
+
+ private void updateMavenSource() throws Exception {
+ List<MavenGav> existingGavs = new ArrayList<>();
+
+ Node camelClone = null;
+ int targetLineNumber = -1;
+
+ File pom = new File(file.getName());
+ if (pom.exists()) {
+ // use line number parser as we want to find where to add new Camel JARs after the existing Camel JARs
+ Document dom = XmlLineNumberParser.parseXml(new FileInputStream(pom));
+ String camelVersion = null;
+ NodeList nl = dom.getElementsByTagName("dependency");
+ for (int i = 0; i < nl.getLength(); i++) {
+ Element node = (Element) nl.item(i);
+
+ // must be child at <project/dependencyManagement> or <project/dependencies>
+ String p = node.getParentNode().getNodeName();
+ String p2 = node.getParentNode().getParentNode().getNodeName();
+ boolean accept = "project".equals(p2) && (p.equals("dependencyManagement") || p.equals("dependencies"));
+ if (!accept) {
+ continue;
+ }
+
+ String g = node.getElementsByTagName("groupId").item(0).getTextContent();
+ String a = node.getElementsByTagName("artifactId").item(0).getTextContent();
+ String v = null;
+ NodeList vl = node.getElementsByTagName("version");
+ if (vl.getLength() > 0) {
+ v = vl.item(0).getTextContent();
+ }
+ String scope = null;
+ vl = node.getElementsByTagName("scope");
+ if (vl.getLength() > 0) {
+ scope = vl.item(0).getTextContent();
+ }
+ if (scope != null && !"compile".equals(scope)) {
+ continue;
+ }
+
+ if ("org.apache.camel".equals(g)) {
+ camelVersion = v;
+ if (camelClone == null && !"camel-bom".equals(a)) {
+ camelClone = node.cloneNode(true);
+ }
+ String num = (String) node.getUserData(XmlLineNumberParser.LINE_NUMBER_END);
+ if (num != null) {
+ targetLineNumber = Integer.parseInt(num);
+ }
+ num = (String) node.getUserData(XmlLineNumberParser.LINE_NUMBER_END);
+ if (num != null) {
+ targetLineNumber = Integer.parseInt(num);
+ }
+ }
+ if ("org.apache.camel.springboot".equals(g)) {
+ camelVersion = v;
+ String num = (String) node.getUserData(XmlLineNumberParser.LINE_NUMBER_END);
+ if (num != null) {
+ targetLineNumber = Integer.parseInt(num);
+ }
+ }
+ if ("org.apache.camel.quarkus".equals(g)) {
+ String num = (String) node.getUserData(XmlLineNumberParser.LINE_NUMBER_END);
+ if (num != null) {
+ targetLineNumber = Integer.parseInt(num);
+ }
+ }
+ if (v != null) {
+ existingGavs.add(MavenGav.parseGav(g + ":" + a + ":" + v));
+ } else {
+ existingGavs.add(MavenGav.parseGav(g + ":" + a));
+ }
+ }
+
+ // find out which JARs are new
+ List<MavenGav> updates = new ArrayList<>();
+ for (MavenGav gav : gavs) {
+ MavenGav target;
+ if (camelVersion != null) {
+ target = MavenGav.parseGav(gav.getGroupId() + ":" + gav.getArtifactId() + ":" + camelVersion);
+ } else {
+ target = MavenGav.parseGav(gav.getGroupId() + ":" + gav.getArtifactId());
+ }
+ updates.add(target);
+ }
+ // sort the new JARs being added
+ updates.sort(mavenGavComparator());
+ List<MavenGav> toBeUpdated = new ArrayList<>();
+ int changes = 0;
+ for (MavenGav update : updates) {
+ if (!existingGavs.contains(update)) {
+ toBeUpdated.add(update);
+ changes++;
+ }
+ }
+
+ if (changes > 0) {
+ // respect indent from existing GAVs
+ String line = IOHelper.loadTextLine(new FileInputStream(file), targetLineNumber);
+ line = StringHelper.before(line, "<");
+ int indent = StringHelper.countChar(line, ' ');
+ String pad = Strings.repeat(" ", indent);
+ line = IOHelper.loadTextLine(new FileInputStream(file), targetLineNumber - 1);
+ line = StringHelper.before(line, "<");
+ int indent2 = StringHelper.countChar(line, ' ');
+ String pad2 = Strings.repeat(" ", indent2);
+
+ // build GAVs to be added to pom.xml
+ StringJoiner sj = new StringJoiner("");
+ for (MavenGav gav : toBeUpdated) {
+ sj.add(pad).add("<dependency>\n");
+ sj.add(pad2).add("<groupId>" + gav.getGroupId() + "</groupId>\n");
+ sj.add(pad2).add("<artifactId>" + gav.getArtifactId() + "</artifactId>\n");
+ if (gav.getVersion() != null) {
+ sj.add(pad2).add("<version>" + gav.getVersion() + "</version>\n");
+ }
+ sj.add(pad).add("</dependency>");
+ }
+
+ StringJoiner out = new StringJoiner("\n");
+ String[] lines = IOHelper.loadText(new FileInputStream(file)).split("\n");
+ for (int i = 0; i < lines.length; i++) {
+ String txt = lines[i];
+ out.add(txt);
+ if (i == targetLineNumber - 1) {
+ out.add(sj.toString());
+ }
+ }
+ if (changes > 1) {
+ outPrinter().println("Updating pom.xml with " + changes + " dependencies added");
+ } else {
+ outPrinter().println("Updating pom.xml with 1 dependency added");
+ }
+ IOHelper.writeText(out.toString(), file);
+ } else {
+ outPrinter().println("No updates to pom.xml");
+ }
}
}
diff --git a/tooling/camel-tooling-maven/src/main/java/org/apache/camel/tooling/maven/MavenGav.java b/tooling/camel-tooling-maven/src/main/java/org/apache/camel/tooling/maven/MavenGav.java
index 2237c0abeca..dcfb5c515d4 100644
--- a/tooling/camel-tooling-maven/src/main/java/org/apache/camel/tooling/maven/MavenGav.java
+++ b/tooling/camel-tooling-maven/src/main/java/org/apache/camel/tooling/maven/MavenGav.java
@@ -16,6 +16,8 @@
*/
package org.apache.camel.tooling.maven;
+import java.util.Objects;
+
/**
* Maven GAV model with parsing support and special rules for some names:
* <ul>
@@ -171,6 +173,27 @@ public final class MavenGav {
this.classifier = classifier;
}
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof MavenGav mavenGav)) {
+ return false;
+ }
+
+ return groupId.equals(mavenGav.groupId) && artifactId.equals(mavenGav.artifactId)
+ && Objects.equals(version, mavenGav.version) && Objects.equals(packaging, mavenGav.packaging)
+ && Objects.equals(classifier, mavenGav.classifier);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = groupId.hashCode();
+ result = 31 * result + artifactId.hashCode();
+ result = 31 * result + Objects.hashCode(version);
+ result = 31 * result + Objects.hashCode(packaging);
+ result = 31 * result + Objects.hashCode(classifier);
+ return result;
+ }
+
@Override
public String toString() {
if (version != null) {