diff --git a/plugin-modernizer-cli/pom.xml b/plugin-modernizer-cli/pom.xml
index 24db2817..7b91df32 100644
--- a/plugin-modernizer-cli/pom.xml
+++ b/plugin-modernizer-cli/pom.xml
@@ -32,8 +32,17 @@
io.jenkins.plugin-modernizer
plugin-modernizer-core
${changelist}
-
+
+
+ io.jenkins.plugins
+ *
+
+
+ org.jenkins-ci.plugins
+ *
+
org.openrewrite
*
diff --git a/plugin-modernizer-core/pom.xml b/plugin-modernizer-core/pom.xml
index 2cb2dabe..cdf0f89f 100644
--- a/plugin-modernizer-core/pom.xml
+++ b/plugin-modernizer-core/pom.xml
@@ -10,6 +10,19 @@
plugin-modernizer-core
Plugin Modernizer Core
+
+
+
+
+ io.jenkins.tools.bom
+ bom-2.479.x
+ 3875.v1df09947cde6
+ pom
+ import
+
+
+
+
com.fasterxml.jackson.dataformat
@@ -160,6 +173,7 @@
jjwt-impl
runtime
+
ch.qos.logback
logback-classic
@@ -171,26 +185,6 @@
0.0.12
test
-
- jakarta.servlet
- jakarta.servlet-api
- 6.1.0
- test
-
-
- javax.servlet
- javax.servlet-api
- 4.0.1
- test
-
-
- org.kohsuke.stapler
- stapler
- 1928.v9115fe47607f
- test
-
-
-
org.openrewrite
rewrite-test
@@ -202,6 +196,7 @@
2.1.7
test
+
@@ -239,15 +234,44 @@
3.8.1
- copy-dependencies
+ copy
- copy-dependencies
+ copy
validate
- ${project.build.directory}/openrewrite-classpath
-
- javax.servlet,jakarta.servlet,org.kohsuke.stapler
+ ${project.build.directory}/openrewrite-jars
+
+
+
+
+
+ org.kohsuke.stapler
+ stapler
+ 1928.v9115fe47607f
+
+
+ jakarta.servlet
+ jakarta.servlet-api
+ 6.1.0
+
+
+ javax.servlet
+ javax.servlet-api
+ 4.0.1
+
+
+
+ org.jenkins-ci.plugins
+ ssh-slaves
+ 1.12
+
+
+ org.jenkins-ci.plugins
+ ssh-slaves
+ 3.1021.va_cc11b_de26a_e
+
+
@@ -315,4 +339,21 @@
+
+
+
+
+ recipes-dependencies
+
+ true
+
+
+
+ org.jenkins-ci.plugins
+ ssh-slaves
+
+
+
+
+
diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/recipes/EnsureIndexJelly.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/recipes/EnsureIndexJelly.java
new file mode 100644
index 00000000..34412f81
--- /dev/null
+++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/recipes/EnsureIndexJelly.java
@@ -0,0 +1,159 @@
+package io.jenkins.tools.pluginmodernizer.core.recipes;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import io.jenkins.tools.pluginmodernizer.core.extractor.ArchetypeCommonFile;
+import io.jenkins.tools.pluginmodernizer.core.extractor.PluginMetadata;
+import io.jenkins.tools.pluginmodernizer.core.extractor.PomResolutionVisitor;
+import java.nio.file.Path;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import org.intellij.lang.annotations.Language;
+import org.openrewrite.Cursor;
+import org.openrewrite.ExecutionContext;
+import org.openrewrite.ScanningRecipe;
+import org.openrewrite.SourceFile;
+import org.openrewrite.Tree;
+import org.openrewrite.TreeVisitor;
+import org.openrewrite.maven.MavenIsoVisitor;
+import org.openrewrite.text.PlainText;
+import org.openrewrite.xml.tree.Xml;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Ensure `index.jelly` exists
+ */
+public class EnsureIndexJelly extends ScanningRecipe {
+
+ /**
+ * Jelly file
+ */
+ @Language("xml")
+ public static final String JELLY_FILE =
+ """
+
+
+ DESCRIPTION
+
+ """;
+
+ /**
+ * LOGGER.
+ */
+ private static final Logger LOG = LoggerFactory.getLogger(EnsureIndexJelly.class);
+
+ @Override
+ public String getDisplayName() {
+ return "Create `index.jelly` if it doesn't exist";
+ }
+
+ @Override
+ public String getDescription() {
+ return "Jenkins tooling [requires](https://github.com/jenkinsci/maven-hpi-plugin/pull/302) "
+ + "`src/main/resources/index.jelly` exists with a description.";
+ }
+
+ @Override
+ public ShouldCreate getInitialValue(ExecutionContext ctx) {
+ return new ShouldCreate();
+ }
+
+ @Override
+ @SuppressFBWarnings("NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE")
+ public TreeVisitor, ExecutionContext> getScanner(ShouldCreate shouldCreate) {
+ PluginMetadata metadata = new PluginMetadata();
+ return new TreeVisitor<>() {
+ @Override
+ public Tree visit(Tree tree, ExecutionContext ctx) {
+ SourceFile sourceFile = (SourceFile) tree;
+ // We visit a jelly
+ if (sourceFile.getSourcePath().endsWith(ArchetypeCommonFile.INDEX_JELLY.getPath())) {
+ LOG.info("Found 1 index.jelly a Will not replace it");
+ shouldCreate.jelliesPath.add(sourceFile.getSourcePath());
+ return tree;
+ }
+ // We visit a pom
+ if (sourceFile.getSourcePath().endsWith(ArchetypeCommonFile.POM.getPath())) {
+ new PomResolutionVisitor().reduce(sourceFile, metadata);
+ if (metadata.getJenkinsVersion() == null) {
+ LOG.info("Skipping pom {} as it is not a Jenkins plugin", sourceFile.getSourcePath());
+ return tree;
+ }
+ Path jellyPath = sourceFile
+ .getSourcePath()
+ .resolve("..")
+ .resolve(ArchetypeCommonFile.INDEX_JELLY.getPath())
+ .normalize();
+ Xml.Document pom = (Xml.Document) sourceFile;
+ DescriptionVisitor descriptionVisitor = new DescriptionVisitor();
+ descriptionVisitor.visitNonNull(pom, ctx);
+ if (!descriptionVisitor.description.isEmpty()) {
+ shouldCreate.plugins.put(jellyPath, descriptionVisitor.description);
+ } else if (!descriptionVisitor.artifactId.isEmpty()) {
+ shouldCreate.plugins.put(jellyPath, descriptionVisitor.artifactId);
+ }
+ LOG.debug(shouldCreate.toString());
+ }
+ return tree;
+ }
+ };
+ }
+
+ /**
+ * Visitor to extract the metadata from the POM file.
+ */
+ private static class DescriptionVisitor extends MavenIsoVisitor {
+ private String artifactId = "";
+ private String description = "";
+
+ @Override
+ public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) {
+ Cursor parent = getCursor().getParentOrThrow();
+ if (!(parent.getValue() instanceof Xml.Tag)) {
+ return super.visitTag(tag, ctx);
+ }
+ Xml.Tag parentTag = parent.getValue();
+ if (!parentTag.getName().equals("project")) {
+ return super.visitTag(tag, ctx);
+ }
+ if ("description".equals(tag.getName())) {
+ description = tag.getValue().orElse("");
+ } else if ("artifactId".equals(tag.getName()) && !isManagedDependencyTag() && !isDependencyTag()) {
+ artifactId =
+ tag.getValue().orElseThrow(() -> new IllegalStateException("Expected to find an artifact id"));
+ }
+ return super.visitTag(tag, ctx);
+ }
+ }
+
+ /**
+ * Accumulator to know if the file should be created or not and with which description.
+ */
+ public static class ShouldCreate {
+ private Map plugins = new HashMap<>();
+ private List jelliesPath = new LinkedList<>();
+ }
+
+ @Override
+ public Collection generate(ShouldCreate shouldCreate, ExecutionContext ctx) {
+ if (shouldCreate.plugins.isEmpty()) {
+ return Collections.emptyList();
+ }
+ List generated = new LinkedList<>();
+ for (Map.Entry plugin : shouldCreate.plugins.entrySet()) {
+ if (shouldCreate.jelliesPath.contains(plugin.getKey())) {
+ continue;
+ }
+ LOG.info("Creating index.jelly at " + plugin.getKey() + " with description " + plugin.getValue());
+ generated.add(PlainText.builder()
+ .sourcePath(plugin.getKey())
+ .text(JELLY_FILE.replace("DESCRIPTION", plugin.getValue()))
+ .build());
+ }
+ return generated;
+ }
+}
diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/recipes/code/ReplaceRemovedSSHLauncherConstructor.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/recipes/code/ReplaceRemovedSSHLauncherConstructor.java
new file mode 100644
index 00000000..ae12ab38
--- /dev/null
+++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/recipes/code/ReplaceRemovedSSHLauncherConstructor.java
@@ -0,0 +1,71 @@
+package io.jenkins.tools.pluginmodernizer.core.recipes.code;
+
+import org.openrewrite.ExecutionContext;
+import org.openrewrite.NlsRewrite;
+import org.openrewrite.Preconditions;
+import org.openrewrite.Recipe;
+import org.openrewrite.TreeVisitor;
+import org.openrewrite.java.JavaIsoVisitor;
+import org.openrewrite.java.JavaParser;
+import org.openrewrite.java.JavaTemplate;
+import org.openrewrite.java.search.IsLikelyTest;
+import org.openrewrite.java.tree.J;
+
+/**
+ * A recipe that update the bom version to latest available.
+ */
+public class ReplaceRemovedSSHLauncherConstructor extends Recipe {
+
+ @Override
+ public @NlsRewrite.DisplayName String getDisplayName() {
+ return "Replace a remove SSHLauncher constructor";
+ }
+
+ @Override
+ public @NlsRewrite.Description String getDescription() {
+ return "Replace a remove SSHLauncher constructor.";
+ }
+
+ @Override
+ public TreeVisitor, ExecutionContext> getVisitor() {
+ // Only run on test files
+ return Preconditions.check(new IsLikelyTest(), new UseDataBoundConstructor());
+ }
+
+ /**
+ * Visitor that replace the removed SSHLauncher removed constructor by the new one.
+ */
+ public static class UseDataBoundConstructor extends JavaIsoVisitor {
+
+ // We will replace by the @DataBoundConstructor
+ JavaTemplate newConstructorTemplate = JavaTemplate.builder(
+ "new SSHLauncher(#{any(java.lang.String)}, #{any(int)}, null)")
+ .imports("hudson.plugins.sshslaves.SSHLauncher")
+ .javaParser(JavaParser.fromJavaVersion().classpath("ssh-slaves"))
+ .build();
+
+ @Override
+ public J.NewClass visitNewClass(J.NewClass newClass, ExecutionContext ctx) {
+ newClass = super.visitNewClass(newClass, ctx);
+ if (newClass.getConstructorType() == null) {
+ return newClass;
+ }
+ if (!newClass.getConstructorType()
+ .getDeclaringType()
+ .getFullyQualifiedName()
+ .equals("hudson.plugins.sshslaves.SSHLauncher")) {
+ return newClass;
+ }
+ // Replace removed 6 arguments constructor with 3 arguments constructor
+ // See https://github.com/jenkinsci/ssh-agents-plugin/commit/f540572d7819bec840605227636de319a192bc84
+ if (newClass.getArguments().size() == 6) {
+ return newConstructorTemplate.apply(
+ updateCursor(newClass),
+ newClass.getCoordinates().replace(),
+ newClass.getArguments().get(0),
+ newClass.getArguments().get(1));
+ }
+ return newClass;
+ }
+ }
+}
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 5051418f..12657158 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
@@ -149,6 +149,8 @@ description: Upgrade to the next major parent version (5.X) requiring Jenkins 2.
tags: ['dependencies']
recipeList:
- io.jenkins.tools.pluginmodernizer.core.recipes.EnsureRelativePath
+ - io.jenkins.tools.pluginmodernizer.EnsureIndexJelly
+ - io.jenkins.tools.pluginmodernizer.core.recipes.UpdateScmUrl
- org.openrewrite.maven.UpgradeParentVersion:
groupId: org.jenkins-ci.plugins
artifactId: plugin
@@ -399,6 +401,8 @@ description: Upgrade to the latest recommended core version and ensure the BOM m
tags: ['developer']
recipeList:
- io.jenkins.tools.pluginmodernizer.core.recipes.EnsureRelativePath
+ - io.jenkins.tools.pluginmodernizer.EnsureIndexJelly
+ - io.jenkins.tools.pluginmodernizer.core.recipes.UpdateScmUrl
- io.jenkins.tools.pluginmodernizer.UpgradeParentVersion
- io.jenkins.tools.pluginmodernizer.core.recipes.UpgradeJenkinsVersion:
minimumVersion: 2.452.4
@@ -414,6 +418,8 @@ description: Upgrade to latest LTS core version supporting Java 11.
tags: ['developer']
recipeList:
- io.jenkins.tools.pluginmodernizer.core.recipes.EnsureRelativePath
+ - io.jenkins.tools.pluginmodernizer.EnsureIndexJelly
+ - io.jenkins.tools.pluginmodernizer.core.recipes.UpdateScmUrl
- io.jenkins.tools.pluginmodernizer.UpgradeParentVersion
- io.jenkins.tools.pluginmodernizer.core.recipes.UpgradeJenkinsVersion:
minimumVersion: 2.462.3
@@ -421,6 +427,11 @@ recipeList:
- io.jenkins.tools.pluginmodernizer.RemoveExtraMavenProperties
- io.jenkins.tools.pluginmodernizer.UpgradeBomVersion
- io.jenkins.tools.pluginmodernizer.MigrateToJenkinsBaseLineProperty
+ - org.openrewrite.maven.UpgradeDependencyVersion: # Latest using Java 11 support
+ groupId: org.jenkins-ci.test
+ artifactId: docker-fixtures
+ newVersion: 190.vd6a_e600cb_775
+ versionPattern: "\\.v[a-f0-9_]+"
---
type: specs.openrewrite.org/v1beta/recipe
name: io.jenkins.tools.pluginmodernizer.UpgradeToLatestJava8CoreVersion
@@ -429,6 +440,8 @@ description: Upgrade to latest LTS core version supporting Java 8.
tags: ['developer']
recipeList:
- io.jenkins.tools.pluginmodernizer.core.recipes.EnsureRelativePath
+ - io.jenkins.tools.pluginmodernizer.EnsureIndexJelly
+ - io.jenkins.tools.pluginmodernizer.core.recipes.UpdateScmUrl
- org.openrewrite.maven.UpgradeParentVersion:
groupId: org.jenkins-ci.plugins
artifactId: plugin
@@ -436,10 +449,16 @@ recipeList:
- io.jenkins.tools.pluginmodernizer.core.recipes.UpgradeJenkinsVersion:
minimumVersion: 2.346.3
- io.jenkins.tools.pluginmodernizer.RemoveDependencyVersionOverride
+ - io.jenkins.tools.pluginmodernizer.core.recipes.code.ReplaceRemovedSSHLauncherConstructor
- io.jenkins.tools.pluginmodernizer.RemoveExtraMavenProperties
- io.jenkins.tools.pluginmodernizer.UpgradeBomVersion
- io.jenkins.tools.pluginmodernizer.MigrateToJenkinsBaseLineProperty
- org.openrewrite.java.RemoveUnusedImports
+ - org.openrewrite.maven.UpgradeDependencyVersion: # Latest using Java 8 support
+ groupId: org.jenkins-ci.test
+ artifactId: docker-fixtures
+ newVersion: 170.v2339def98d76
+ versionPattern: "\\.v[a-f0-9_]+"
---
type: specs.openrewrite.org/v1beta/recipe
name: io.jenkins.tools.pluginmodernizer.SetupDependabot
@@ -492,3 +511,11 @@ tags: ['condition']
recipeList:
- org.openrewrite.jenkins.IsJenkinsPlugin:
version: "[2.489,)" # Adapt when LTS
+---
+type: specs.openrewrite.org/v1beta/recipe
+name: io.jenkins.tools.pluginmodernizer.EnsureIndexJelly
+displayName: Create `index.jelly` if it doesn't exist
+description: Jenkins tooling [requires](https://github.com/jenkinsci/maven-hpi-plugin/pull/302) `src/main/resources/index.jelly` exists with a description.
+tags: ['chore']
+recipeList:
+ - io.jenkins.tools.pluginmodernizer.core.recipes.EnsureIndexJelly
diff --git a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/recipes/DeclarativeRecipesTest.java b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/recipes/DeclarativeRecipesTest.java
index 0dc0c2f6..3b5b8558 100644
--- a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/recipes/DeclarativeRecipesTest.java
+++ b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/recipes/DeclarativeRecipesTest.java
@@ -1,7 +1,10 @@
package io.jenkins.tools.pluginmodernizer.core.recipes;
import static org.openrewrite.groovy.Assertions.groovy;
-import static org.openrewrite.java.Assertions.*;
+import static org.openrewrite.java.Assertions.java;
+import static org.openrewrite.java.Assertions.mavenProject;
+import static org.openrewrite.java.Assertions.srcMainResources;
+import static org.openrewrite.java.Assertions.srcTestJava;
import static org.openrewrite.maven.Assertions.pomXml;
import static org.openrewrite.test.SourceSpecs.text;
import static org.openrewrite.yaml.Assertions.yaml;
@@ -9,10 +12,12 @@
import io.github.yamlpath.YamlPath;
import io.jenkins.tools.pluginmodernizer.core.config.Settings;
import io.jenkins.tools.pluginmodernizer.core.extractor.ArchetypeCommonFile;
+import io.jenkins.tools.pluginmodernizer.core.recipes.code.ReplaceRemovedSSHLauncherConstructorTest;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
+import org.intellij.lang.annotations.Language;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
@@ -27,6 +32,15 @@
*/
public class DeclarativeRecipesTest implements RewriteTest {
+ @Language("xml")
+ public static final String EXPECTED_JELLY =
+ """
+
+
+ empty
+
+ """;
+
/**
* LOGGER.
*/
@@ -452,6 +466,11 @@ void upgradeToRecommendCoreVersionTest() {
"/META-INF/rewrite/recipes.yml",
"io.jenkins.tools.pluginmodernizer.UpgradeToRecommendCoreVersion"),
// language=xml
+ srcMainResources(text(
+ null,
+ EXPECTED_JELLY,
+ s -> s.path(ArchetypeCommonFile.INDEX_JELLY.getPath().getFileName()))),
+ // language=xml
pomXml(
"""
@@ -467,6 +486,9 @@ void upgradeToRecommendCoreVersionTest() {
1.0.0-SNAPSHOT
hpi
Empty Plugin
+
+ scm:git:git://github.com/jenkinsci/empty-plugin.git
+
2.440.3
17
@@ -509,6 +531,9 @@ void upgradeToRecommendCoreVersionTest() {
1.0.0-SNAPSHOT
hpi
Empty Plugin
+
+ scm:git:https://github.com/jenkinsci/empty-plugin.git
+
2.452
@@ -555,6 +580,11 @@ void upgradeToRecommendCoreVersionTestWithBaseline() {
"/META-INF/rewrite/recipes.yml",
"io.jenkins.tools.pluginmodernizer.UpgradeToRecommendCoreVersion"),
// language=xml
+ srcMainResources(text(
+ null,
+ EXPECTED_JELLY,
+ s -> s.path(ArchetypeCommonFile.INDEX_JELLY.getPath().getFileName()))),
+ // language=xml
pomXml(
"""
@@ -657,6 +687,11 @@ void upgradeToRecommendCoreVersionTestWithMultipleBom() {
"io.jenkins.tools.pluginmodernizer.UpgradeToRecommendCoreVersion");
},
// language=xml
+ srcMainResources(text(
+ null,
+ EXPECTED_JELLY,
+ s -> s.path(ArchetypeCommonFile.INDEX_JELLY.getPath().getFileName()))),
+ // language=xml
pomXml(
"""
@@ -668,7 +703,7 @@ void upgradeToRecommendCoreVersionTestWithMultipleBom() {
4.88
- my-api
+ empty
${revision}-${changelist}
hpi
My API Plugin
@@ -729,7 +764,7 @@ void upgradeToRecommendCoreVersionTestWithMultipleBom() {
4.88
- my-api
+ empty
${revision}-${changelist}
hpi
My API Plugin
@@ -792,6 +827,11 @@ void upgradeToUpgradeToLatestJava11CoreVersion() {
"/META-INF/rewrite/recipes.yml",
"io.jenkins.tools.pluginmodernizer.UpgradeToLatestJava11CoreVersion"),
// language=xml
+ srcMainResources(text(
+ null,
+ EXPECTED_JELLY,
+ s -> s.path(ArchetypeCommonFile.INDEX_JELLY.getPath().getFileName()))),
+ // language=xml
pomXml(
"""
@@ -807,6 +847,9 @@ void upgradeToUpgradeToLatestJava11CoreVersion() {
1.0.0-SNAPSHOT
hpi
Empty Plugin
+
+ scm:git:git://github.com/jenkinsci/empty-plugin.git
+
2.440.3
@@ -850,6 +893,9 @@ void upgradeToUpgradeToLatestJava11CoreVersion() {
1.0.0-SNAPSHOT
hpi
Empty Plugin
+
+ scm:git:https://github.com/jenkinsci/empty-plugin.git
+
2.462
@@ -886,9 +932,24 @@ void upgradeToUpgradeToLatestJava11CoreVersion() {
@Test
void upgradeToUpgradeToLatestJava8CoreVersion() {
rewriteRun(
- spec -> spec.recipeFromResource(
- "/META-INF/rewrite/recipes.yml",
- "io.jenkins.tools.pluginmodernizer.UpgradeToLatestJava8CoreVersion"),
+ spec -> {
+ var parser = JavaParser.fromJavaVersion().logCompilationWarningsAndErrors(true);
+ collectRewriteTestDependencies().stream()
+ .filter(entry -> entry.getFileName().toString().contains("ssh-slaves-1.12"))
+ .forEach(parser::addClasspathEntry);
+ spec.recipeFromResource(
+ "/META-INF/rewrite/recipes.yml",
+ "io.jenkins.tools.pluginmodernizer.UpgradeToLatestJava8CoreVersion")
+ .parser(parser);
+ },
+ // language=java
+ srcTestJava(java(
+ ReplaceRemovedSSHLauncherConstructorTest.BEFORE,
+ ReplaceRemovedSSHLauncherConstructorTest.AFTER)),
+ srcMainResources(text(
+ null,
+ EXPECTED_JELLY,
+ s -> s.path(ArchetypeCommonFile.INDEX_JELLY.getPath().getFileName()))),
// language=xml
pomXml(
"""
@@ -906,6 +967,9 @@ void upgradeToUpgradeToLatestJava8CoreVersion() {
1.0.0-SNAPSHOT
hpi
Empty Plugin
+
+ scm:git:git://github.com/jenkinsci/empty-plugin.git
+
2.303.3
@@ -949,6 +1013,9 @@ void upgradeToUpgradeToLatestJava8CoreVersion() {
1.0.0-SNAPSHOT
hpi
Empty Plugin
+
+ scm:git:https://github.com/jenkinsci/empty-plugin.git
+
2.346
@@ -994,6 +1061,11 @@ void upgradeNextMajorParentVersionTest() {
},
mavenProject("test"),
// language=xml
+ srcMainResources(text(
+ null,
+ EXPECTED_JELLY,
+ s -> s.path(ArchetypeCommonFile.INDEX_JELLY.getPath().getFileName()))),
+ // language=xml
pomXml(
"""
@@ -1009,6 +1081,9 @@ void upgradeNextMajorParentVersionTest() {
1.0.0-SNAPSHOT
hpi
Empty Plugin
+
+ scm:git:https://github.com/jenkinsci/empty-plugin.git
+
11
2.440.3
@@ -1045,6 +1120,9 @@ void upgradeNextMajorParentVersionTest() {
1.0.0-SNAPSHOT
hpi
Empty Plugin
+
+ scm:git:https://github.com/jenkinsci/empty-plugin.git
+
2.479.1
@@ -1097,6 +1175,11 @@ void upgradeNextMajorParentVersionTestWithBom() {
"/META-INF/rewrite/recipes.yml",
"io.jenkins.tools.pluginmodernizer.UpgradeNextMajorParentVersion"),
// language=xml
+ srcMainResources(text(
+ null,
+ EXPECTED_JELLY,
+ s -> s.path(ArchetypeCommonFile.INDEX_JELLY.getPath().getFileName()))),
+ // language=xml
pomXml(
"""
@@ -1200,6 +1283,11 @@ void upgradeNextMajorParentVersionTestWithBaseline() {
"/META-INF/rewrite/recipes.yml",
"io.jenkins.tools.pluginmodernizer.UpgradeNextMajorParentVersion"),
// language=xml
+ srcMainResources(text(
+ null,
+ EXPECTED_JELLY,
+ s -> s.path(ArchetypeCommonFile.INDEX_JELLY.getPath().getFileName()))),
+ // language=xml
pomXml(
"""
@@ -2253,9 +2341,9 @@ void shouldAddSecurityScan() {
*
* @return List of Path
*/
- private List collectRewriteTestDependencies() {
+ public static List collectRewriteTestDependencies() {
try {
- List entries = Files.list(Path.of("target/openrewrite-classpath"))
+ List entries = Files.list(Path.of("target/openrewrite-jars"))
.filter(p -> p.toString().endsWith(".jar"))
.toList();
LOG.debug("Collected rewrite test dependencies: {}", entries);
diff --git a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/recipes/EnsureIndexJellyTest.java b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/recipes/EnsureIndexJellyTest.java
new file mode 100644
index 00000000..5fe7a62a
--- /dev/null
+++ b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/recipes/EnsureIndexJellyTest.java
@@ -0,0 +1,237 @@
+package io.jenkins.tools.pluginmodernizer.core.recipes;
+
+import static org.openrewrite.java.Assertions.mavenProject;
+import static org.openrewrite.java.Assertions.srcMainResources;
+import static org.openrewrite.maven.Assertions.pomXml;
+import static org.openrewrite.test.SourceSpecs.text;
+
+import io.jenkins.tools.pluginmodernizer.core.extractor.ArchetypeCommonFile;
+import org.junit.jupiter.api.Test;
+import org.openrewrite.test.RewriteTest;
+
+/**
+ * Test for {@link EnsureIndexJelly}.
+ */
+public class EnsureIndexJellyTest implements RewriteTest {
+
+ @Test
+ void shouldNotReplaceJellyFile() {
+ rewriteRun(spec -> spec.recipe(new EnsureIndexJelly()), text("jelly", sourceSpecs -> {
+ sourceSpecs.path(ArchetypeCommonFile.INDEX_JELLY.getPath());
+ }));
+ }
+
+ @Test
+ void createFromDescription() {
+ rewriteRun(
+ spec -> spec.recipe(new EnsureIndexJelly()),
+ // language=xml
+ pomXml(
+ """
+
+
+ org.jenkins-ci.plugins
+ plugin
+ 4.88
+
+ empty
+ The empty plugin
+ 1.0.0-SNAPSHOT
+
+
+ repo.jenkins-ci.org
+ https://repo.jenkins-ci.org/public/
+
+
+
+ """),
+ text(
+ null,
+ """
+
+
+ The empty plugin
+
+ """,
+ s -> s.path(ArchetypeCommonFile.INDEX_JELLY.getPath())));
+ }
+
+ @Test
+ void createNoCreateIfNotAPlugin() {
+ rewriteRun(
+ spec -> spec.recipe(new EnsureIndexJelly()),
+ // language=xml
+ pomXml(
+ """
+
+ not-plugin
+ Not a plugin
+ org.example
+ 1.0.0-SNAPSHOT
+
+ """));
+ }
+
+ @Test
+ void createFromArtifactIdEmptyDescription() {
+ rewriteRun(
+ spec -> spec.recipe(new EnsureIndexJelly()),
+ // language=xml
+ pomXml(
+ """
+
+
+ org.jenkins-ci.plugins
+ plugin
+ 4.88
+
+ empty
+
+ 1.0.0-SNAPSHOT
+
+
+ repo.jenkins-ci.org
+ https://repo.jenkins-ci.org/public/
+
+
+
+ """),
+ text(
+ null,
+ """
+
+
+ empty
+
+ """,
+ s -> s.path(ArchetypeCommonFile.INDEX_JELLY.getPath())));
+ }
+
+ @Test
+ void createFromArtifactIdNoDescription() {
+ rewriteRun(
+ spec -> spec.recipe(new EnsureIndexJelly()),
+ // language=xml
+ pomXml(
+ """
+
+
+ org.jenkins-ci.plugins
+ plugin
+ 4.88
+
+ empty
+ 1.0.0-SNAPSHOT
+
+
+ repo.jenkins-ci.org
+ https://repo.jenkins-ci.org/public/
+
+
+
+ """),
+ text(
+ null,
+ """
+
+
+ empty
+
+ """,
+ s -> s.path("src/main/resources/index.jelly")));
+ }
+
+ @Test
+ void shouldCreateMultipleNestedIndexJellies() {
+ rewriteRun(
+ spec -> spec.recipe(new EnsureIndexJelly()),
+ mavenProject(
+ "parent",
+ // language=xml
+ pomXml(
+ """
+
+ org.example
+ my-root
+ 0.1
+ pom
+
+ plugin
+ other-plugin
+ not-a-plugin
+
+
+ """),
+ mavenProject(
+ "plugin",
+ pomXml(
+ """
+
+
+ org.jenkins-ci.plugins
+ plugin
+ 4.86
+
+ plugin
+ 1.0.0-SNAPSHOT
+
+
+ repo.jenkins-ci.org
+ https://repo.jenkins-ci.org/public/
+
+
+
+ """),
+ srcMainResources(text(
+ null,
+ """
+
+
+ plugin
+
+ """,
+ s -> s.path(ArchetypeCommonFile.INDEX_JELLY
+ .getPath()
+ .getFileName()
+ .toString())))),
+ mavenProject(
+ "other-plugin",
+ pomXml(
+ """
+
+
+ org.jenkins-ci.plugins
+ plugin
+ 4.88
+
+ other-plugin
+ 1.0.0-SNAPSHOT
+
+
+ repo.jenkins-ci.org
+ https://repo.jenkins-ci.org/public/
+
+
+
+ """),
+ srcMainResources(text(
+ null,
+ """
+
+
+ other-plugin
+
+ """,
+ s -> s.path("index.jelly")))),
+ mavenProject(
+ "non-plugin",
+ pomXml(
+ """
+
+ org.example
+ not-a-plugin
+ 1.0.0-SNAPSHOT
+
+ """))));
+ }
+}
diff --git a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/recipes/code/ReplaceRemovedSSHLauncherConstructorTest.java b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/recipes/code/ReplaceRemovedSSHLauncherConstructorTest.java
new file mode 100644
index 00000000..0394ba9d
--- /dev/null
+++ b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/recipes/code/ReplaceRemovedSSHLauncherConstructorTest.java
@@ -0,0 +1,69 @@
+package io.jenkins.tools.pluginmodernizer.core.recipes.code;
+
+import static org.openrewrite.java.Assertions.java;
+import static org.openrewrite.java.Assertions.srcTestJava;
+
+import io.jenkins.tools.pluginmodernizer.core.recipes.DeclarativeRecipesTest;
+import org.intellij.lang.annotations.Language;
+import org.junit.jupiter.api.Test;
+import org.openrewrite.java.JavaParser;
+import org.openrewrite.test.RewriteTest;
+
+/**
+ * Test for {@link ReplaceRemovedSSHLauncherConstructor}
+ */
+public class ReplaceRemovedSSHLauncherConstructorTest implements RewriteTest {
+
+ @Language("java")
+ public static final String BEFORE =
+ """
+ import hudson.plugins.sshslaves.SSHLauncher;
+
+ public class Foo {
+ public void foo() {
+ SSHLauncher launcher = new SSHLauncher("127.0.0.1", 22, "username", "password", "privatekey", "jvmOptions");
+ }
+ }
+ """;
+
+ @Language("java")
+ public static final String AFTER =
+ """
+ import hudson.plugins.sshslaves.SSHLauncher;
+
+ public class Foo {
+ public void foo() {
+ SSHLauncher launcher = new SSHLauncher("127.0.0.1", 22, null);
+ }
+ }
+ """;
+
+ @Test
+ void replaceConstructor() {
+ rewriteRun(
+ spec -> {
+ var parser = JavaParser.fromJavaVersion().logCompilationWarningsAndErrors(true);
+ DeclarativeRecipesTest.collectRewriteTestDependencies().stream()
+ .filter(entry -> entry.getFileName().toString().contains("ssh-slaves-1.12"))
+ .forEach(parser::addClasspathEntry);
+ spec.recipe(new ReplaceRemovedSSHLauncherConstructor()).parser(parser);
+ },
+ // language=java
+ srcTestJava(java(BEFORE, AFTER)));
+ }
+
+ @Test
+ void keepConstructor() {
+ rewriteRun(
+ spec -> {
+ var parser = JavaParser.fromJavaVersion().logCompilationWarningsAndErrors(true);
+ DeclarativeRecipesTest.collectRewriteTestDependencies().stream()
+ .filter(entry ->
+ entry.getFileName().toString().contains("ssh-slaves-3.1021.va_cc11b_de26a_e"))
+ .forEach(parser::addClasspathEntry);
+ spec.recipe(new ReplaceRemovedSSHLauncherConstructor()).parser(parser);
+ },
+ // language=java
+ srcTestJava(java(AFTER)));
+ }
+}