From fa6969a658c524d4a3565dec45b2fe2dc6939061 Mon Sep 17 00:00:00 2001 From: Valentin Delaye Date: Wed, 1 Jan 2025 10:29:59 +0100 Subject: [PATCH] Allow to run recipes on outdated plugins --- .../core/impl/MavenInvoker.java | 8 ++-- .../core/impl/PluginModernizer.java | 37 ++++++++++++++++--- .../pluginmodernizer/core/model/Plugin.java | 26 ++++++++++++- 3 files changed, 60 insertions(+), 11 deletions(-) diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/impl/MavenInvoker.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/impl/MavenInvoker.java index 507ac70d..fe84c3f5 100644 --- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/impl/MavenInvoker.java +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/impl/MavenInvoker.java @@ -73,14 +73,14 @@ public class MavenInvoker { /** * Invoke a goal on a plugin * @param plugin The plugin to run the goal on - * @param goal The goal to run. For example, "clean" + * @param goals The goals to run. For example, "clean" */ - public void invokeGoal(Plugin plugin, String goal) { - LOG.debug("Running {} phase for plugin {}", goal, plugin.getName()); + public void invokeGoal(Plugin plugin, String... goals) { + LOG.debug("Running {} phase for plugin {}", goals, plugin.getName()); LOG.debug( "Running maven on directory {}", plugin.getLocalRepository().toAbsolutePath().toFile()); - invokeGoals(plugin, goal); + invokeGoals(plugin, goals); } /** 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 f6c8a7ca..3dfd7623 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 @@ -6,6 +6,7 @@ import io.jenkins.tools.pluginmodernizer.core.extractor.PluginMetadata; import io.jenkins.tools.pluginmodernizer.core.github.GHService; import io.jenkins.tools.pluginmodernizer.core.model.JDK; +import io.jenkins.tools.pluginmodernizer.core.model.ModernizerException; import io.jenkins.tools.pluginmodernizer.core.model.Plugin; import io.jenkins.tools.pluginmodernizer.core.model.PluginProcessingException; import io.jenkins.tools.pluginmodernizer.core.utils.PluginService; @@ -228,7 +229,7 @@ private void process(Plugin plugin) { // Collect metadata and move metadata from the target directory of the plugin to the common cache if (!plugin.hasMetadata() || config.isFetchMetadataOnly()) { - collectMetadata(plugin); + collectMetadata(plugin, true); } else { LOG.debug("Metadata already computed for plugin {}. Using cached metadata.", plugin.getName()); @@ -253,7 +254,7 @@ private void process(Plugin plugin) { // Retry to collect metadata after remediation to get up-to-date results if (!config.isFetchMetadataOnly()) { - collectMetadata(plugin); + collectMetadata(plugin, true); } } @@ -292,7 +293,7 @@ private void process(Plugin plugin) { if (!config.isFetchMetadataOnly()) { plugin.withJDK(JDK.JAVA_17); plugin.clean(mavenInvoker); - collectMetadata(plugin); + collectMetadata(plugin, false); LOG.debug( "Plugin {} metadata after modernization: {}", plugin.getName(), @@ -325,8 +326,34 @@ private void process(Plugin plugin) { * Collect metadata for a plugin * @param plugin The plugin */ - private void collectMetadata(Plugin plugin) { - plugin.collectMetadata(mavenInvoker); + private void collectMetadata(Plugin plugin, boolean retryAfterFirstCompile) { + LOG.debug("Collecting metadata for plugin {}... Please be patient", plugin.getName()); + plugin.withJDK(JDK.JAVA_17); + try { + plugin.collectMetadata(mavenInvoker); + if (plugin.hasErrors()) { + plugin.raiseLastError(); + } + } catch (ModernizerException e) { + if (retryAfterFirstCompile) { + plugin.removeErrors(); + LOG.warn( + "Failed to collect metadata for plugin {}. Will retry after a first compile using lowest JDK", + plugin.getName()); + plugin.verifyWithoutTests(mavenInvoker, JDK.JAVA_8); + if (plugin.hasErrors()) { + LOG.debug( + "Plugin {} failed to compile with JDK 8. Skipping metadata collection after retry", + plugin.getName()); + plugin.raiseLastError(); + } + plugin.withJDK(JDK.JAVA_17); + plugin.collectMetadata(mavenInvoker); + } else { + LOG.info("Failed to collect metadata for plugin {}. Not retrying.", plugin.getName()); + throw e; + } + } plugin.copyMetadata(cacheManager); plugin.loadMetadata(cacheManager); plugin.enrichMetadata(pluginService); diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/model/Plugin.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/model/Plugin.java index 0c3c9009..39b7110d 100644 --- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/model/Plugin.java +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/model/Plugin.java @@ -357,6 +357,13 @@ public void raiseLastError() throws PluginProcessingException { throw errors.get(errors.size() - 1); } + /** + * Remove all errors from the plugin + */ + public void removeErrors() { + errors.clear(); + } + /** * Add a tag to the plugin * @param tag Tag to add @@ -489,7 +496,7 @@ public void clean(MavenInvoker maven) { } /** - * Execute maven compile on this plugin + * Execute maven compile on this plugin. Compile is skipped if only metadata is required * @param maven The maven invoker instance */ public void compile(MavenInvoker maven) { @@ -507,6 +514,21 @@ public void compile(MavenInvoker maven) { } } + /** + * Verify the plugin without tests using the given maven invoker and JDK. + * This is useful to run recipes on very outdated plugin + * @param maven The maven invoker instance + * @param jdk The JDK to use + */ + public void verifyWithoutTests(MavenInvoker maven, JDK jdk) { + LOG.info("Verifying plugin without tests {} using with JDK {} ... Please be patient", name, jdk.getMajor()); + this.withJDK(jdk); + maven.invokeGoal(this, "verify", "-DskipTests"); + if (!hasErrors()) { + LOG.info("Done"); + } + } + /** * Execute maven verify on this plugin * @param maven The maven invoker instance @@ -572,7 +594,7 @@ public void collectMetadata(MavenInvoker maven) { // Static parse of the pom file and check for pattern preventing minimal build Path pom = getLocalRepository().resolve("pom.xml"); if (!getLocalRepository().resolve("target").toFile().mkdir()) { - LOG.debug("Failed to create target directory for plugin {}", name); + LOG.trace("Failed to create target directory for plugin {}", name); } Document document = staticPomParse(pom);