diff --git a/tycho-extras/tycho-version-bump-plugin/src/main/java/org/eclipse/tycho/versionbump/UpdateTargetMojo.java b/tycho-extras/tycho-version-bump-plugin/src/main/java/org/eclipse/tycho/versionbump/UpdateTargetMojo.java
index af9ab2a7ba..f37fb0ba5d 100644
--- a/tycho-extras/tycho-version-bump-plugin/src/main/java/org/eclipse/tycho/versionbump/UpdateTargetMojo.java
+++ b/tycho-extras/tycho-version-bump-plugin/src/main/java/org/eclipse/tycho/versionbump/UpdateTargetMojo.java
@@ -19,6 +19,8 @@
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collections;
@@ -28,11 +30,17 @@
import javax.xml.parsers.ParserConfigurationException;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.Dependency;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
+import org.eclipse.aether.resolution.ArtifactResolutionException;
+import org.eclipse.aether.resolution.VersionRangeResolutionException;
import org.eclipse.tycho.TargetEnvironment;
+import org.eclipse.tycho.core.maven.MavenDependenciesResolver;
import org.eclipse.tycho.core.resolver.P2ResolutionResult;
import org.eclipse.tycho.p2resolver.TargetDefinitionVariableResolver;
import org.eclipse.tycho.targetplatform.TargetDefinition;
@@ -43,10 +51,12 @@
import org.eclipse.tycho.targetplatform.TargetDefinitionFile;
import org.eclipse.tycho.targetplatform.TargetPlatformArtifactResolver;
import org.eclipse.tycho.targetplatform.TargetResolveException;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
+
+import de.pdark.decentxml.Document;
+import de.pdark.decentxml.Element;
+import de.pdark.decentxml.XMLIOSource;
+import de.pdark.decentxml.XMLParser;
+import de.pdark.decentxml.XMLWriter;
/**
* Quick&dirty way to update .target file to use latest versions of IUs available from specified
@@ -60,16 +70,23 @@ public class UpdateTargetMojo extends AbstractUpdateMojo {
@Component
private TargetDefinitionVariableResolver varResolver;
- @Override
- protected void doUpdate() throws IOException, URISyntaxException, ParserConfigurationException, SAXException,
- TargetResolveException, MojoFailureException {
+ @Component
+ private MavenDependenciesResolver resolver;
+ @Component
+ private MavenSession mavenSession;
+
+ @Override
+ protected void doUpdate() throws IOException, URISyntaxException, ParserConfigurationException,
+ TargetResolveException, MojoFailureException, VersionRangeResolutionException, ArtifactResolutionException {
File file = getFileToBeUpdated();
getLog().info("Update target file " + file);
- Document target;
+ //we use the descent xml parser here because we need to retain the formating of the original file
+ XMLParser parser = new XMLParser();
+ Document target = parser.parse(new XMLIOSource(targetFile));
+ boolean changed = false;
try (FileInputStream input = new FileInputStream(file)) {
- target = TargetDefinitionFile.parseDocument(input);
- TargetDefinitionFile parsedTarget = TargetDefinitionFile.parse(target, file.getAbsolutePath());
+ TargetDefinitionFile parsedTarget = TargetDefinitionFile.read(file);
resolutionContext.setEnvironments(Collections.singletonList(TargetEnvironment.getRunningEnvironment()));
resolutionContext.addTargetDefinition(new LatestVersionTarget(parsedTarget, varResolver));
resolutionContext.setIgnoreLocalArtifacts(true);
@@ -79,22 +96,89 @@ protected void doUpdate() throws IOException, URISyntaxException, ParserConfigur
for (P2ResolutionResult.Entry entry : result.getArtifacts()) {
ius.put(entry.getId(), entry.getVersion());
}
- //update
- NodeList units = target.getElementsByTagName("unit");
- for (int i = 0; i < units.getLength(); i++) {
- Element unit = (Element) units.item(i);
- String id = unit.getAttribute("id");
- String version = ius.get(id);
- if (version != null) {
- unit.setAttribute("version", version);
- } else {
- getLog().error("Resolution result does not contain root installable unit: " + id);
+ for (Element iuLocation : getLocations("InstallableUnit", target)) {
+ List children = iuLocation.getChildren("unit");
+ for (Element unit : children) {
+ String id = unit.getAttributeValue("id");
+ String version = ius.get(id);
+ if (version != null) {
+ String currentVersion = unit.getAttributeValue("version");
+ if (version.equals(currentVersion)) {
+ getLog().debug("unit '" + id + "' is already up-to date");
+ } else {
+ changed = true;
+ getLog().info(
+ "Update version of unit '" + id + "' from " + currentVersion + " > " + version);
+ unit.setAttribute("version", version);
+ }
+ } else {
+ getLog().warn("Resolution result does not contain root installable unit '" + id
+ + "' update is skipped!");
+ }
+ }
+ }
+ for (Element mavenLocation : getLocations("Maven", target)) {
+ Element dependencies = mavenLocation.getChild("dependencies");
+ if (dependencies != null) {
+ for (Element dependency : dependencies.getChildren("dependency")) {
+ Dependency mavenDependency = new Dependency();
+ mavenDependency.setGroupId(getElementValue("groupId", dependency));
+ mavenDependency.setArtifactId(getElementValue("artifactId", dependency));
+ mavenDependency.setVersion(getElementValue("version", dependency));
+ mavenDependency.setType(getElementValue("type", dependency));
+ mavenDependency.setClassifier(getElementValue("classifier", dependency));
+ Artifact highestVersionArtifact = resolver.resolveHighestVersion(project, mavenSession,
+ mavenDependency);
+ String newVersion = highestVersionArtifact.getVersion();
+ if (newVersion.equals(mavenDependency.getVersion())) {
+ getLog().debug(mavenDependency + " is already up-to date");
+ } else {
+ changed = true;
+ setElementValue("version", newVersion, dependency);
+ getLog().info("update " + mavenDependency + " to version " + newVersion);
+ }
+ }
}
}
}
- try (FileOutputStream outputStream = new FileOutputStream(file)) {
- TargetDefinitionFile.writeDocument(target, outputStream);
+ if (changed) {
+ String enc = target.getEncoding() != null ? target.getEncoding() : "UTF-8";
+ try (Writer w = new OutputStreamWriter(new FileOutputStream(file), enc); XMLWriter xw = new XMLWriter(w)) {
+ try {
+ target.toXML(xw);
+ } finally {
+ xw.flush();
+ }
+ }
+ }
+ }
+
+ private void setElementValue(String name, String value, Element root) {
+ Element child = root.getChild(name);
+ if (child != null) {
+ child.setText(value);
+ }
+ }
+
+ private String getElementValue(String name, Element root) {
+ Element child = root.getChild(name);
+ if (child != null) {
+ String text = child.getText().trim();
+ if (text.isBlank()) {
+ return null;
+ }
+ return text;
+ }
+ return null;
+ }
+
+ private List getLocations(String type, Document target) {
+ Element locations = target.getRootElement().getChild("locations");
+ if (locations != null) {
+ return locations.getChildren().stream().filter(elem -> type.equals(elem.getAttributeValue("type")))
+ .toList();
}
+ return List.of();
}
@Override
diff --git a/tycho-its/projects/tycho-version-bump-plugin/update-target/update-target.target b/tycho-its/projects/tycho-version-bump-plugin/update-target/update-target.target
index eeed349f9b..6b6d492240 100644
--- a/tycho-its/projects/tycho-version-bump-plugin/update-target/update-target.target
+++ b/tycho-its/projects/tycho-version-bump-plugin/update-target/update-target.target
@@ -2,15 +2,22 @@
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+ javax.annotation
+ javax.annotation-api
+ 1.2
+ jar
+
+
-
+
\ No newline at end of file
diff --git a/tycho-its/src/test/java/org/eclipse/tycho/test/VersionBumpPluginTest.java b/tycho-its/src/test/java/org/eclipse/tycho/test/VersionBumpPluginTest.java
index 342ae9aa29..42fb7b08c5 100644
--- a/tycho-its/src/test/java/org/eclipse/tycho/test/VersionBumpPluginTest.java
+++ b/tycho-its/src/test/java/org/eclipse/tycho/test/VersionBumpPluginTest.java
@@ -12,17 +12,20 @@
*******************************************************************************/
package org.eclipse.tycho.test;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
-import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.File;
import java.io.FileInputStream;
+import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.maven.it.Verifier;
import org.eclipse.tycho.targetplatform.TargetDefinition.InstallableUnitLocation;
import org.eclipse.tycho.targetplatform.TargetDefinition.Location;
+import org.eclipse.tycho.targetplatform.TargetDefinition.MavenDependency;
+import org.eclipse.tycho.targetplatform.TargetDefinition.MavenGAVLocation;
import org.eclipse.tycho.targetplatform.TargetDefinition.Unit;
import org.eclipse.tycho.targetplatform.TargetDefinitionFile;
import org.eclipse.tycho.version.TychoVersion;
@@ -55,6 +58,13 @@ public void testUpdateTarget() throws Exception {
assertIUVersion("org.eclipse.jdt.feature.group", "3.18.500.v20200902-1800", units, targetFile);
assertIUVersion("org.eclipse.platform.ide", "4.17.0.I20200902-1800", units, targetFile);
assertIUVersion("org.eclipse.pde.feature.group", "3.14.500.v20200902-1800", units, targetFile);
+ MavenGAVLocation maven = locations.stream().filter(MavenGAVLocation.class::isInstance)
+ .map(MavenGAVLocation.class::cast).findFirst()
+ .orElseThrow(() -> new AssertionError("Maven Location not found!"));
+ Collection roots = maven.getRoots();
+ assertEquals(1, roots.size());
+ MavenDependency dependency = roots.iterator().next();
+ assertEquals("Maven version was not updated correctly in " + targetFile, "1.3.2", dependency.getVersion());
}
}