From 788652d0f53ff71f62a795ffdedac0846342ea94 Mon Sep 17 00:00:00 2001 From: Bruno Verachten Date: Mon, 30 Sep 2024 15:27:16 +0200 Subject: [PATCH 01/17] Add POM modifier to handle POM modifications Related to #20 --- For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/gounthar/plugin-modernizer-tool/issues/20?shareId=XXXX-XXXX-XXXX-XXXX). --- .../core/impl/PluginModernizer.java | 1 + .../core/utils/PomModifier.java | 90 +++++++++++++++++++ .../core/utils/PomModifierTest.java | 74 +++++++++++++++ 3 files changed, 165 insertions(+) create mode 100644 plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifier.java create mode 100644 plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifierTest.java diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/impl/PluginModernizer.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/impl/PluginModernizer.java index 6848fbc6..18c23b28 100644 --- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/impl/PluginModernizer.java +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/impl/PluginModernizer.java @@ -12,6 +12,7 @@ import io.jenkins.tools.pluginmodernizer.core.utils.JdkFetcher; import io.jenkins.tools.pluginmodernizer.core.utils.PluginVersionUtils; import io.jenkins.tools.pluginmodernizer.core.utils.UpdateCenterUtils; +import io.jenkins.tools.pluginmodernizer.core.utils.PomModifier; import java.util.List; import java.util.stream.Collectors; import org.openrewrite.Recipe; diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifier.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifier.java new file mode 100644 index 00000000..2d6fd6a4 --- /dev/null +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifier.java @@ -0,0 +1,90 @@ +package io.jenkins.tools.pluginmodernizer.core.utils; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import java.io.File; + +public class PomModifier { + + private Document document; + + public PomModifier(String pomFilePath) { + try { + File pomFile = new File(pomFilePath); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + document = dBuilder.parse(pomFile); + document.getDocumentElement().normalize(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void removeOffendingProperties() { + NodeList propertiesList = document.getElementsByTagName("properties"); + if (propertiesList.getLength() > 0) { + Node propertiesNode = propertiesList.item(0); + NodeList childNodes = propertiesNode.getChildNodes(); + for (int i = 0; i < childNodes.getLength(); i++) { + Node node = childNodes.item(i); + if (node.getNodeType() == Node.ELEMENT_NODE) { + String nodeName = node.getNodeName(); + if (nodeName.equals("project.basedir") || nodeName.equals("basedir")) { + propertiesNode.removeChild(node); + } + } + } + } + } + + public void addParentPom(String groupId, String artifactId, String version) { + Element parentElement = document.createElement("parent"); + + Element groupIdElement = document.createElement("groupId"); + groupIdElement.appendChild(document.createTextNode(groupId)); + parentElement.appendChild(groupIdElement); + + Element artifactIdElement = document.createElement("artifactId"); + artifactIdElement.appendChild(document.createTextNode(artifactId)); + parentElement.appendChild(artifactIdElement); + + Element versionElement = document.createElement("version"); + versionElement.appendChild(document.createTextNode(version)); + parentElement.appendChild(versionElement); + + document.getDocumentElement().appendChild(parentElement); + } + + public void updateJenkinsMinimalVersion(String version) { + NodeList propertiesList = document.getElementsByTagName("properties"); + if (propertiesList.getLength() > 0) { + Node propertiesNode = propertiesList.item(0); + Element jenkinsVersionElement = document.createElement("jenkins.version"); + jenkinsVersionElement.appendChild(document.createTextNode(version)); + propertiesNode.appendChild(jenkinsVersionElement); + } + } + + public void savePom(String outputPath) { + try { + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + DOMSource source = new DOMSource(document); + StreamResult result = new StreamResult(new File(outputPath)); + transformer.transform(source, result); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifierTest.java b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifierTest.java new file mode 100644 index 00000000..2f85f943 --- /dev/null +++ b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifierTest.java @@ -0,0 +1,74 @@ +package io.jenkins.tools.pluginmodernizer.core.utils; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class PomModifierTest { + + private static final String TEST_POM_PATH = "src/test/resources/test-pom.xml"; + private static final String OUTPUT_POM_PATH = "src/test/resources/output-pom.xml"; + + @BeforeEach + public void setUp() throws Exception { + Files.copy(Path.of(TEST_POM_PATH), Path.of(OUTPUT_POM_PATH)); + } + + @Test + public void testRemoveOffendingProperties() throws Exception { + PomModifier pomModifier = new PomModifier(OUTPUT_POM_PATH); + pomModifier.removeOffendingProperties(); + pomModifier.savePom(OUTPUT_POM_PATH); + + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + Document doc = dBuilder.parse(new File(OUTPUT_POM_PATH)); + doc.getDocumentElement().normalize(); + + Element propertiesElement = (Element) doc.getElementsByTagName("properties").item(0); + assertTrue(propertiesElement.getElementsByTagName("project.basedir").getLength() == 0); + assertTrue(propertiesElement.getElementsByTagName("basedir").getLength() == 0); + } + + @Test + public void testAddParentPom() throws Exception { + PomModifier pomModifier = new PomModifier(OUTPUT_POM_PATH); + pomModifier.addParentPom("io.jenkins.plugin-modernizer", "plugin-modernizer-parent-pom", "1.0"); + pomModifier.savePom(OUTPUT_POM_PATH); + + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + Document doc = dBuilder.parse(new File(OUTPUT_POM_PATH)); + doc.getDocumentElement().normalize(); + + Element parentElement = (Element) doc.getElementsByTagName("parent").item(0); + assertEquals("io.jenkins.plugin-modernizer", parentElement.getElementsByTagName("groupId").item(0).getTextContent()); + assertEquals("plugin-modernizer-parent-pom", parentElement.getElementsByTagName("artifactId").item(0).getTextContent()); + assertEquals("1.0", parentElement.getElementsByTagName("version").item(0).getTextContent()); + } + + @Test + public void testUpdateJenkinsMinimalVersion() throws Exception { + PomModifier pomModifier = new PomModifier(OUTPUT_POM_PATH); + pomModifier.updateJenkinsMinimalVersion("2.289.1"); + pomModifier.savePom(OUTPUT_POM_PATH); + + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + Document doc = dBuilder.parse(new File(OUTPUT_POM_PATH)); + doc.getDocumentElement().normalize(); + + Element propertiesElement = (Element) doc.getElementsByTagName("properties").item(0); + assertEquals("2.289.1", propertiesElement.getElementsByTagName("jenkins.version").item(0).getTextContent()); + } +} From 6e2fb32253916589745ce6ce2a8c30aec261a945 Mon Sep 17 00:00:00 2001 From: gounthar Date: Mon, 30 Sep 2024 18:26:14 +0200 Subject: [PATCH 02/17] fix(pom): Compiles at last. --- .../core/impl/PluginModernizer.java | 1 - .../core/utils/PomModifier.java | 157 +++++++++++++++--- .../core/utils/PomModifierTest.java | 80 ++++++--- updatecli/scripts/jenkins-lts-baseline.sh | 34 ++++ updatecli/scripts/jenkins-lts.sh | 33 ++++ updatecli/updatecli.d/jenkins-lts.yaml | 81 +++++++++ 6 files changed, 338 insertions(+), 48 deletions(-) create mode 100644 updatecli/scripts/jenkins-lts-baseline.sh create mode 100644 updatecli/scripts/jenkins-lts.sh create mode 100644 updatecli/updatecli.d/jenkins-lts.yaml diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/impl/PluginModernizer.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/impl/PluginModernizer.java index 18c23b28..6848fbc6 100644 --- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/impl/PluginModernizer.java +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/impl/PluginModernizer.java @@ -12,7 +12,6 @@ import io.jenkins.tools.pluginmodernizer.core.utils.JdkFetcher; import io.jenkins.tools.pluginmodernizer.core.utils.PluginVersionUtils; import io.jenkins.tools.pluginmodernizer.core.utils.UpdateCenterUtils; -import io.jenkins.tools.pluginmodernizer.core.utils.PomModifier; import java.util.List; import java.util.stream.Collectors; import org.openrewrite.Recipe; diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifier.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifier.java index 2d6fd6a4..514b991e 100644 --- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifier.java +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifier.java @@ -1,10 +1,11 @@ package io.jenkins.tools.pluginmodernizer.core.utils; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import java.io.File; +import java.nio.file.Files; +import java.nio.file.InvalidPathException; +import java.nio.file.Path; +import java.nio.file.Paths; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.OutputKeys; @@ -12,24 +13,65 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; -import java.io.File; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +/** + * Utility class for modifying POM files. + */ public class PomModifier { + private static final Logger LOG = LoggerFactory.getLogger(PomModifier.class); private Document document; + // Base directory for file operations + private static final String BASE_DIR = System.getProperty("java.io.tmpdir"); + + /** + * Constructor for PomModifier. + * + * @param pomFilePath the path to the POM file + * @throws IllegalArgumentException if the file path is invalid + */ + @SuppressFBWarnings("PATH_TRAVERSAL_IN") public PomModifier(String pomFilePath) { try { - File pomFile = new File(pomFilePath); + // Validate the file path + Path path = Paths.get(pomFilePath).normalize().toAbsolutePath(); + if (!Files.exists(path) || !Files.isRegularFile(path)) { + throw new IllegalArgumentException("Invalid file path: " + path.toString()); + } + + File pomFile = path.toFile(); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + dbFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + dbFactory.setFeature("http://xml.org/sax/features/external-general-entities", false); + dbFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + dbFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); + dbFactory.setXIncludeAware(false); + dbFactory.setExpandEntityReferences(false); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); document = dBuilder.parse(pomFile); document.getDocumentElement().normalize(); + } catch (InvalidPathException e) { + LOG.error("Invalid file path: " + e.getMessage()); + throw new IllegalArgumentException("Invalid file path: " + pomFilePath, e); + } catch (IllegalArgumentException e) { + LOG.error("Invalid file path: " + e.getMessage()); + throw e; // Re-throw to ensure the caller is aware of the issue } catch (Exception e) { - e.printStackTrace(); + LOG.error("Error initializing PomModifier: " + e.getMessage(), e); + throw new RuntimeException("Failed to initialize PomModifier", e); // Re-throw as a runtime exception } } + /** + * Removes offending properties from the POM file. + */ public void removeOffendingProperties() { NodeList propertiesList = document.getElementsByTagName("properties"); if (propertiesList.getLength() > 0) { @@ -39,7 +81,7 @@ public void removeOffendingProperties() { Node node = childNodes.item(i); if (node.getNodeType() == Node.ELEMENT_NODE) { String nodeName = node.getNodeName(); - if (nodeName.equals("project.basedir") || nodeName.equals("basedir")) { + if (nodeName.equals("jenkins-test-harness.version") || nodeName.equals("java.level")) { propertiesNode.removeChild(node); } } @@ -47,44 +89,109 @@ public void removeOffendingProperties() { } } - public void addParentPom(String groupId, String artifactId, String version) { - Element parentElement = document.createElement("parent"); + /** + * Updates the parent POM information. + * + * @param groupId the groupId to set + * @param artifactId the artifactId to set + * @param version the version to set + */ + public void updateParentPom(String groupId, String artifactId, String version) { + NodeList parentList = document.getElementsByTagName("parent"); + if (parentList.getLength() > 0) { + Node parentNode = parentList.item(0); + NodeList childNodes = parentNode.getChildNodes(); + for (int i = 0; i < childNodes.getLength(); i++) { + Node node = childNodes.item(i); + if (node.getNodeType() == Node.ELEMENT_NODE) { + switch (node.getNodeName()) { + case "groupId": + node.setTextContent(groupId); + break; + case "artifactId": + node.setTextContent(artifactId); + break; + case "version": + node.setTextContent(version); + break; + default: + LOG.warn("Unexpected element in parent POM: " + node.getNodeName()); + break; + } + } + } + } else { + Element parentElement = document.createElement("parent"); - Element groupIdElement = document.createElement("groupId"); - groupIdElement.appendChild(document.createTextNode(groupId)); - parentElement.appendChild(groupIdElement); + Element groupIdElement = document.createElement("groupId"); + groupIdElement.appendChild(document.createTextNode(groupId)); + parentElement.appendChild(groupIdElement); - Element artifactIdElement = document.createElement("artifactId"); - artifactIdElement.appendChild(document.createTextNode(artifactId)); - parentElement.appendChild(artifactIdElement); + Element artifactIdElement = document.createElement("artifactId"); + artifactIdElement.appendChild(document.createTextNode(artifactId)); + parentElement.appendChild(artifactIdElement); - Element versionElement = document.createElement("version"); - versionElement.appendChild(document.createTextNode(version)); - parentElement.appendChild(versionElement); + Element versionElement = document.createElement("version"); + versionElement.appendChild(document.createTextNode(version)); + parentElement.appendChild(versionElement); - document.getDocumentElement().appendChild(parentElement); + document.getDocumentElement().appendChild(parentElement); + } } + /** + * Updates the Jenkins minimal version in the POM file. + * + * @param version the version to set + */ public void updateJenkinsMinimalVersion(String version) { NodeList propertiesList = document.getElementsByTagName("properties"); if (propertiesList.getLength() > 0) { Node propertiesNode = propertiesList.item(0); - Element jenkinsVersionElement = document.createElement("jenkins.version"); - jenkinsVersionElement.appendChild(document.createTextNode(version)); - propertiesNode.appendChild(jenkinsVersionElement); + NodeList childNodes = propertiesNode.getChildNodes(); + boolean versionUpdated = false; + for (int i = 0; i < childNodes.getLength(); i++) { + Node node = childNodes.item(i); + if (node.getNodeType() == Node.ELEMENT_NODE + && node.getNodeName().equals("jenkins.version")) { + node.setTextContent(version); + versionUpdated = true; + break; + } + } + if (!versionUpdated) { + Element jenkinsVersionElement = document.createElement("jenkins.version"); + jenkinsVersionElement.appendChild(document.createTextNode(version)); + propertiesNode.appendChild(jenkinsVersionElement); + } } } + /** + * Saves the modified POM file to the specified output path. + * + * @param outputPath the path to save the POM file + * @throws IllegalArgumentException if the output path is invalid + */ + @SuppressFBWarnings("PATH_TRAVERSAL_IN") public void savePom(String outputPath) { try { + // Validate the output path + Path path = Paths.get(outputPath).normalize().toAbsolutePath(); + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + transformerFactory.setFeature("http://javax.xml.XMLConstants/feature/secure-processing", true); Transformer transformer = transformerFactory.newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); DOMSource source = new DOMSource(document); StreamResult result = new StreamResult(new File(outputPath)); transformer.transform(source, result); + } catch (InvalidPathException e) { + LOG.error("Invalid output path: " + e.getMessage()); + throw new IllegalArgumentException("Invalid output path: " + outputPath, e); } catch (Exception e) { - e.printStackTrace(); + LOG.error("Error saving POM file: " + e.getMessage(), e); + throw new RuntimeException("Failed to save POM file", e); } } } diff --git a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifierTest.java b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifierTest.java index 2f85f943..c348a26a 100644 --- a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifierTest.java +++ b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifierTest.java @@ -1,27 +1,47 @@ package io.jenkins.tools.pluginmodernizer.core.utils; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.w3c.dom.Document; -import org.w3c.dom.Element; +import static java.nio.file.Files.createTempFile; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; import java.io.File; +import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.logging.Logger; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Element; public class PomModifierTest { + private static final Logger logger = Logger.getLogger(PomModifierTest.class.getName()); private static final String TEST_POM_PATH = "src/test/resources/test-pom.xml"; - private static final String OUTPUT_POM_PATH = "src/test/resources/output-pom.xml"; + private static final String OUTPUT_POM_PATH; + + static { + try { + OUTPUT_POM_PATH = Files.move( + createTempFile(null, null), + Paths.get(System.getProperty("java.io.tmpdir"), "output-pom.xml"), + StandardCopyOption.REPLACE_EXISTING) + .toAbsolutePath() + .toString(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } @BeforeEach public void setUp() throws Exception { - Files.copy(Path.of(TEST_POM_PATH), Path.of(OUTPUT_POM_PATH)); + Path tempFile = new File(OUTPUT_POM_PATH).toPath(); + Files.copy(Path.of(TEST_POM_PATH), tempFile, StandardCopyOption.REPLACE_EXISTING); + logger.info("Setup completed, copied test POM to temporary file: " + tempFile.toString()); } @Test @@ -35,15 +55,20 @@ public void testRemoveOffendingProperties() throws Exception { Document doc = dBuilder.parse(new File(OUTPUT_POM_PATH)); doc.getDocumentElement().normalize(); - Element propertiesElement = (Element) doc.getElementsByTagName("properties").item(0); - assertTrue(propertiesElement.getElementsByTagName("project.basedir").getLength() == 0); - assertTrue(propertiesElement.getElementsByTagName("basedir").getLength() == 0); + Element propertiesElement = + (Element) doc.getElementsByTagName("properties").item(0); + assertTrue(propertiesElement.getElementsByTagName("java.level").getLength() == 0); + assertTrue(propertiesElement + .getElementsByTagName("jenkins-test-harness.version") + .getLength() + == 0); + logger.info("Offending properties removed successfully"); } @Test - public void testAddParentPom() throws Exception { + public void testUpdateParentPom() throws Exception { PomModifier pomModifier = new PomModifier(OUTPUT_POM_PATH); - pomModifier.addParentPom("io.jenkins.plugin-modernizer", "plugin-modernizer-parent-pom", "1.0"); + pomModifier.updateParentPom("org.jenkins-ci.plugins", "plugin", "4.80"); pomModifier.savePom(OUTPUT_POM_PATH); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); @@ -52,15 +77,20 @@ public void testAddParentPom() throws Exception { doc.getDocumentElement().normalize(); Element parentElement = (Element) doc.getElementsByTagName("parent").item(0); - assertEquals("io.jenkins.plugin-modernizer", parentElement.getElementsByTagName("groupId").item(0).getTextContent()); - assertEquals("plugin-modernizer-parent-pom", parentElement.getElementsByTagName("artifactId").item(0).getTextContent()); - assertEquals("1.0", parentElement.getElementsByTagName("version").item(0).getTextContent()); + assertEquals( + "org.jenkins-ci.plugins", + parentElement.getElementsByTagName("groupId").item(0).getTextContent()); + assertEquals( + "plugin", + parentElement.getElementsByTagName("artifactId").item(0).getTextContent()); + assertEquals( + "4.80", parentElement.getElementsByTagName("version").item(0).getTextContent()); } @Test public void testUpdateJenkinsMinimalVersion() throws Exception { PomModifier pomModifier = new PomModifier(OUTPUT_POM_PATH); - pomModifier.updateJenkinsMinimalVersion("2.289.1"); + pomModifier.updateJenkinsMinimalVersion("2.462.2"); pomModifier.savePom(OUTPUT_POM_PATH); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); @@ -68,7 +98,13 @@ public void testUpdateJenkinsMinimalVersion() throws Exception { Document doc = dBuilder.parse(new File(OUTPUT_POM_PATH)); doc.getDocumentElement().normalize(); - Element propertiesElement = (Element) doc.getElementsByTagName("properties").item(0); - assertEquals("2.289.1", propertiesElement.getElementsByTagName("jenkins.version").item(0).getTextContent()); + Element propertiesElement = + (Element) doc.getElementsByTagName("properties").item(0); + String jenkinsVersion = propertiesElement + .getElementsByTagName("jenkins.version") + .item(0) + .getTextContent(); + logger.info("Jenkins version found: " + jenkinsVersion); + assertEquals("2.462.2", jenkinsVersion); } } diff --git a/updatecli/scripts/jenkins-lts-baseline.sh b/updatecli/scripts/jenkins-lts-baseline.sh new file mode 100644 index 00000000..bbbed744 --- /dev/null +++ b/updatecli/scripts/jenkins-lts-baseline.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +# This script fetches the Jenkins release data, extracts the LTS version numbers, sorts them, and then outputs a specific version based on a "backward" argument. + +# -e causes the script to exit immediately if any command fails. +# -u treats unset variables as an error and exits the script. +set -eu -o pipefail + +# Get the "backward" argument, default to 0 if not provided. +# This argument specifies which version to get, starting from 0 for the latest version. +backward=${1:-0} + +# Add 1 to backward to start from 1. +backward=$((backward + 1)) + +# Uses the wget command to download the RSS feed of the Jenkins changelog and outputs it to the standard output (-O -). +wget -q -O - https://www.jenkins.io/changelog-stable/rss.xml | \ +# Uses awk to extract the LTS (Long-Term Support) version numbers from the downloaded RSS feed. +# It searches for lines containing Jenkins, splits the third field based on spaces, and prints the second element of the resulting array. +awk -F'[<>]' '/<title>Jenkins /{split($3,a," "); print a[2]}' | \ +# Sorts the version numbers in ascending order. +# It uses the sort command with the delimiter set to dot (-t.) and sorts numerically (-n) based on the first, second, and third fields (-k1,1n -k2,2n -k3,3n). +sort -t. -k1,1n -k2,2n -k3,3n | \ +# Uses awk to get the first version of each unique base version. +# It creates an associative array x with the first and second fields as the key and the whole version number as the value. +# If the key is not already in the array, it stores the version number. +# In the END block, it iterates over the array and prints the values. +awk -F. '{if (!($1"."$2 in x)) x[$1"."$2]=$0} END {for (i in x) print x[i]}' | \ +# Sorts the versions again in ascending order. +sort -t. -k1,1n -k2,2n -k3,3n | \ +# Uses the tail command to get the "backward" version. +# It gets the last n lines, where n is the "backward" argument. +# Then it uses the head command to get the first line of the result, which is the desired version. +tail -n $backward | head -n 1 diff --git a/updatecli/scripts/jenkins-lts.sh b/updatecli/scripts/jenkins-lts.sh new file mode 100644 index 00000000..ae2b2d8f --- /dev/null +++ b/updatecli/scripts/jenkins-lts.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# This script fetches the Jenkins release data, extracts the LTS version numbers, sorts them, and then outputs a specific version based on a "backward" argument. + +# -e causes the script to exit immediately if any command fails. +# -u treats unset variables as an error and exits the script. +set -eu -o pipefail + +# Get the "backward" argument, default to 0 if not provided. +# This argument specifies which version to get, starting from 0 for the latest version. +backward=${1:-0} + +# Subtract 1 from backward to start from 0. +backward=$((backward + 1)) + +# Uses the wget command to download the RSS feed of the Jenkins changelog and outputs it to the standard output (-O -). +wget -q -O - https://www.jenkins.io/changelog-stable/rss.xml | \ +# Uses awk to extract the LTS (Long-Term Support) version numbers from the downloaded RSS feed. +# It searches for lines containing <title>Jenkins, splits the third field based on spaces, and prints the second element of the resulting array. +awk -F'[<>]' '/<title>Jenkins /{split($3,a," "); print a[2]}' | \ +# Sorts the version numbers in ascending order. +# It uses the sort command with the delimiter set to dot (-t.) and sorts numerically (-n) based on the first, second, and third fields (-k1,1n -k2,2n -k3,3n). +sort -t. -k1,1n -k2,2n -k3,3n | \ +# Uses awk to get the last version of each unique base version. +# It creates an associative array x with the first and second fields as the key and the whole version number as the value. +# In the END block, it iterates over the array and prints the values. +awk -F. '{x[$1"."$2]=$0} END {for (i in x) print x[i]}' | \ +# Sorts the versions again in ascending order. +sort -t. -k1,1n -k2,2n -k3,3n | \ +# Uses the tail command to get the "backward" version. +# It gets the last n lines, where n is the "backward" argument. +# Then it uses the head command to get the first line of the result, which is the desired version. +tail -n $backward | head -n 1 diff --git a/updatecli/updatecli.d/jenkins-lts.yaml b/updatecli/updatecli.d/jenkins-lts.yaml new file mode 100644 index 00000000..44ca522e --- /dev/null +++ b/updatecli/updatecli.d/jenkins-lts.yaml @@ -0,0 +1,81 @@ +--- +name: Bump last three Jenkins' LTS versions in the documentation + +scms: + default: + kind: github + spec: + user: "{{ .github.user }}" + email: "{{ .github.email }}" + owner: "{{ .github.owner }}" + repository: "{{ .github.repository }}" + token: "{{ requiredEnv .github.token }}" + username: "{{ .github.username }}" + branch: "{{ .github.branch }}" + +sources: + JenkinsLatestLTS: + name: Get the latest Jenkins LTS version + kind: shell + spec: + command: bash ./updatecli/scripts/jenkins-lts.sh 0 # source input value passed as argument + JenkinsLatestLTSBaseline: + name: Get the latest Jenkins LTS baseline version + kind: shell + spec: + command: bash ./updatecli/scripts/jenkins-lts-baseline.sh 0 # source input value passed as argument + JenkinsPreviousLTS: + name: Get the previous Jenkins LTS version + kind: shell + spec: + command: bash ./updatecli/scripts/jenkins-lts.sh 1 # source input value passed as argument + JenkinsThirdToLastLTS: &jenkinsThirdToLastLTS + name: Get the third to last Jenkins LTS version + kind: shell + spec: &jenkinsThirdToLastLTSSpec + command: bash ./updatecli/scripts/jenkins-lts.sh 2 # source input value passed as argument + JenkinsThirdToLastLTSTruncated: &jenkinsThirdToLastLTSTruncated + name: Get the previous Jenkins LTS version for the BOM root version + kind: shell + spec: &jenkinsThirdToLastLTSTruncatedSpec + command: bash ./updatecli/scripts/jenkins-lts.sh 2 | rev | cut -d. -f2- | rev # Fetches the third-to-last Jenkins LTS version and trims the last segment after the final dot. + +conditions: + # Test that the latest LTS Jenkins version exists + jenkinsLatestLTSVersion: + kind: jenkins + sourceid: JenkinsLatestLTS + # Test that the latest LTS Jenkins baseline version exists + jenkinsLatestLTSBaselineVersion: + kind: jenkins + sourceid: JenkinsLatestLTSBaseline + # Test that the previous LTS Jenkins version exists + jenkinsPreviousLTSVersion: + kind: jenkins + sourceid: JenkinsPreviousLTS + # Test that the third to last LTS Jenkins version exists + jenkinsThirdToLastVersion: + kind: jenkins + sourceid: JenkinsThirdToLastLTS +targets: + setLTSVersionInUpdateMinimumRequiredJenkinsVersion: + kind: file + name: "Bump Jenkins minimum LTS version in the \"improve a plugin tutorial\"" + sourceid: JenkinsPreviousLTS + spec: + file: src/main/resources/versions.properties + matchpattern: >- + (.*jenkins.version = )(.*) + replacepattern: >- + ${1}{{ source "JenkinsPreviousLTS" }} + scmid: default + +actions: + default: + kind: github/pullrequest + scmid: default + title: Update Jenkins LTS versions to {{ source "JenkinsLatestLTS" }} in the `versions.properties` file + spec: + labels: + - dependencies + - chore From a8a11f5b118c205a95475ecd8e1305970a02a0a9 Mon Sep 17 00:00:00 2001 From: gounthar <gounthar@gmail.com> Date: Mon, 30 Sep 2024 18:27:08 +0200 Subject: [PATCH 03/17] fix(pom): Compiles at last. --- .../src/main/resources/versions.properties | 1 + .../src/test/resources/test-pom.xml | 81 +++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 plugin-modernizer-core/src/test/resources/test-pom.xml diff --git a/plugin-modernizer-core/src/main/resources/versions.properties b/plugin-modernizer-core/src/main/resources/versions.properties index ba60e6bf..987dea15 100644 --- a/plugin-modernizer-core/src/main/resources/versions.properties +++ b/plugin-modernizer-core/src/main/resources/versions.properties @@ -1 +1,2 @@ openrewrite.maven.plugin.version = ${openrewrite.maven.plugin.version} +jenkins.version = ${jenkins.version} diff --git a/plugin-modernizer-core/src/test/resources/test-pom.xml b/plugin-modernizer-core/src/test/resources/test-pom.xml new file mode 100644 index 00000000..48f97bf1 --- /dev/null +++ b/plugin-modernizer-core/src/test/resources/test-pom.xml @@ -0,0 +1,81 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.jenkins-ci.plugins</groupId> + <artifactId>plugin</artifactId> + <version>1.554.1</version> + <relativePath /> + </parent> + + <properties> + <!-- Baseline Jenkins version you use to build the plugin. Users must have this version or newer to run. --> + <jenkins.version>1.532.3</jenkins.version> + <!-- Java Level to use. Java 7 required when using core >= 1.612 --> + <java.level>7</java.level> + <!-- Jenkins Test Harness version you use to test the plugin. --> + <!-- For Jenkins version >= 1.580.1 use JTH 2.x or higher. --> + <jenkins-test-harness.version>1.532.3</jenkins-test-harness.version> + <!-- Other properties you may want to use: + ~ hpi-plugin.version: The HPI Maven Plugin version used by the plugin.. + ~ stapler-plugin.version: The Stapler Maven plugin version required by the plugin. + --> + </properties> + <groupId>org.jenkins-ci.plugins</groupId> + <artifactId>vagrant</artifactId> + <version>1.0.3-SNAPSHOT</version> + <packaging>hpi</packaging> + + <name>vagrant</name> + <description>Vagrant plugin to execute and manage vagrant commands on remote nodes</description> + <url>https://wiki.jenkins-ci.org/display/JENKINS/Vagrant-plugin</url> + + <licenses> + <license> + <name>MIT License</name> + <url>http://opensource.org/licenses/MIT</url> + </license> + </licenses> + + <developers> + <developer> + <id>ShimiTaNaka</id> + <name>Elad Shmitanka</name> + <email>elad.shmitanka@gmail.com</email> + </developer> + </developers> + + <!-- get every artifact through repo.jenkins-ci.org, which proxies all the artifacts that we need --> + <repositories> + <repository> + <id>repo.jenkins-ci.org</id> + <url>https://repo.jenkins-ci.org/public/</url> + </repository> + </repositories> + + <pluginRepositories> + <pluginRepository> + <id>repo.jenkins-ci.org</id> + <url>https://repo.jenkins-ci.org/public/</url> + </pluginRepository> + </pluginRepositories> + + <scm> + <connection>scm:git:ssh://github.com/jenkinsci/vagrant-plugin.git</connection> + <developerConnection>scm:git:ssh://git@github.com/jenkinsci/vagrant-plugin.git</developerConnection> + <url>https://github.com/jenkinsci/vagrant-plugin</url> + <tag>vagrant-1.0.3</tag> + </scm> + + <build> + <plugins> + <plugin> + <groupId>org.jenkins-ci.tools</groupId> + <artifactId>maven-hpi-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <compatibleSinceVersion>1.0.0</compatibleSinceVersion> + </configuration> + </plugin> + </plugins> + </build> +</project> From 6b9176e6afc17795f737fe44e5b93b28707486de Mon Sep 17 00:00:00 2001 From: gounthar <gounthar@gmail.com> Date: Mon, 30 Sep 2024 22:09:59 +0200 Subject: [PATCH 04/17] fix(pom): BOM version --- .../core/config/Settings.java | 10 ++- .../core/utils/PomModifier.java | 50 +++++++++++++++ .../src/main/resources/versions.properties | 1 + .../core/utils/PomModifierTest.java | 53 ++++++++++++++- updatecli/updatecli.d/jenkins-bom.yaml | 64 +++++++++++++++++++ updatecli/updatecli.d/jenkins-lts.yaml | 6 +- 6 files changed, 178 insertions(+), 6 deletions(-) create mode 100644 updatecli/updatecli.d/jenkins-bom.yaml diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/config/Settings.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/config/Settings.java index 488d6cad..7b614f9c 100644 --- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/config/Settings.java +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/config/Settings.java @@ -36,6 +36,8 @@ public class Settings { public static final String MAVEN_REWRITE_PLUGIN_VERSION; + public static final String JENKINS_VERSION; + public static final String GITHUB_TOKEN; public static final String GITHUB_OWNER; @@ -72,6 +74,7 @@ private Settings() {} } DEFAULT_MAVEN_HOME = getDefaultMavenHome(); MAVEN_REWRITE_PLUGIN_VERSION = getRewritePluginVersion(); + JENKINS_VERSION = getJenkinsVersion(); GITHUB_TOKEN = getGithubToken(); GITHUB_OWNER = getGithubOwner(); try { @@ -128,6 +131,10 @@ private static Path getDefaultMavenHome() { return readProperty("openrewrite.maven.plugin.version", "versions.properties"); } + private static @Nullable String getJenkinsVersion() { + return readProperty("jenkins.version", "versions.properties"); + } + private static @Nullable URL getUpdateCenterUrl() throws MalformedURLException { String url = System.getenv("JENKINS_UC"); if (url != null) { @@ -180,7 +187,8 @@ public static Path getPluginsDirectory(Plugin plugin) { /** * Read a property from a resource file. - * @param key The key to read + * + * @param key The key to read * @param resource The resource file to read from * @return The value of the property or null if it could not be read */ diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifier.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifier.java index 514b991e..e586f0a1 100644 --- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifier.java +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifier.java @@ -167,6 +167,56 @@ public void updateJenkinsMinimalVersion(String version) { } } + /** + * Adds a BOM section to the POM file. + * + * @param groupId the groupId of the BOM + * @param artifactId the artifactId of the BOM + * @param version the version of the BOM + */ + public void addBom(String groupId, String artifactId, String version) { + NodeList dependencyManagementList = document.getElementsByTagName("dependencyManagement"); + Element dependencyManagementElement; + + if (dependencyManagementList.getLength() > 0) { + dependencyManagementElement = (Element) dependencyManagementList.item(0); + } else { + dependencyManagementElement = document.createElement("dependencyManagement"); + document.getDocumentElement().appendChild(dependencyManagementElement); + } + + Element dependenciesElement = (Element) + dependencyManagementElement.getElementsByTagName("dependencies").item(0); + if (dependenciesElement == null) { + dependenciesElement = document.createElement("dependencies"); + dependencyManagementElement.appendChild(dependenciesElement); + } + + Element dependencyElement = document.createElement("dependency"); + + Element groupIdElement = document.createElement("groupId"); + groupIdElement.appendChild(document.createTextNode(groupId)); + dependencyElement.appendChild(groupIdElement); + + Element artifactIdElement = document.createElement("artifactId"); + artifactIdElement.appendChild(document.createTextNode(artifactId)); + dependencyElement.appendChild(artifactIdElement); + + Element versionElement = document.createElement("version"); + versionElement.appendChild(document.createTextNode(version)); + dependencyElement.appendChild(versionElement); + + Element typeElement = document.createElement("type"); + typeElement.appendChild(document.createTextNode("pom")); + dependencyElement.appendChild(typeElement); + + Element scopeElement = document.createElement("scope"); + scopeElement.appendChild(document.createTextNode("import")); + dependencyElement.appendChild(scopeElement); + + dependenciesElement.appendChild(dependencyElement); + } + /** * Saves the modified POM file to the specified output path. * diff --git a/plugin-modernizer-core/src/main/resources/versions.properties b/plugin-modernizer-core/src/main/resources/versions.properties index 987dea15..eca14506 100644 --- a/plugin-modernizer-core/src/main/resources/versions.properties +++ b/plugin-modernizer-core/src/main/resources/versions.properties @@ -1,2 +1,3 @@ openrewrite.maven.plugin.version = ${openrewrite.maven.plugin.version} jenkins.version = ${jenkins.version} +bom.version = ${bom.version} diff --git a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifierTest.java b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifierTest.java index c348a26a..6bb95d47 100644 --- a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifierTest.java +++ b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifierTest.java @@ -4,6 +4,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +import io.jenkins.tools.pluginmodernizer.core.config.Settings; import java.io.File; import java.io.IOException; import java.nio.file.Files; @@ -17,6 +18,7 @@ import org.junit.jupiter.api.Test; import org.w3c.dom.Document; import org.w3c.dom.Element; +import org.w3c.dom.NodeList; public class PomModifierTest { private static final Logger logger = Logger.getLogger(PomModifierTest.class.getName()); @@ -90,7 +92,7 @@ public void testUpdateParentPom() throws Exception { @Test public void testUpdateJenkinsMinimalVersion() throws Exception { PomModifier pomModifier = new PomModifier(OUTPUT_POM_PATH); - pomModifier.updateJenkinsMinimalVersion("2.462.2"); + pomModifier.updateJenkinsMinimalVersion(Settings.JENKINS_VERSION); pomModifier.savePom(OUTPUT_POM_PATH); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); @@ -105,6 +107,53 @@ public void testUpdateJenkinsMinimalVersion() throws Exception { .item(0) .getTextContent(); logger.info("Jenkins version found: " + jenkinsVersion); - assertEquals("2.462.2", jenkinsVersion); + assertEquals(Settings.JENKINS_VERSION, jenkinsVersion); + } + + @Test + public void testAddBom() throws Exception { + PomModifier pomModifier = new PomModifier(OUTPUT_POM_PATH); + pomModifier.addBom("io.jenkins.tools.bom", "bom-2.440.x", "3413.v0d896b_76a_30d"); + pomModifier.savePom(OUTPUT_POM_PATH); + + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + Document doc = dBuilder.parse(new File(OUTPUT_POM_PATH)); + doc.getDocumentElement().normalize(); + + NodeList dependencyManagementList = doc.getElementsByTagName("dependencyManagement"); + assertTrue(dependencyManagementList.getLength() > 0); + + Element dependencyManagementElement = (Element) dependencyManagementList.item(0); + NodeList dependenciesList = dependencyManagementElement.getElementsByTagName("dependencies"); + assertTrue(dependenciesList.getLength() > 0); + + Element dependenciesElement = (Element) dependenciesList.item(0); + NodeList dependencyList = dependenciesElement.getElementsByTagName("dependency"); + boolean bomFound = false; + + for (int i = 0; i < dependencyList.getLength(); i++) { + Element dependencyElement = (Element) dependencyList.item(i); + String groupId = + dependencyElement.getElementsByTagName("groupId").item(0).getTextContent(); + String artifactId = + dependencyElement.getElementsByTagName("artifactId").item(0).getTextContent(); + String version = + dependencyElement.getElementsByTagName("version").item(0).getTextContent(); + String scope = + dependencyElement.getElementsByTagName("scope").item(0).getTextContent(); + String type = dependencyElement.getElementsByTagName("type").item(0).getTextContent(); + + if (groupId.equals("io.jenkins.tools.bom") + && artifactId.equals("bom-2.440.x") + && version.equals("3413.v0d896b_76a_30d") + && scope.equals("import") + && type.equals("pom")) { + bomFound = true; + break; + } + } + + assertTrue(bomFound, "BOM dependency not found in the POM file"); } } diff --git a/updatecli/updatecli.d/jenkins-bom.yaml b/updatecli/updatecli.d/jenkins-bom.yaml new file mode 100644 index 00000000..f9676a9d --- /dev/null +++ b/updatecli/updatecli.d/jenkins-bom.yaml @@ -0,0 +1,64 @@ +--- +name: Bump Jenkins' recommended BOM versions in the versions.properties file + +scms: + default: + kind: github + spec: + user: "{{ .github.user }}" + email: "{{ .github.email }}" + owner: "{{ .github.owner }}" + repository: "{{ .github.repository }}" + token: "{{ requiredEnv .github.token }}" + username: "{{ .github.username }}" + branch: "{{ .github.branch }}" + +sources: + JenkinsThirdToLastLTS: &jenkinsThirdToLastLTS + name: Get the third to last Jenkins LTS version + kind: shell + spec: &jenkinsThirdToLastLTSSpec + command: bash ./updatecli/scripts/jenkins-lts.sh 2 # source input value passed as argument + JenkinsThirdToLastLTSTruncated: &jenkinsThirdToLastLTSTruncated + name: Get the previous Jenkins LTS version for the BOM root version + kind: shell + spec: &jenkinsThirdToLastLTSTruncatedSpec + command: bash ./updatecli/scripts/jenkins-lts.sh 2 | rev | cut -d. -f2- | rev # Fetches the third-to-last Jenkins LTS version and trims the last segment after the final dot. + BOM: + name: Get the latest Jenkins BOM version + kind: maven + source: JenkinsThirdToLastLTSTruncated + dependson: + - JenkinsThirdToLastLTSTruncated + spec: + repository: "https://repo.jenkins-ci.org/releases" + groupid: "io.jenkins.tools.bom" + artifactid: bom-{{ source "JenkinsThirdToLastLTSTruncated" }}.x + +conditions: + # Test that the third to last LTS Jenkins version exists + jenkinsThirdToLastVersion: + kind: jenkins + sourceid: JenkinsThirdToLastLTS + +targets: + setBOMVersionInUpdateMinimumRequiredJenkinsVersion: + kind: file + name: "Bump Jenkins minimum BOM artifact version in the \"improve a plugin tutorial\"" + sourceid: BOM + spec: + file: plugin-modernizer-core/src/main/resources/versions.properties + matchpattern: >- + (bom.version = )(.*) + replacepattern: >- + ${1}{{ source "BOM" }} + scmid: default + +actions: + default: + kind: github/pullrequest + scmid: default + title: Update the plugin bill of materials versions to {{ source "BOM" }} in the versions.properties file + spec: + labels: + - dependencies diff --git a/updatecli/updatecli.d/jenkins-lts.yaml b/updatecli/updatecli.d/jenkins-lts.yaml index 44ca522e..0f8ae849 100644 --- a/updatecli/updatecli.d/jenkins-lts.yaml +++ b/updatecli/updatecli.d/jenkins-lts.yaml @@ -1,5 +1,5 @@ --- -name: Bump last three Jenkins' LTS versions in the documentation +name: Bump Jenkins' LTS versions in the versions.properties file scms: default: @@ -63,9 +63,9 @@ targets: name: "Bump Jenkins minimum LTS version in the \"improve a plugin tutorial\"" sourceid: JenkinsPreviousLTS spec: - file: src/main/resources/versions.properties + file: plugin-modernizer-core/src/main/resources/versions.properties matchpattern: >- - (.*jenkins.version = )(.*) + (jenkins.version = )(.*) replacepattern: >- ${1}{{ source "JenkinsPreviousLTS" }} scmid: default From da047fce1f2215eb932f23cc12c18c5e0ef31f8d Mon Sep 17 00:00:00 2001 From: gounthar <gounthar@gmail.com> Date: Mon, 30 Sep 2024 22:16:24 +0200 Subject: [PATCH 05/17] fix(pom): BOM base --- .../src/main/resources/versions.properties | 1 + updatecli/updatecli.d/jenkins-bom.yaml | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/plugin-modernizer-core/src/main/resources/versions.properties b/plugin-modernizer-core/src/main/resources/versions.properties index eca14506..b2988d5d 100644 --- a/plugin-modernizer-core/src/main/resources/versions.properties +++ b/plugin-modernizer-core/src/main/resources/versions.properties @@ -1,3 +1,4 @@ openrewrite.maven.plugin.version = ${openrewrite.maven.plugin.version} jenkins.version = ${jenkins.version} bom.version = ${bom.version} +bom.base = ${bom.base} diff --git a/updatecli/updatecli.d/jenkins-bom.yaml b/updatecli/updatecli.d/jenkins-bom.yaml index f9676a9d..fe874574 100644 --- a/updatecli/updatecli.d/jenkins-bom.yaml +++ b/updatecli/updatecli.d/jenkins-bom.yaml @@ -42,9 +42,20 @@ conditions: sourceid: JenkinsThirdToLastLTS targets: + setBOMBaseVersionInUpdateMinimumRequiredJenkinsVersion: + kind: file + name: "Bump Jenkins minimum BOM artifact" + sourceid: BOM + spec: + file: plugin-modernizer-core/src/main/resources/versions.properties + matchpattern: >- + (bom.base = )(.*) + replacepattern: >- + ${1}bom-{{ source "JenkinsThirdToLastLTSTruncated" }}.x + scmid: default setBOMVersionInUpdateMinimumRequiredJenkinsVersion: kind: file - name: "Bump Jenkins minimum BOM artifact version in the \"improve a plugin tutorial\"" + name: "Bump Jenkins minimum BOM artifact" sourceid: BOM spec: file: plugin-modernizer-core/src/main/resources/versions.properties From 3e241edd5dc7cf3a7576a7128f209db9c15e20de Mon Sep 17 00:00:00 2001 From: gounthar <gounthar@gmail.com> Date: Mon, 30 Sep 2024 22:24:06 +0200 Subject: [PATCH 06/17] fix(pom): BOM base --- .../core/config/Settings.java | 19 ++++++++++- .../core/utils/PomModifierTest.java | 33 ++++++++++--------- 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/config/Settings.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/config/Settings.java index 7b614f9c..ca9daa8a 100644 --- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/config/Settings.java +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/config/Settings.java @@ -4,6 +4,7 @@ import edu.umd.cs.findbugs.annotations.Nullable; import io.jenkins.tools.pluginmodernizer.core.model.ModernizerException; import io.jenkins.tools.pluginmodernizer.core.model.Plugin; + import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; @@ -13,6 +14,7 @@ import java.nio.file.Paths; import java.util.List; import java.util.Properties; + import org.apache.maven.artifact.versioning.ComparableVersion; import org.openrewrite.Recipe; import org.openrewrite.config.YamlResourceLoader; @@ -38,6 +40,10 @@ public class Settings { public static final String JENKINS_VERSION; + public static final String BOM_BASE; + + public static final String BOM_VERSION; + public static final String GITHUB_TOKEN; public static final String GITHUB_OWNER; @@ -58,7 +64,8 @@ public class Settings { public static final Recipe MINIMAL_BUILD_JAVA_8_RECIPE; - private Settings() {} + private Settings() { + } static { String cacheBaseDir = System.getProperty("user.home"); @@ -75,6 +82,8 @@ private Settings() {} DEFAULT_MAVEN_HOME = getDefaultMavenHome(); MAVEN_REWRITE_PLUGIN_VERSION = getRewritePluginVersion(); JENKINS_VERSION = getJenkinsVersion(); + BOM_BASE = getBomBase(); + BOM_VERSION = getBomVersion(); GITHUB_TOKEN = getGithubToken(); GITHUB_OWNER = getGithubOwner(); try { @@ -135,6 +144,14 @@ private static Path getDefaultMavenHome() { return readProperty("jenkins.version", "versions.properties"); } + private static @Nullable String getBomBase() { + return readProperty("bom.base", "versions.properties"); + } + + private static @Nullable String getBomVersion() { + return readProperty("bom.version", "versions.properties"); + } + private static @Nullable URL getUpdateCenterUrl() throws MalformedURLException { String url = System.getenv("JENKINS_UC"); if (url != null) { diff --git a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifierTest.java b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifierTest.java index 6bb95d47..93d36204 100644 --- a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifierTest.java +++ b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifierTest.java @@ -1,10 +1,14 @@ package io.jenkins.tools.pluginmodernizer.core.utils; -import static java.nio.file.Files.createTempFile; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - import io.jenkins.tools.pluginmodernizer.core.config.Settings; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; import java.io.File; import java.io.IOException; import java.nio.file.Files; @@ -12,13 +16,10 @@ import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.logging.Logger; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; + +import static java.nio.file.Files.createTempFile; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; public class PomModifierTest { private static final Logger logger = Logger.getLogger(PomModifierTest.class.getName()); @@ -61,8 +62,8 @@ public void testRemoveOffendingProperties() throws Exception { (Element) doc.getElementsByTagName("properties").item(0); assertTrue(propertiesElement.getElementsByTagName("java.level").getLength() == 0); assertTrue(propertiesElement - .getElementsByTagName("jenkins-test-harness.version") - .getLength() + .getElementsByTagName("jenkins-test-harness.version") + .getLength() == 0); logger.info("Offending properties removed successfully"); } @@ -113,7 +114,7 @@ public void testUpdateJenkinsMinimalVersion() throws Exception { @Test public void testAddBom() throws Exception { PomModifier pomModifier = new PomModifier(OUTPUT_POM_PATH); - pomModifier.addBom("io.jenkins.tools.bom", "bom-2.440.x", "3413.v0d896b_76a_30d"); + pomModifier.addBom("io.jenkins.tools.bom", Settings.BOM_BASE, Settings.BOM_VERSION); pomModifier.savePom(OUTPUT_POM_PATH); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); @@ -145,8 +146,8 @@ public void testAddBom() throws Exception { String type = dependencyElement.getElementsByTagName("type").item(0).getTextContent(); if (groupId.equals("io.jenkins.tools.bom") - && artifactId.equals("bom-2.440.x") - && version.equals("3413.v0d896b_76a_30d") + && artifactId.equals(Settings.BOM_BASE) + && version.equals(Settings.BOM_VERSION) && scope.equals("import") && type.equals("pom")) { bomFound = true; From 45348ad165c212340b778965b9857f03e13723ad Mon Sep 17 00:00:00 2001 From: gounthar <gounthar@gmail.com> Date: Mon, 30 Sep 2024 22:26:09 +0200 Subject: [PATCH 07/17] fix(pom): mvn spotless:apply --- .../core/config/Settings.java | 7 ++--- .../core/utils/PomModifierTest.java | 27 +++++++++---------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/config/Settings.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/config/Settings.java index ca9daa8a..d74c8fb0 100644 --- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/config/Settings.java +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/config/Settings.java @@ -4,7 +4,6 @@ import edu.umd.cs.findbugs.annotations.Nullable; import io.jenkins.tools.pluginmodernizer.core.model.ModernizerException; import io.jenkins.tools.pluginmodernizer.core.model.Plugin; - import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; @@ -14,7 +13,6 @@ import java.nio.file.Paths; import java.util.List; import java.util.Properties; - import org.apache.maven.artifact.versioning.ComparableVersion; import org.openrewrite.Recipe; import org.openrewrite.config.YamlResourceLoader; @@ -64,8 +62,7 @@ public class Settings { public static final Recipe MINIMAL_BUILD_JAVA_8_RECIPE; - private Settings() { - } + private Settings() {} static { String cacheBaseDir = System.getProperty("user.home"); @@ -148,7 +145,7 @@ private static Path getDefaultMavenHome() { return readProperty("bom.base", "versions.properties"); } - private static @Nullable String getBomVersion() { + private static @Nullable String getBomVersion() { return readProperty("bom.version", "versions.properties"); } diff --git a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifierTest.java b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifierTest.java index 93d36204..582ee9d0 100644 --- a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifierTest.java +++ b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifierTest.java @@ -1,14 +1,10 @@ package io.jenkins.tools.pluginmodernizer.core.utils; -import io.jenkins.tools.pluginmodernizer.core.config.Settings; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; +import static java.nio.file.Files.createTempFile; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; +import io.jenkins.tools.pluginmodernizer.core.config.Settings; import java.io.File; import java.io.IOException; import java.nio.file.Files; @@ -16,10 +12,13 @@ import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.logging.Logger; - -import static java.nio.file.Files.createTempFile; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; public class PomModifierTest { private static final Logger logger = Logger.getLogger(PomModifierTest.class.getName()); @@ -62,8 +61,8 @@ public void testRemoveOffendingProperties() throws Exception { (Element) doc.getElementsByTagName("properties").item(0); assertTrue(propertiesElement.getElementsByTagName("java.level").getLength() == 0); assertTrue(propertiesElement - .getElementsByTagName("jenkins-test-harness.version") - .getLength() + .getElementsByTagName("jenkins-test-harness.version") + .getLength() == 0); logger.info("Offending properties removed successfully"); } From 97f626ac268ac2b105ff8770b73a2ec7a7d3dfd9 Mon Sep 17 00:00:00 2001 From: gounthar <gounthar@gmail.com> Date: Tue, 1 Oct 2024 09:18:10 +0200 Subject: [PATCH 08/17] fix(java): Javadoc --- .../core/utils/PomModifierTest.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifierTest.java b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifierTest.java index 582ee9d0..a247f576 100644 --- a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifierTest.java +++ b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifierTest.java @@ -20,6 +20,9 @@ import org.w3c.dom.Element; import org.w3c.dom.NodeList; +/** + * Test class for PomModifier. + */ public class PomModifierTest { private static final Logger logger = Logger.getLogger(PomModifierTest.class.getName()); @@ -39,6 +42,11 @@ public class PomModifierTest { } } + /** + * Sets up the test environment by copying the test POM to a temporary file. + * + * @throws Exception if an error occurs during setup + */ @BeforeEach public void setUp() throws Exception { Path tempFile = new File(OUTPUT_POM_PATH).toPath(); @@ -46,6 +54,11 @@ public void setUp() throws Exception { logger.info("Setup completed, copied test POM to temporary file: " + tempFile.toString()); } + /** + * Tests the removeOffendingProperties method of PomModifier. + * + * @throws Exception if an error occurs during the test + */ @Test public void testRemoveOffendingProperties() throws Exception { PomModifier pomModifier = new PomModifier(OUTPUT_POM_PATH); @@ -67,6 +80,11 @@ public void testRemoveOffendingProperties() throws Exception { logger.info("Offending properties removed successfully"); } + /** + * Tests the updateParentPom method of PomModifier. + * + * @throws Exception if an error occurs during the test + */ @Test public void testUpdateParentPom() throws Exception { PomModifier pomModifier = new PomModifier(OUTPUT_POM_PATH); @@ -89,6 +107,11 @@ public void testUpdateParentPom() throws Exception { "4.80", parentElement.getElementsByTagName("version").item(0).getTextContent()); } + /** + * Tests the updateJenkinsMinimalVersion method of PomModifier. + * + * @throws Exception if an error occurs during the test + */ @Test public void testUpdateJenkinsMinimalVersion() throws Exception { PomModifier pomModifier = new PomModifier(OUTPUT_POM_PATH); @@ -110,6 +133,11 @@ public void testUpdateJenkinsMinimalVersion() throws Exception { assertEquals(Settings.JENKINS_VERSION, jenkinsVersion); } + /** + * Tests the addBom method of PomModifier. + * + * @throws Exception if an error occurs during the test + */ @Test public void testAddBom() throws Exception { PomModifier pomModifier = new PomModifier(OUTPUT_POM_PATH); From 86bc30640265807ae472117b53c4c838f7c7cdb7 Mon Sep 17 00:00:00 2001 From: Bruno Verachten <gounthar@gmail.com> Date: Tue, 1 Oct 2024 09:49:20 +0200 Subject: [PATCH 09/17] Add command line option to ignore JDK7 error Fixes #26 Add a new command line option `--ignore-jdk7-error` to allow plugins using JDK7 or older. * **Main.java** - Add `--ignore-jdk7-error` option. - Update `setup` method to include the new option in the `Config` object. * **Config.java** - Add `ignoreJdk7Error` field. - Update `Builder` class to include `withIgnoreJdk7Error` method. - Update `build` method to set `ignoreJdk7Error` field. * **PluginModernizer.java** - Update `process` method to check for `ignoreJdk7Error` option. - Use `PomModifier` to modify `pom.xml` if `ignoreJdk7Error` is set. --- For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/gounthar/plugin-modernizer-tool/issues/26?shareId=XXXX-XXXX-XXXX-XXXX). --- .../tools/pluginmodernizer/cli/Main.java | 6 ++++++ .../pluginmodernizer/core/config/Config.java | 18 ++++++++++++++++-- .../core/impl/PluginModernizer.java | 10 ++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/plugin-modernizer-cli/src/main/java/io/jenkins/tools/pluginmodernizer/cli/Main.java b/plugin-modernizer-cli/src/main/java/io/jenkins/tools/pluginmodernizer/cli/Main.java index e48fb4cf..deef346b 100644 --- a/plugin-modernizer-cli/src/main/java/io/jenkins/tools/pluginmodernizer/cli/Main.java +++ b/plugin-modernizer-cli/src/main/java/io/jenkins/tools/pluginmodernizer/cli/Main.java @@ -148,6 +148,11 @@ static class PluginOptions { description = "List available recipes.") public boolean listRecipes; + @Option( + names = {"--ignore-jdk7-error"}, + description = "Ignore errors for plugins using JDK7 or older and launch PomModifier on the faulty pom.xml.") + public boolean ignoreJdk7Error; + public Config setup() { Config.DEBUG = debug; return Config.builder() @@ -169,6 +174,7 @@ public Config setup() { ? cachePath.resolve(Settings.CACHE_SUBDIR) : cachePath) .withMavenHome(mavenHome) + .withIgnoreJdk7Error(ignoreJdk7Error) .build(); } diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/config/Config.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/config/Config.java index 09ad1e90..c1a998b2 100644 --- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/config/Config.java +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/config/Config.java @@ -27,6 +27,7 @@ public class Config { private final boolean removeForks; private final boolean exportDatatables; private final String githubOwner; + private final boolean ignoreJdk7Error; private Config( String version, @@ -43,7 +44,8 @@ private Config( boolean skipPullRequest, boolean removeLocalData, boolean removeForks, - boolean exportDatatables) { + boolean exportDatatables, + boolean ignoreJdk7Error) { this.version = version; this.githubOwner = githubOwner; this.plugins = plugins; @@ -59,6 +61,7 @@ private Config( this.removeLocalData = removeLocalData; this.removeForks = removeForks; this.exportDatatables = exportDatatables; + this.ignoreJdk7Error = ignoreJdk7Error; } public String getVersion() { @@ -133,6 +136,10 @@ public boolean isExportDatatables() { return exportDatatables; } + public boolean isIgnoreJdk7Error() { + return ignoreJdk7Error; + } + public static Builder builder() { return new Builder(); } @@ -153,6 +160,7 @@ public static class Builder { private boolean exportDatatables = false; public boolean removeLocalData = false; public boolean removeForks = false; + private boolean ignoreJdk7Error = false; public Builder withVersion(String version) { this.version = version; @@ -239,6 +247,11 @@ public Builder withExportDatatables(boolean exportDatatables) { return this; } + public Builder withIgnoreJdk7Error(boolean ignoreJdk7Error) { + this.ignoreJdk7Error = ignoreJdk7Error; + return this; + } + public Config build() { return new Config( version, @@ -255,7 +268,8 @@ public Config build() { skipPullRequest, removeLocalData, removeForks, - exportDatatables); + exportDatatables, + ignoreJdk7Error); } } } diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/impl/PluginModernizer.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/impl/PluginModernizer.java index 6848fbc6..39b87b5e 100644 --- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/impl/PluginModernizer.java +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/impl/PluginModernizer.java @@ -11,6 +11,7 @@ import io.jenkins.tools.pluginmodernizer.core.utils.HealthScoreUtils; import io.jenkins.tools.pluginmodernizer.core.utils.JdkFetcher; import io.jenkins.tools.pluginmodernizer.core.utils.PluginVersionUtils; +import io.jenkins.tools.pluginmodernizer.core.utils.PomModifier; import io.jenkins.tools.pluginmodernizer.core.utils.UpdateCenterUtils; import java.util.List; import java.util.stream.Collectors; @@ -161,6 +162,15 @@ private void process(Plugin plugin) { return; } + // Check for ignoreJdk7Error option and use PomModifier if set + if (config.isIgnoreJdk7Error() && plugin.hasPreconditionErrors()) { + LOG.info("Ignoring JDK7 error for plugin {} and modifying pom.xml", plugin.getName()); + PomModifier pomModifier = new PomModifier(plugin.getLocalRepository().resolve("pom.xml").toString()); + pomModifier.removeOffendingProperties(); + pomModifier.savePom(plugin.getLocalRepository().resolve("pom.xml").toString()); + plugin.withoutErrors(); + } + // Run OpenRewrite plugin.runOpenRewrite(mavenInvoker); if (plugin.hasErrors()) { From 2bd525d95669c3de6eb81681762d94a353ac558d Mon Sep 17 00:00:00 2001 From: gounthar <gounthar@gmail.com> Date: Tue, 1 Oct 2024 11:52:10 +0200 Subject: [PATCH 10/17] fix(java): Can deal with the Vagrant plugin. --- .../core/config/Settings.java | 7 ++++ .../core/impl/PluginModernizer.java | 33 +++++++++++++------ .../resources/META-INF/rewrite/recipes.yml | 1 + .../src/main/resources/versions.properties | 7 ++-- .../core/config/ConfigTest.java | 3 ++ 5 files changed, 38 insertions(+), 13 deletions(-) diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/config/Settings.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/config/Settings.java index d74c8fb0..29d95b92 100644 --- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/config/Settings.java +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/config/Settings.java @@ -38,6 +38,8 @@ public class Settings { public static final String JENKINS_VERSION; + public static final String PLUGIN_PARENT_VERSION; + public static final String BOM_BASE; public static final String BOM_VERSION; @@ -81,6 +83,7 @@ private Settings() {} JENKINS_VERSION = getJenkinsVersion(); BOM_BASE = getBomBase(); BOM_VERSION = getBomVersion(); + PLUGIN_PARENT_VERSION = getPluginParentVersion(); GITHUB_TOKEN = getGithubToken(); GITHUB_OWNER = getGithubOwner(); try { @@ -141,6 +144,10 @@ private static Path getDefaultMavenHome() { return readProperty("jenkins.version", "versions.properties"); } + private static @Nullable String getPluginParentVersion() { + return readProperty("jenkins.plugin.parent.version", "versions.properties"); + } + private static @Nullable String getBomBase() { return readProperty("bom.base", "versions.properties"); } diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/impl/PluginModernizer.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/impl/PluginModernizer.java index 39b87b5e..072a7859 100644 --- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/impl/PluginModernizer.java +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/impl/PluginModernizer.java @@ -36,6 +36,7 @@ public class PluginModernizer { /** * Create a new PluginModernizer + * * @param config The configuration to use */ public PluginModernizer(Config config) { @@ -82,6 +83,7 @@ public void start() { /** * Process a plugin + * * @param plugin The plugin to process */ private void process(Plugin plugin) { @@ -135,7 +137,7 @@ private void process(Plugin plugin) { LOG.debug("Plugin {} compiled successfully with JDK {}", plugin.getName(), jdk.getMajor()); } else { LOG.debug( - "No metadata or precondition errors found for plugin {}. Skipping initial compilation.", + "There are no metadata or we found precondition errors for plugin {}. Skipping initial compilation.", plugin.getName()); } } @@ -153,6 +155,23 @@ private void process(Plugin plugin) { LOG.debug("Metadata already computed for plugin {}. Using cached metadata.", plugin.getName()); } + // Check for ignoreJdk7Error option and use PomModifier if set + if (config.isIgnoreJdk7Error() && plugin.hasPreconditionErrors()) { + LOG.info("Ignoring JDK7 error for plugin {} and modifying pom.xml", plugin.getName()); + PomModifier pomModifier = new PomModifier( + plugin.getLocalRepository().resolve("pom.xml").toString()); + pomModifier.removeOffendingProperties(); + pomModifier.addBom("io.jenkins.tools.bom", Settings.BOM_BASE, Settings.BOM_VERSION); + pomModifier.updateParentPom("org.jenkins-ci.plugins", "plugin", Settings.PLUGIN_PARENT_VERSION); + pomModifier.updateJenkinsMinimalVersion(Settings.JENKINS_VERSION); + + pomModifier.savePom( + plugin.getLocalRepository().resolve("pom.xml").toString()); + plugin.withoutErrors(); + // Retry the metadata fetching + plugin.collectMetadata(mavenInvoker); + plugin.moveMetadata(cacheManager); + } else // Abort here if we have errors if (plugin.hasErrors() || plugin.hasPreconditionErrors()) { plugin.addPreconditionErrors(plugin.getMetadata()); @@ -162,15 +181,6 @@ private void process(Plugin plugin) { return; } - // Check for ignoreJdk7Error option and use PomModifier if set - if (config.isIgnoreJdk7Error() && plugin.hasPreconditionErrors()) { - LOG.info("Ignoring JDK7 error for plugin {} and modifying pom.xml", plugin.getName()); - PomModifier pomModifier = new PomModifier(plugin.getLocalRepository().resolve("pom.xml").toString()); - pomModifier.removeOffendingProperties(); - pomModifier.savePom(plugin.getLocalRepository().resolve("pom.xml").toString()); - plugin.withoutErrors(); - } - // Run OpenRewrite plugin.runOpenRewrite(mavenInvoker); if (plugin.hasErrors()) { @@ -226,6 +236,7 @@ private void process(Plugin plugin) { /** * Compile a plugin + * * @param plugin The plugin to compile */ private JDK compilePlugin(Plugin plugin) { @@ -239,6 +250,7 @@ private JDK compilePlugin(Plugin plugin) { /** * Verify a plugin and return the first JDK that successfully verifies it, starting from the target JDK and moving backward + * * @param plugin The plugin to verify * @return The JDK that verifies the plugin */ @@ -277,6 +289,7 @@ private JDK verifyPlugin(Plugin plugin) { /** * Collect results from the plugins and display a summary + * * @param plugins The plugins */ private void printResults(List<Plugin> plugins) { diff --git a/plugin-modernizer-core/src/main/resources/META-INF/rewrite/recipes.yml b/plugin-modernizer-core/src/main/resources/META-INF/rewrite/recipes.yml index 259ca418..52980e33 100644 --- a/plugin-modernizer-core/src/main/resources/META-INF/rewrite/recipes.yml +++ b/plugin-modernizer-core/src/main/resources/META-INF/rewrite/recipes.yml @@ -16,6 +16,7 @@ tags: ['java8'] recipeList: - org.openrewrite.maven.security.UseHttpsForRepositories - org.openrewrite.jenkins.DisableLocalResolutionForParentPom + - org.openrewrite.java.cleanup.RemoveRedundantNullChecks --- type: specs.openrewrite.org/v1beta/recipe name: io.jenkins.tools.pluginmodernizer.AddPluginsBom diff --git a/plugin-modernizer-core/src/main/resources/versions.properties b/plugin-modernizer-core/src/main/resources/versions.properties index b2988d5d..b7f1cb62 100644 --- a/plugin-modernizer-core/src/main/resources/versions.properties +++ b/plugin-modernizer-core/src/main/resources/versions.properties @@ -1,4 +1,5 @@ openrewrite.maven.plugin.version = ${openrewrite.maven.plugin.version} -jenkins.version = ${jenkins.version} -bom.version = ${bom.version} -bom.base = ${bom.base} +jenkins.version = 2.440.2 +jenkins.plugin.parent.version = 4.80 +bom.version = 3413.v0d896b_76a_30d +bom.base = bom-2.440.x diff --git a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/config/ConfigTest.java b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/config/ConfigTest.java index 7eb29454..abd6e4c1 100644 --- a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/config/ConfigTest.java +++ b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/config/ConfigTest.java @@ -47,6 +47,7 @@ public void testConfigBuilderWithAllFields() throws MalformedURLException { .withExportDatatables(true) .withRemoveForks(true) .withRemoveLocalData(true) + .withIgnoreJdk7Error(true) .build(); assertEquals(version, config.getVersion()); @@ -63,6 +64,7 @@ public void testConfigBuilderWithAllFields() throws MalformedURLException { assertTrue(config.isRemoveLocalData()); assertTrue(config.isExportDatatables()); assertTrue(config.isDryRun()); + assertTrue(config.isIgnoreJdk7Error()); } @Test @@ -82,6 +84,7 @@ public void testConfigBuilderWithDefaultValues() { assertFalse(config.isRemoveLocalData()); assertFalse(config.isExportDatatables()); assertFalse(config.isDryRun()); + assertFalse(config.isIgnoreJdk7Error()); } @Test From 4316c0cd3ebc335ac89cf25b8932632c502abce5 Mon Sep 17 00:00:00 2001 From: Bruno Verachten <gounthar@gmail.com> Date: Wed, 2 Oct 2024 17:15:14 +0200 Subject: [PATCH 11/17] fix(java): Changed the jenkins.version name and value after Valentin's review. --- plugin-modernizer-core/src/main/resources/versions.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin-modernizer-core/src/main/resources/versions.properties b/plugin-modernizer-core/src/main/resources/versions.properties index b7f1cb62..fa47852b 100644 --- a/plugin-modernizer-core/src/main/resources/versions.properties +++ b/plugin-modernizer-core/src/main/resources/versions.properties @@ -1,5 +1,5 @@ openrewrite.maven.plugin.version = ${openrewrite.maven.plugin.version} -jenkins.version = 2.440.2 +jenkins.minimum.version = 2.440.3 jenkins.plugin.parent.version = 4.80 bom.version = 3413.v0d896b_76a_30d bom.base = bom-2.440.x From c7e506742f2fd82f59d7f40a0c1faae942cb202f Mon Sep 17 00:00:00 2001 From: gounthar <gounthar@gmail.com> Date: Wed, 2 Oct 2024 17:35:41 +0200 Subject: [PATCH 12/17] fix(updatecli): Changed the key to update. --- updatecli/updatecli.d/jenkins-lts.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/updatecli/updatecli.d/jenkins-lts.yaml b/updatecli/updatecli.d/jenkins-lts.yaml index 0f8ae849..75243e0c 100644 --- a/updatecli/updatecli.d/jenkins-lts.yaml +++ b/updatecli/updatecli.d/jenkins-lts.yaml @@ -60,12 +60,12 @@ conditions: targets: setLTSVersionInUpdateMinimumRequiredJenkinsVersion: kind: file - name: "Bump Jenkins minimum LTS version in the \"improve a plugin tutorial\"" + name: "Bump Jenkins minimum LTS version in the `versions.properties` file" sourceid: JenkinsPreviousLTS spec: file: plugin-modernizer-core/src/main/resources/versions.properties matchpattern: >- - (jenkins.version = )(.*) + (jenkins.minimum.version = )(.*) replacepattern: >- ${1}{{ source "JenkinsPreviousLTS" }} scmid: default From e3e15e1ebb81ac91dc6b719bd5d18c829251ee13 Mon Sep 17 00:00:00 2001 From: gounthar <gounthar@gmail.com> Date: Wed, 2 Oct 2024 17:36:07 +0200 Subject: [PATCH 13/17] fix(java): Changed the constant name. --- .../tools/pluginmodernizer/core/config/Settings.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/config/Settings.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/config/Settings.java index 29d95b92..8b3ab489 100644 --- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/config/Settings.java +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/config/Settings.java @@ -36,7 +36,7 @@ public class Settings { public static final String MAVEN_REWRITE_PLUGIN_VERSION; - public static final String JENKINS_VERSION; + public static final String JENKINS_MINIMUM_VERSION; public static final String PLUGIN_PARENT_VERSION; @@ -80,7 +80,7 @@ private Settings() {} } DEFAULT_MAVEN_HOME = getDefaultMavenHome(); MAVEN_REWRITE_PLUGIN_VERSION = getRewritePluginVersion(); - JENKINS_VERSION = getJenkinsVersion(); + JENKINS_MINIMUM_VERSION = getJenkinsMinimumVersion(); BOM_BASE = getBomBase(); BOM_VERSION = getBomVersion(); PLUGIN_PARENT_VERSION = getPluginParentVersion(); @@ -140,8 +140,8 @@ private static Path getDefaultMavenHome() { return readProperty("openrewrite.maven.plugin.version", "versions.properties"); } - private static @Nullable String getJenkinsVersion() { - return readProperty("jenkins.version", "versions.properties"); + private static @Nullable String getJenkinsMinimumVersion() { + return readProperty("jenkins.minimum.version", "versions.properties"); } private static @Nullable String getPluginParentVersion() { From 223557864dbbc5f17c7b28ef4cc771d887bfc6ed Mon Sep 17 00:00:00 2001 From: gounthar <gounthar@gmail.com> Date: Wed, 2 Oct 2024 17:59:53 +0200 Subject: [PATCH 14/17] fix(java): Changed the constant name. --- .../tools/pluginmodernizer/core/utils/PomModifierTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifierTest.java b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifierTest.java index a247f576..0ed71c48 100644 --- a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifierTest.java +++ b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/utils/PomModifierTest.java @@ -115,7 +115,7 @@ public void testUpdateParentPom() throws Exception { @Test public void testUpdateJenkinsMinimalVersion() throws Exception { PomModifier pomModifier = new PomModifier(OUTPUT_POM_PATH); - pomModifier.updateJenkinsMinimalVersion(Settings.JENKINS_VERSION); + pomModifier.updateJenkinsMinimalVersion(Settings.JENKINS_MINIMUM_VERSION); pomModifier.savePom(OUTPUT_POM_PATH); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); @@ -130,7 +130,7 @@ public void testUpdateJenkinsMinimalVersion() throws Exception { .item(0) .getTextContent(); logger.info("Jenkins version found: " + jenkinsVersion); - assertEquals(Settings.JENKINS_VERSION, jenkinsVersion); + assertEquals(Settings.JENKINS_MINIMUM_VERSION, jenkinsVersion); } /** From 510f12eed91952bfd9b2db47f537fe53dc66794a Mon Sep 17 00:00:00 2001 From: gounthar <gounthar@gmail.com> Date: Wed, 2 Oct 2024 18:00:08 +0200 Subject: [PATCH 15/17] fix(java): Changed the constant name. --- .../tools/pluginmodernizer/core/impl/PluginModernizer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/impl/PluginModernizer.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/impl/PluginModernizer.java index 072a7859..59632044 100644 --- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/impl/PluginModernizer.java +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/impl/PluginModernizer.java @@ -163,7 +163,7 @@ private void process(Plugin plugin) { pomModifier.removeOffendingProperties(); pomModifier.addBom("io.jenkins.tools.bom", Settings.BOM_BASE, Settings.BOM_VERSION); pomModifier.updateParentPom("org.jenkins-ci.plugins", "plugin", Settings.PLUGIN_PARENT_VERSION); - pomModifier.updateJenkinsMinimalVersion(Settings.JENKINS_VERSION); + pomModifier.updateJenkinsMinimalVersion(Settings.JENKINS_MINIMUM_VERSION); pomModifier.savePom( plugin.getLocalRepository().resolve("pom.xml").toString()); From 98f4791b0c16e58d03c89ccd1b7d79ae2c35f489 Mon Sep 17 00:00:00 2001 From: gounthar <gounthar@gmail.com> Date: Wed, 2 Oct 2024 18:31:14 +0200 Subject: [PATCH 16/17] fix(java): Parent POM version for JDK8. Since version 4.89, the plugin parent POM requires Jenkins 2.477 or newer and JDK 17 or newer. Since version 4.52, the plugin parent POM requires Jenkins 2.361 or newer and JDK 11 or newer. Since version 4.40, the plugin parent POM supports Java 17. --- plugin-modernizer-core/src/main/resources/versions.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin-modernizer-core/src/main/resources/versions.properties b/plugin-modernizer-core/src/main/resources/versions.properties index fa47852b..ca36baf4 100644 --- a/plugin-modernizer-core/src/main/resources/versions.properties +++ b/plugin-modernizer-core/src/main/resources/versions.properties @@ -1,5 +1,5 @@ openrewrite.maven.plugin.version = ${openrewrite.maven.plugin.version} jenkins.minimum.version = 2.440.3 -jenkins.plugin.parent.version = 4.80 +jenkins.plugin.parent.version = 4.51 bom.version = 3413.v0d896b_76a_30d bom.base = bom-2.440.x From 36d0c913d65b55581af2b6e2a9fec36117f403eb Mon Sep 17 00:00:00 2001 From: gounthar <gounthar@gmail.com> Date: Mon, 7 Oct 2024 10:21:18 +0200 Subject: [PATCH 17/17] fix(recipes): No need for the Non Null detection. --- .../src/main/resources/META-INF/rewrite/recipes.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/plugin-modernizer-core/src/main/resources/META-INF/rewrite/recipes.yml b/plugin-modernizer-core/src/main/resources/META-INF/rewrite/recipes.yml index 92cf5f3e..752b296a 100644 --- a/plugin-modernizer-core/src/main/resources/META-INF/rewrite/recipes.yml +++ b/plugin-modernizer-core/src/main/resources/META-INF/rewrite/recipes.yml @@ -16,7 +16,6 @@ tags: ['java8'] recipeList: - org.openrewrite.maven.security.UseHttpsForRepositories - org.openrewrite.jenkins.DisableLocalResolutionForParentPom - - org.openrewrite.java.cleanup.RemoveRedundantNullChecks --- type: specs.openrewrite.org/v1beta/recipe name: io.jenkins.tools.pluginmodernizer.AddPluginsBom