From 8825e3b7d9d469829f8da70e38148e7efb7f2dee Mon Sep 17 00:00:00 2001 From: Valentin Delaye Date: Tue, 7 Jan 2025 12:22:07 +0100 Subject: [PATCH] Avoid hardcoding implicit JDK and workarround #580 --- .../core/extractor/JenkinsfileVisitor.java | 6 ++--- .../core/impl/PluginModernizer.java | 25 +++++++++++-------- .../pluginmodernizer/core/model/JDK.java | 20 +++++++++++++++ .../core/utils/StaticPomParser.java | 14 +++++++++++ .../core/extractor/FetchMetadataTest.java | 6 ++--- .../pluginmodernizer/core/model/JDKTest.java | 12 +++++++++ 6 files changed, 67 insertions(+), 16 deletions(-) diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/JenkinsfileVisitor.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/JenkinsfileVisitor.java index c7a235a3..f015b2c5 100644 --- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/JenkinsfileVisitor.java +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/JenkinsfileVisitor.java @@ -84,8 +84,8 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Plugi // Empty args means Java 8 in Windows and Linux if (args.size() == 1 && args.get(0) instanceof J.Empty) { - pluginMetadata.addPlatform(new PlatformConfig(Platform.LINUX, JDK.JAVA_8, null, true)); - pluginMetadata.addPlatform(new PlatformConfig(Platform.WINDOWS, JDK.JAVA_8, null, true)); + pluginMetadata.addPlatform(new PlatformConfig(Platform.LINUX, JDK.getImplicit(), null, true)); + pluginMetadata.addPlatform(new PlatformConfig(Platform.WINDOWS, JDK.getImplicit(), null, true)); return method; } @@ -112,7 +112,7 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Plugi for (PlatformConfig pc : platforms) { if (!pc.name().equals(Platform.UNKNOWN)) { if (platforms.stream().allMatch(p -> p.jdk() == null)) { - newPlatforms.add(new PlatformConfig(pc.name(), JDK.JAVA_8, null, false)); + newPlatforms.add(new PlatformConfig(pc.name(), JDK.getImplicit(), null, false)); continue; } for (PlatformConfig pc2 : platforms) { 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 ab00c849..da0e5c75 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 @@ -268,14 +268,19 @@ private void process(Plugin plugin) { return; } - // Handle Java 8 plugins and outdated - if (plugin.getMetadata().getJdks().stream().allMatch(jdk -> jdk.equals(JDK.JAVA_8))) { - String jenkinsVersion = new StaticPomParser( - plugin.getLocalRepository().resolve("pom.xml").toString()) - .getJenkinsVersion(); - LOG.debug("Found jenkins version {}", jenkinsVersion); - JDK jdk = JDK.get(jenkinsVersion).stream().findFirst().orElse(JDK.JAVA_8); - LOG.info("Plugin support Java {}. Need a first compile to general classes", jdk.getMajor()); + // Handle outdated plugin or unparsable Jenkinsfile + if (plugin.getMetadata().getJdks().stream().allMatch(jdk -> jdk.equals(JDK.getImplicit()))) { + LOG.info("Plugin look outdated or without Jenkinsfile."); + StaticPomParser parser = new StaticPomParser( + plugin.getLocalRepository().resolve("pom.xml").toString()); + String jenkinsVersion = parser.getJenkinsVersion(); + String baseline = parser.getBaseline(); + if (baseline != null && jenkinsVersion != null && jenkinsVersion.contains("${jenkins.baseline}")) { + jenkinsVersion = jenkinsVersion.replace("${jenkins.baseline}", baseline); + } + LOG.debug("Found jenkins version from pom {}", jenkinsVersion); + JDK jdk = JDK.get(jenkinsVersion).stream().findFirst().orElse(JDK.min()); + LOG.info("Plugin support Java {}. Need a first compile to generate classes", jdk.getMajor()); plugin.verifyQuickBuild(mavenInvoker, jdk); if (plugin.hasErrors()) { plugin.raiseLastError(); @@ -389,7 +394,7 @@ private void collectMetadata(Plugin plugin, boolean retryAfterFirstCompile) { */ private JDK compilePlugin(Plugin plugin) { PluginMetadata metadata = plugin.getMetadata(); - JDK jdk = JDK.min(metadata.getJdks()); + JDK jdk = JDK.min(metadata.getJdks(), metadata.getJenkinsVersion()); plugin.withJDK(jdk); plugin.clean(mavenInvoker); plugin.compile(mavenInvoker); @@ -412,7 +417,7 @@ private JDK verifyPlugin(Plugin plugin) { "No JDKs found in metadata for plugin {}. Using same JDK as rewrite for verification", plugin.getName()); } else { - jdk = JDK.min(metadata.getJdks()); + jdk = JDK.min(metadata.getJdks(), metadata.getJenkinsVersion()); LOG.info("Using minimum JDK {} from metadata for plugin {}", jdk.getMajor(), plugin.getName()); } // If the plugin was modernized we should find next JDK compatible diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/model/JDK.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/model/JDK.java index 5c9fd0de..f3662c61 100644 --- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/model/JDK.java +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/model/JDK.java @@ -139,6 +139,14 @@ public boolean supported(String jenkinsVersion) { return get(jenkinsVersion).contains(this); } + /** + * Get the implicit JDK when not specified on Jenkinsfile + * @return The implicit JDK + */ + public static JDK getImplicit() { + return JDK.JAVA_8; + } + /** * Has next predicate * @param jdk The JDK @@ -221,6 +229,18 @@ public static JDK min(Set jdks) { return jdks.stream().min(JDK::compareMajor).orElseThrow(); } + /** + * Return the minimum JDK + * @param jdks List of JDKS. Can be null or empty + * @return The minimum JDK. If the list is empty, return the minimum JDK available + */ + public static JDK min(Set jdks, String jenkinsVersion) { + if (jdks == null || jdks.isEmpty() && jenkinsVersion == null) { + return JDK.min(); + } + return JDK.get(jenkinsVersion).stream().min(JDK::compareMajor).orElseThrow(); + } + /** * Return a list of all JDK sorted by major version * @return The list of JDKs diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/utils/StaticPomParser.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/utils/StaticPomParser.java index 8c696100..79e87ba4 100644 --- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/utils/StaticPomParser.java +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/utils/StaticPomParser.java @@ -82,6 +82,20 @@ public String getJenkinsVersion() { } } + /** + * Return the Jenkins baseline of the POM file. + * @return the Jenkins baseline or null if not found + */ + public String getBaseline() { + XPath xPath = XPathFactory.newInstance().newXPath(); + try { + return xPath.compile("/project/properties/jenkins.baseline").evaluate(document); + } catch (Exception e) { + LOG.warn("Error getting baseline: {}", e.getMessage()); + return null; + } + } + /** * Return the groupId of the POM file. * @return the groupId or null if not found diff --git a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/extractor/FetchMetadataTest.java b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/extractor/FetchMetadataTest.java index 8b84080e..22a45161 100644 --- a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/extractor/FetchMetadataTest.java +++ b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/extractor/FetchMetadataTest.java @@ -554,8 +554,8 @@ void testPluginWithJenkinsfileWithJdkInfoVersionVar() { void testPluginWithJenkinsfileDefault() { // Keep in sync with https://github.com/jenkins-infra/pipeline-library with default JDK and 2 platforms - EXPECTED_METADATA.addPlatform(Platform.LINUX, JDK.JAVA_8, null); - EXPECTED_METADATA.addPlatform(Platform.WINDOWS, JDK.JAVA_8, null); + EXPECTED_METADATA.addPlatform(Platform.LINUX, JDK.getImplicit(), null); + EXPECTED_METADATA.addPlatform(Platform.WINDOWS, JDK.getImplicit(), null); rewriteRun( recipeSpec -> recipeSpec.recipe(new FetchMetadata()), @@ -574,7 +574,7 @@ void testPluginWithJenkinsfileDefault() { Set jdkVersion = pluginMetadata.getJdks(); assertEquals(1, jdkVersion.size()); assertNull(pluginMetadata.isUseContainerAgent()); - assertTrue(jdkVersion.contains(JDK.JAVA_8)); + assertTrue(jdkVersion.contains(JDK.getImplicit())); // Assert platform Set platforms = pluginMetadata.getPlatforms(); diff --git a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/model/JDKTest.java b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/model/JDKTest.java index cbd7479c..335a8780 100644 --- a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/model/JDKTest.java +++ b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/model/JDKTest.java @@ -3,6 +3,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; +import java.util.Set; import org.junit.jupiter.api.Test; public class JDKTest { @@ -47,6 +48,17 @@ public void all() { assertEquals(JDK.JAVA_21, JDK.all().get(3)); } + @Test + public void min() { + assertEquals(JDK.JAVA_8, JDK.min()); + assertEquals(JDK.JAVA_8, JDK.min(Set.of(JDK.values()))); + assertEquals(JDK.JAVA_8, JDK.min(Set.of(JDK.values()), "2.164.1")); + assertEquals(JDK.JAVA_8, JDK.min(Set.of(JDK.values()), "2.346.1")); + assertEquals(JDK.JAVA_11, JDK.min(Set.of(JDK.values()), "2.361.1")); + assertEquals(JDK.JAVA_11, JDK.min(Set.of(JDK.values()), "2.462.3")); + assertEquals(JDK.JAVA_17, JDK.min(Set.of(JDK.values()), "2.479.1")); + } + @Test public void getBuildableJdk() {