From a69f9a34835cef5dfa4123d60a261d163bbbc504 Mon Sep 17 00:00:00 2001 From: Valentin Delaye Date: Wed, 18 Dec 2024 14:09:55 +0100 Subject: [PATCH 1/2] Ensure preconditions for API plugins --- .gitignore | 2 - .../cli/CommandLineITCase.java | 7 +- .../resources/replace-by-api-plugins/pom.xml | 88 +++++++++++++++++++ .../src/main/resources/index.jelly | 4 + .../pluginmodernizer/core/model/Recipe.java | 7 ++ .../resources/META-INF/rewrite/recipes.yml | 18 +++- 6 files changed, 120 insertions(+), 6 deletions(-) create mode 100644 plugin-modernizer-cli/src/test/resources/replace-by-api-plugins/pom.xml create mode 100644 plugin-modernizer-cli/src/test/resources/replace-by-api-plugins/src/main/resources/index.jelly diff --git a/.gitignore b/.gitignore index 2989fb2d..8d905583 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,5 @@ target/ !.mvn/wrapper/maven-wrapper.jar -!**/src/main/**/target/ -!**/src/test/**/target/ ### Log file ### logs/ diff --git a/plugin-modernizer-cli/src/test/java/io/jenkins/tools/pluginmodernizer/cli/CommandLineITCase.java b/plugin-modernizer-cli/src/test/java/io/jenkins/tools/pluginmodernizer/cli/CommandLineITCase.java index 2a0f4795..fd004001 100644 --- a/plugin-modernizer-cli/src/test/java/io/jenkins/tools/pluginmodernizer/cli/CommandLineITCase.java +++ b/plugin-modernizer-cli/src/test/java/io/jenkins/tools/pluginmodernizer/cli/CommandLineITCase.java @@ -66,6 +66,11 @@ private static Stream testsPlugins() { setPluginName("empty"); setJenkinsVersion("2.440.3"); } + + { + setPluginName("replace-by-api-plugins"); + setJenkinsVersion("2.452.4"); + } })); } @@ -227,7 +232,7 @@ public void testBuildMetadata(PluginMetadata expectedMetadata, WireMockRuntimeIn .anyMatch(line -> line.matches("(.*)GitHub owner: fake-owner(.*)"))), () -> assertTrue(Files.readAllLines(outputPath.resolve("stdout.txt")).stream() .anyMatch(line -> - line.matches(".*Metadata was fetched for plugin empty and is available at.*")))); + line.matches(".*Metadata was fetched for plugin (.*) and is available at.*")))); // Assert some metadata PluginMetadata metadata = JsonUtils.fromJson( diff --git a/plugin-modernizer-cli/src/test/resources/replace-by-api-plugins/pom.xml b/plugin-modernizer-cli/src/test/resources/replace-by-api-plugins/pom.xml new file mode 100644 index 00000000..88e6d9c2 --- /dev/null +++ b/plugin-modernizer-cli/src/test/resources/replace-by-api-plugins/pom.xml @@ -0,0 +1,88 @@ + + + 4.0.0 + + + org.jenkins-ci.plugins + plugin + 4.88 + + + + io.jenkins.plugins + replace-by-api-plugin + ${revision}${changelist} + hpi + + TODO Plugin + https://github.com/jenkinsci/${project.artifactId}-plugin + + + MIT License + https://opensource.org/license/mit/ + + + + scm:git:https://github.com/${gitHubRepo} + scm:git:https://github.com/${gitHubRepo} + ${scmTag} + https://github.com/${gitHubRepo} + + + + 1.0 + -SNAPSHOT + + 2.452 + ${jenkins.baseline}.4 + jenkinsci/${project.artifactId}-plugin + + false + + + + + + io.jenkins.tools.bom + bom-${jenkins.baseline}.x + 3814.v9563d972079a_ + pom + import + + + + + + + + com.google.code.gson + gson + 2.10.1 + + + + + org.apache.commons + commons-compress + 1.26.1 + + + org.json + json + 20240303 + + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + diff --git a/plugin-modernizer-cli/src/test/resources/replace-by-api-plugins/src/main/resources/index.jelly b/plugin-modernizer-cli/src/test/resources/replace-by-api-plugins/src/main/resources/index.jelly new file mode 100644 index 00000000..35f37a7f --- /dev/null +++ b/plugin-modernizer-cli/src/test/resources/replace-by-api-plugins/src/main/resources/index.jelly @@ -0,0 +1,4 @@ + +
+ TODO +
diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/model/Recipe.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/model/Recipe.java index fed86cc3..e4b40d23 100644 --- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/model/Recipe.java +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/model/Recipe.java @@ -16,6 +16,9 @@ public class Recipe { @JsonIgnore private Object recipeList; // Use Object to avoid mapping complex nested structures. + @JsonIgnore + private Object preconditions; // Use Object to avoid mapping complex nested structures. + public String getName() { return name; } @@ -63,4 +66,8 @@ public Object getRecipeList() { public void setRecipeList(Object recipeList) { this.recipeList = recipeList; } + + public Object getPreconditions() { + return preconditions; + } } 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 d4983397..cb1675b0 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 @@ -107,11 +107,15 @@ name: io.jenkins.tools.pluginmodernizer.UseJsonApiPlugin displayName: Use JSON API plugin instead of direct dependency description: Use JSON API plugin instead of direct dependency tags: ['developer'] +preconditions: + - org.openrewrite.maven.FindDependency: + groupId: org.jenkins-ci.main + artifactId: jenkins-core + version: ">=2.452.4" recipeList: - org.openrewrite.jenkins.ReplaceLibrariesWithApiPlugin: pluginGroupId: io.jenkins.plugins pluginArtifactId: json-api - # TODO: version from bom and filtered here ? or managed by renovate ? pluginVersion: 20240303-41.v94e11e6de726 replaces: - groupId: org.json @@ -122,11 +126,15 @@ name: io.jenkins.tools.pluginmodernizer.UseGsonApiPlugin displayName: Use GSON API plugin instead of direct dependency description: Use GSON API plugin instead of direct dependency tags: ['developer'] +preconditions: + - org.openrewrite.maven.FindDependency: + groupId: org.jenkins-ci.main + artifactId: jenkins-core + version: ">=2.452.4" recipeList: - org.openrewrite.jenkins.ReplaceLibrariesWithApiPlugin: pluginGroupId: io.jenkins.plugins pluginArtifactId: gson-api - # TODO: version from bom and filtered here ? or managed by renovate ? pluginVersion: 2.11.0-85.v1f4e87273c33 replaces: - groupId: com.google.code.gson @@ -137,11 +145,15 @@ name: io.jenkins.tools.pluginmodernizer.UseCompressApiPlugin displayName: Use Compress API plugin instead of direct dependency description: Use Compress API plugin instead of direct dependency tags: ['developer'] +preconditions: + - org.openrewrite.maven.FindDependency: + groupId: org.jenkins-ci.main + artifactId: jenkins-core + version: ">=2.489" recipeList: - org.openrewrite.jenkins.ReplaceLibrariesWithApiPlugin: pluginGroupId: io.jenkins.plugins pluginArtifactId: commons-compress-api - # TODO: version from bom and filtered here ? or managed by renovate ? pluginVersion: 1.26.1-2 replaces: - groupId: org.apache.commons From 8cff607ab8859b8536b13429be8dadcb3593bc0e Mon Sep 17 00:00:00 2001 From: Valentin Delaye Date: Wed, 18 Dec 2024 14:55:47 +0100 Subject: [PATCH 2/2] API plugin recipes conditions and integrationt test --- README.md | 29 +++ plugin-modernizer-cli/pom.xml | 59 ++++- .../cli/command/DryRunCommand.java | 16 ++ .../cli/CommandLineITCase.java | 217 +++++++++++------- .../cli/utils/ModernizerTestWatcher.java | 32 +++ .../test/resources/empty/.github/CODEOWNERS | 1 - .../resources/empty/.github/dependabot.yml | 12 - .../empty/.github/release-drafter.yml | 2 - .../workflows/jenkins-security-scan.yml | 23 -- .../.github/workflows/release-drafter.yml | 17 -- .../test/resources/empty/.mvn/extensions.xml | 7 - .../test/resources/empty/.mvn/maven.config | 2 - .../src/test/resources/empty/LICENSE.md | 9 - .../src/test/resources/empty/README.md | 28 --- .../src/test/resources/empty/pom.xml | 31 +-- .../src/test/resources/empty/rewrite.yml | 7 + .../replace-by-api-plugins/.gitignore | 15 ++ .../resources/replace-by-api-plugins/pom.xml | 62 +++-- .../replace-by-api-plugins/rewrite.yml | 7 + .../resources/META-INF/rewrite/recipes.yml | 140 +++++++++-- 20 files changed, 475 insertions(+), 241 deletions(-) create mode 100644 plugin-modernizer-cli/src/test/java/io/jenkins/tools/pluginmodernizer/cli/utils/ModernizerTestWatcher.java delete mode 100644 plugin-modernizer-cli/src/test/resources/empty/.github/CODEOWNERS delete mode 100644 plugin-modernizer-cli/src/test/resources/empty/.github/dependabot.yml delete mode 100644 plugin-modernizer-cli/src/test/resources/empty/.github/release-drafter.yml delete mode 100644 plugin-modernizer-cli/src/test/resources/empty/.github/workflows/jenkins-security-scan.yml delete mode 100644 plugin-modernizer-cli/src/test/resources/empty/.github/workflows/release-drafter.yml delete mode 100644 plugin-modernizer-cli/src/test/resources/empty/.mvn/extensions.xml delete mode 100644 plugin-modernizer-cli/src/test/resources/empty/.mvn/maven.config delete mode 100644 plugin-modernizer-cli/src/test/resources/empty/LICENSE.md delete mode 100644 plugin-modernizer-cli/src/test/resources/empty/README.md create mode 100644 plugin-modernizer-cli/src/test/resources/empty/rewrite.yml create mode 100644 plugin-modernizer-cli/src/test/resources/replace-by-api-plugins/.gitignore create mode 100644 plugin-modernizer-cli/src/test/resources/replace-by-api-plugins/rewrite.yml diff --git a/README.md b/README.md index 9e99445a..841f1d20 100644 --- a/README.md +++ b/README.md @@ -291,6 +291,35 @@ If you are using a mirror for `central` you should adapt the `reference.repo` pr Thanks to all our contributors! Check out our [CONTRIBUTING](docs/CONTRIBUTING.md) file to learn how to get started. +## How to debug recipes + +Update the `rewrite.yml` into the src/test/resources/ + +Example + +```yaml +--- +type: specs.openrewrite.org/v1beta/recipe +name: io.jenkins.tools.pluginmodernizer.Debug +displayName: Debug recipe +description: Debug recipe +conditions: [] +recipeList: [] +``` + +Then run openrewrite with the following command + +```shell +mvn org.openrewrite.maven:rewrite-maven-plugin:dryRun -Drewrite.recipeArtifactCoordinates=org.openrewrite.recipe:rewrite-jenkins:0.19.0 -Drewrite.activeRecipes=io.jenkins.tools.pluginmodernizer.Debug +``` + +If you want to test with recipes from modernizer core + +``` +mvn org.openrewrite.maven:rewrite-maven-plugin:dryRun -Drewrite.recipeArtifactCoordinates=io.jenkins.plugin-modernizer:plugin-modernizer-core:999999-SNAPSHOT -Drewrite.activeRecipes=io.jenkins.tools.pluginmodernizer.Debug + +``` + ## References - [GSoC 2024 Project Proposal](https://docs.google.com/document/d/1e1QkprPN6fLpFXk_QqBUQlJhZrAl9RvXbOXOiJ-gAuY/edit?usp=sharing) diff --git a/plugin-modernizer-cli/pom.xml b/plugin-modernizer-cli/pom.xml index 41bc4d72..207da469 100644 --- a/plugin-modernizer-cli/pom.xml +++ b/plugin-modernizer-cli/pom.xml @@ -90,6 +90,38 @@ + + + + maven-clean-plugin + + + clean-plugin + + clean + + clean + + + + src/test/resources + + **/target/** + + + + . + + logs/*.log + logs/*.txt + + + + + + + + org.apache.maven.plugins @@ -127,7 +159,6 @@ **/*ITCase.java - ${maven.repo.local} ${project.build.directory}/apache-maven-${maven.version} fake-token fake-owner @@ -203,4 +234,30 @@ + + + + maven-repo-local + + + maven.repo.local + + + + + + maven-failsafe-plugin + + + + maven.repo.local + ${maven.repo.local} + + + + + + + + diff --git a/plugin-modernizer-cli/src/main/java/io/jenkins/tools/pluginmodernizer/cli/command/DryRunCommand.java b/plugin-modernizer-cli/src/main/java/io/jenkins/tools/pluginmodernizer/cli/command/DryRunCommand.java index 10d79493..d76fd93d 100644 --- a/plugin-modernizer-cli/src/main/java/io/jenkins/tools/pluginmodernizer/cli/command/DryRunCommand.java +++ b/plugin-modernizer-cli/src/main/java/io/jenkins/tools/pluginmodernizer/cli/command/DryRunCommand.java @@ -1,6 +1,8 @@ package io.jenkins.tools.pluginmodernizer.cli.command; import io.jenkins.tools.pluginmodernizer.cli.converter.RecipeConverter; +import io.jenkins.tools.pluginmodernizer.cli.options.EnvOptions; +import io.jenkins.tools.pluginmodernizer.cli.options.GitHubOptions; import io.jenkins.tools.pluginmodernizer.cli.options.GlobalOptions; import io.jenkins.tools.pluginmodernizer.cli.options.PluginOptions; import io.jenkins.tools.pluginmodernizer.core.config.Config; @@ -38,16 +40,30 @@ public class DryRunCommand implements ICommand { converter = RecipeConverter.class) private Recipe recipe; + /** + * Environment options + */ + @CommandLine.Mixin + private EnvOptions envOptions; + /** * Global options for all commands */ @CommandLine.Mixin private GlobalOptions options; + /** + * GitHub options + */ + @CommandLine.Mixin + private GitHubOptions githubOptions; + @Override public Config setup(Config.Builder builder) { options.config(builder); pluginOptions.config(builder); + githubOptions.config(builder); + envOptions.config(builder); return builder.withDryRun(true).withRecipe(recipe).build(); } diff --git a/plugin-modernizer-cli/src/test/java/io/jenkins/tools/pluginmodernizer/cli/CommandLineITCase.java b/plugin-modernizer-cli/src/test/java/io/jenkins/tools/pluginmodernizer/cli/CommandLineITCase.java index fd004001..a1cfaae5 100644 --- a/plugin-modernizer-cli/src/test/java/io/jenkins/tools/pluginmodernizer/cli/CommandLineITCase.java +++ b/plugin-modernizer-cli/src/test/java/io/jenkins/tools/pluginmodernizer/cli/CommandLineITCase.java @@ -9,6 +9,7 @@ import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo; import com.github.tomakehurst.wiremock.junit5.WireMockTest; import io.jenkins.tools.pluginmodernizer.cli.utils.GitHubServerContainer; +import io.jenkins.tools.pluginmodernizer.cli.utils.ModernizerTestWatcher; import io.jenkins.tools.pluginmodernizer.core.extractor.PluginMetadata; import io.jenkins.tools.pluginmodernizer.core.impl.CacheManager; import io.jenkins.tools.pluginmodernizer.core.model.Plugin; @@ -30,7 +31,10 @@ import org.apache.maven.shared.invoker.InvocationResult; import org.apache.maven.shared.invoker.Invoker; import org.bouncycastle.openssl.jcajce.JcaPEMWriter; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.io.CleanupMode; import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -45,6 +49,7 @@ */ @WireMockTest @Testcontainers(disabledWithoutDocker = true) +@ExtendWith(ModernizerTestWatcher.class) public class CommandLineITCase { static { @@ -61,94 +66,101 @@ public class CommandLineITCase { * @return the plugins */ private static Stream testsPlugins() { - return Stream.of(Arguments.of(new PluginMetadata() { - { - setPluginName("empty"); - setJenkinsVersion("2.440.3"); - } - - { - setPluginName("replace-by-api-plugins"); - setJenkinsVersion("2.452.4"); - } - })); + return Stream.of( + Arguments.of(new PluginMetadata() { + { + setPluginName("empty"); + setJenkinsVersion("2.452.4"); + } + }), + Arguments.of(new PluginMetadata() { + { + setPluginName("replace-by-api-plugins"); + setJenkinsVersion("2.452.4"); + } + })); } - @TempDir - private Path outputPath; + // Path for logs + private final Path logFolder = Path.of("logs"); - @TempDir + // Allow to debug source code after the test as run + @TempDir(cleanup = CleanupMode.NEVER) private Path cachePath; @TempDir private Path keysPath; + @BeforeEach + public void beforeEach() throws Exception { + if (!Files.isDirectory(logFolder)) { + Files.createDirectory(logFolder); + } + } + @Test public void testVersion() throws Exception { - LOG.info("Running testVersion"); + Path logFile = setupLogs("testVersion"); Invoker invoker = buildInvoker(); - InvocationResult result1 = invoker.execute(buildRequest("--version")); + InvocationResult result1 = invoker.execute(buildRequest("--version", logFile)); assertAll( () -> assertEquals(0, result1.getExitCode()), - () -> assertTrue(Files.readAllLines(outputPath.resolve("stdout.txt")).stream() - .anyMatch(line -> line.matches("plugin modernizer ([a-zA-Z0-9.-_]+) (.*)")))); + () -> assertTrue(Files.readAllLines(logFile).stream() + .anyMatch(line -> line.matches("plugin modernizer ([a-zA-Z0-9.\\-_]+) (.*)")))); - Files.delete(outputPath.resolve("stdout.txt")); - - InvocationResult result2 = invoker.execute(buildRequest("version")); + InvocationResult result2 = invoker.execute(buildRequest("version", logFile)); assertAll( () -> assertEquals(0, result2.getExitCode()), - () -> assertTrue(Files.readAllLines(outputPath.resolve("stdout.txt")).stream() - .anyMatch(line -> line.matches("plugin modernizer ([a-zA-Z0-9.-_]+) (.*)")))); - - Files.delete(outputPath.resolve("stdout.txt")); + () -> assertTrue(Files.readAllLines(logFile).stream() + .anyMatch(line -> line.matches("plugin modernizer ([a-zA-Z0-9.\\-_]+) (.*)")))); - InvocationResult result3 = invoker.execute(buildRequest("version --short")); + InvocationResult result3 = invoker.execute(buildRequest("version --short", logFile)); assertAll( () -> assertEquals(0, result3.getExitCode()), - () -> assertTrue(Files.readAllLines(outputPath.resolve("stdout.txt")).stream() - .anyMatch(line -> line.matches("(.*)\\s*[a-zA-Z0-9.-_]+\\s*")))); + () -> assertTrue(Files.readAllLines(logFile).stream() + .anyMatch(line -> line.matches("(.*)\\s*[a-zA-Z0-9.\\-_]+\\s*")))); } @Test public void testHelp() throws Exception { - LOG.info("Running testHelp"); + Path logFile = setupLogs("testHelp"); Invoker invoker = buildInvoker(); - InvocationRequest request = buildRequest("--help"); + InvocationRequest request = buildRequest("--help", logFile); InvocationResult result = invoker.execute(request); assertAll( () -> assertEquals(0, result.getExitCode()), - () -> assertTrue(Files.readAllLines(outputPath.resolve("stdout.txt")).stream() + () -> assertTrue(Files.readAllLines(logFile).stream() .anyMatch(line -> line.matches("(.*)Usage: plugin-modernizer (.*) COMMAND(.*)")))); } @Test public void testCleanupWithDryRun() throws Exception { - LOG.info("Running testCleanupWithDryRun"); + Path logFile = setupLogs("testCleanupWithDryRun"); Invoker invoker = buildInvoker(); - InvocationRequest request = buildRequest("cleanup --cache-path %s --dry-run".formatted(cachePath)); + InvocationRequest request = buildRequest("cleanup --cache-path %s --dry-run".formatted(cachePath), logFile); InvocationResult result = invoker.execute(request); assertAll( () -> assertEquals(0, result.getExitCode()), - () -> assertTrue(Files.readAllLines(outputPath.resolve("stdout.txt")).stream() + () -> assertTrue(Files.readAllLines(logFile).stream() .anyMatch(line -> line.matches("(.*)Would remove path: (.*)")))); } @Test public void testCleanup() throws Exception { - LOG.info("Running testCleanup"); + Path logFile = setupLogs("testCleanup"); Invoker invoker = buildInvoker(); - InvocationRequest request = buildRequest("cleanup --cache-path %s".formatted(cachePath)); + InvocationRequest request = buildRequest("cleanup --cache-path %s".formatted(cachePath), logFile); InvocationResult result = invoker.execute(request); assertAll( () -> assertEquals(0, result.getExitCode()), - () -> assertTrue(Files.readAllLines(outputPath.resolve("stdout.txt")).stream() - .anyMatch(line -> line.matches("(.*)Removed path: (.*)")))); + () -> assertTrue( + Files.readAllLines(logFile).stream().anyMatch(line -> line.matches("(.*)Removed path: (.*)")))); } @Test public void testValidateWithSshKey(WireMockRuntimeInfo wmRuntimeInfo) throws Exception { - LOG.info("Running testValidateWithSshKey"); + + Path logFile = setupLogs("testValidateWithSshKey"); // Setup WireMock wireMock = wmRuntimeInfo.getWireMock(); @@ -157,24 +169,26 @@ public void testValidateWithSshKey(WireMockRuntimeInfo wmRuntimeInfo) throws Exc WireMock.jsonResponse(new GitHubServerContainer.UserApiResponse("fake-owner", "User"), 200))); Invoker invoker = buildInvoker(); - InvocationRequest request = - buildRequest("validate --maven-home %s --ssh-private-key %s --debug --github-api-url %s/api" + InvocationRequest request = buildRequest( + "validate --maven-home %s --ssh-private-key %s --debug --github-api-url %s/api" .formatted( getModernizerMavenHome(), generatePrivateKey("testValidateWithSshKey"), - wmRuntimeInfo.getHttpBaseUrl())); + wmRuntimeInfo.getHttpBaseUrl()), + logFile); InvocationResult result = invoker.execute(request); assertAll( () -> assertEquals(0, result.getExitCode()), - () -> assertTrue(Files.readAllLines(outputPath.resolve("stdout.txt")).stream() + () -> assertTrue(Files.readAllLines(logFile).stream() .anyMatch(line -> line.matches("(.*)GitHub owner: fake-owner(.*)"))), - () -> assertTrue(Files.readAllLines(outputPath.resolve("stdout.txt")).stream() + () -> assertTrue(Files.readAllLines(logFile).stream() .anyMatch(line -> line.matches("(.*)Validation successful(.*)")))); } @Test public void testValidate(WireMockRuntimeInfo wmRuntimeInfo) throws Exception { - LOG.info("Running testValidate"); + + Path logFile = setupLogs("testValidate"); // Setup WireMock wireMock = wmRuntimeInfo.getWireMock(); @@ -183,26 +197,26 @@ public void testValidate(WireMockRuntimeInfo wmRuntimeInfo) throws Exception { WireMock.jsonResponse(new GitHubServerContainer.UserApiResponse("fake-owner", "User"), 200))); Invoker invoker = buildInvoker(); - InvocationRequest request = - buildRequest("validate --debug --github-api-url %s/api".formatted(wmRuntimeInfo.getHttpBaseUrl())); + InvocationRequest request = buildRequest( + "validate --debug --github-api-url %s/api".formatted(wmRuntimeInfo.getHttpBaseUrl()), logFile); InvocationResult result = invoker.execute(request); assertAll( () -> assertEquals(0, result.getExitCode()), - () -> assertTrue(Files.readAllLines(outputPath.resolve("stdout.txt")).stream() + () -> assertTrue(Files.readAllLines(logFile).stream() .anyMatch(line -> line.matches("(.*)GitHub owner: fake-owner(.*)"))), - () -> assertTrue(Files.readAllLines(outputPath.resolve("stdout.txt")).stream() + () -> assertTrue(Files.readAllLines(logFile).stream() .anyMatch(line -> line.matches("(.*)Validation successful(.*)")))); } @Test public void testListRecipes() throws Exception { - LOG.info("Running testListRecipes"); + Path logFile = setupLogs("testListRecipes"); Invoker invoker = buildInvoker(); - InvocationRequest request = buildRequest("recipes"); + InvocationRequest request = buildRequest("recipes", logFile); InvocationResult result = invoker.execute(request); assertAll( () -> assertEquals(0, result.getExitCode()), - () -> assertTrue(Files.readAllLines(outputPath.resolve("stdout.txt")).stream() + () -> assertTrue(Files.readAllLines(logFile).stream() .anyMatch( line -> line.matches(".*FetchMetadata - Extracts metadata from a Jenkins plugin.*")))); } @@ -211,26 +225,31 @@ public void testListRecipes() throws Exception { @MethodSource("testsPlugins") public void testBuildMetadata(PluginMetadata expectedMetadata, WireMockRuntimeInfo wmRuntimeInfo) throws Exception { + Path logFile = logFolder.resolve("testBuildMetadata-%s.txt".formatted(expectedMetadata.getPluginName())); + Files.deleteIfExists(logFile); + Files.createFile(logFile); String plugin = expectedMetadata.getPluginName(); // Junit attachment with logs file for the plugin build System.out.printf( "[[ATTACHMENT|%s]]%n", Plugin.build(plugin).getLogFile().toAbsolutePath()); + System.out.printf("[[ATTACHMENT|%s]]%n", logFile.toAbsolutePath()); try (GitHubServerContainer gitRemote = new GitHubServerContainer(wmRuntimeInfo, keysPath, plugin, "main")) { gitRemote.start(); Invoker invoker = buildInvoker(); - InvocationRequest request = buildRequest("build-metadata %s".formatted(getRunArgs(wmRuntimeInfo, plugin))); + InvocationRequest request = + buildRequest("build-metadata %s".formatted(getRunArgs(wmRuntimeInfo, plugin)), logFile); InvocationResult result = invoker.execute(request); // Assert output assertAll( () -> assertEquals(0, result.getExitCode()), - () -> assertTrue(Files.readAllLines(outputPath.resolve("stdout.txt")).stream() + () -> assertTrue(Files.readAllLines(logFile).stream() .anyMatch(line -> line.matches("(.*)GitHub owner: fake-owner(.*)"))), - () -> assertTrue(Files.readAllLines(outputPath.resolve("stdout.txt")).stream() + () -> assertTrue(Files.readAllLines(logFile).stream() .anyMatch(line -> line.matches(".*Metadata was fetched for plugin (.*) and is available at.*")))); @@ -246,6 +265,33 @@ public void testBuildMetadata(PluginMetadata expectedMetadata, WireMockRuntimeIn } } + @Test + public void testDryRunReplaceLibrariesWithApiPlugin(WireMockRuntimeInfo wmRuntimeInfo) throws Exception { + + Path logFile = setupLogs("testDryRunReplaceLibrariesWithApiPlugin"); + + final String plugin = "replace-by-api-plugins"; + final String recipe = "ReplaceLibrariesWithApiPlugin"; + + // Junit attachment with logs file for the plugin build + System.out.printf( + "[[ATTACHMENT|%s]]%n", Plugin.build(plugin).getLogFile().toAbsolutePath()); + System.out.printf("[[ATTACHMENT|%s]]%n", logFile.toAbsolutePath()); + + try (GitHubServerContainer gitRemote = new GitHubServerContainer(wmRuntimeInfo, keysPath, plugin, "main")) { + + gitRemote.start(); + + Invoker invoker = buildInvoker(); + InvocationRequest request = buildRequest( + "dry-run --recipe %s %s".formatted(recipe, getRunArgs(wmRuntimeInfo, plugin)), logFile); + InvocationResult result = invoker.execute(request); + + // Assert output + assertAll(() -> assertEquals(0, result.getExitCode())); + } + } + /** * Build the invoker * @return the invoker @@ -264,7 +310,7 @@ private Invoker buildInvoker() { * Build the request * @return the request */ - private InvocationRequest buildRequest(String args) { + private InvocationRequest buildRequest(String args, Path logFile) { String javaHomeEnv = System.getenv("JAVA_HOME"); assertNotNull(javaHomeEnv, "JAVA_HOME is not set"); Path javaHome = Path.of(javaHomeEnv); @@ -290,11 +336,7 @@ private InvocationRequest buildRequest(String args) { request.setJavaHome(javaHome.toFile()); request.setOutputHandler(line -> { try { - Files.write( - outputPath.resolve("stdout.txt"), - (line + System.lineSeparator()).getBytes(), - StandardOpenOption.CREATE, - StandardOpenOption.APPEND); + Files.write(logFile, (line + System.lineSeparator()).getBytes(), StandardOpenOption.APPEND); } catch (Exception e) { LOG.error("Error writing to stdout", e); throw new RuntimeException(e); @@ -303,11 +345,7 @@ private InvocationRequest buildRequest(String args) { }); request.setErrorHandler(line -> { try { - Files.write( - outputPath.resolve("stderr.txt"), - (line + System.lineSeparator()).getBytes(), - StandardOpenOption.CREATE, - StandardOpenOption.APPEND); + Files.write(logFile, (line + System.lineSeparator()).getBytes(), StandardOpenOption.APPEND); } catch (Exception e) { LOG.error("Error writing to stderr", e); throw new RuntimeException(e); @@ -342,6 +380,20 @@ private Path getModernizerMavenHome() { return Path.of("target/apache-maven-3.9.9").toAbsolutePath(); } + /** + * Setup log file for a given test + * @param test The test name + * @throws Exception If an error occurs + */ + private Path setupLogs(String test) throws Exception { + Path logFile = logFolder.resolve("%s.txt".formatted(test)); + Files.deleteIfExists(logFile); + Files.createFile(logFile); + LOG.debug("Created log file: {}", logFile.toAbsolutePath()); + System.out.printf("[[ATTACHMENT|%s]]%n", logFile.toAbsolutePath()); + return logFile; + } + /** * Get the URL arguments * @param wmRuntimeInfo The WireMock runtime info @@ -349,7 +401,14 @@ private Path getModernizerMavenHome() { * @return the URL arguments */ private String getRunArgs(WireMockRuntimeInfo wmRuntimeInfo, String plugin) { - return """ + + String args = ""; + String mavenLocalRepo = System.getProperty("maven.repo.local"); + if (mavenLocalRepo != null) { + args += "--maven-local-repo %s ".formatted(mavenLocalRepo); + } + args += + """ --plugins %s --debug --maven-home %s @@ -361,16 +420,18 @@ private String getRunArgs(WireMockRuntimeInfo wmRuntimeInfo, String plugin) { --plugin-health-score %s --jenkins-plugins-stats-installations-url %s """ - .formatted( - plugin, - getModernizerMavenHome(), - keysPath.resolve(plugin), - cachePath, - wmRuntimeInfo.getHttpBaseUrl() + "/api", - wmRuntimeInfo.getHttpBaseUrl() + "/update-center.json", - wmRuntimeInfo.getHttpBaseUrl() + "/plugin-versions.json", - wmRuntimeInfo.getHttpBaseUrl() + "/scores", - wmRuntimeInfo.getHttpBaseUrl() + "/jenkins-stats/svg/202406-plugins.csv") - .replaceAll("\\s+", " "); + .formatted( + plugin, + getModernizerMavenHome(), + keysPath.resolve(plugin), + cachePath, + wmRuntimeInfo.getHttpBaseUrl() + "/api", + wmRuntimeInfo.getHttpBaseUrl() + "/update-center.json", + wmRuntimeInfo.getHttpBaseUrl() + "/plugin-versions.json", + wmRuntimeInfo.getHttpBaseUrl() + "/scores", + wmRuntimeInfo.getHttpBaseUrl() + "/jenkins-stats/svg/202406-plugins.csv") + .replaceAll("\\s+", " "); + LOG.debug("Run args: {}", args); + return args; } } diff --git a/plugin-modernizer-cli/src/test/java/io/jenkins/tools/pluginmodernizer/cli/utils/ModernizerTestWatcher.java b/plugin-modernizer-cli/src/test/java/io/jenkins/tools/pluginmodernizer/cli/utils/ModernizerTestWatcher.java new file mode 100644 index 00000000..22ff482b --- /dev/null +++ b/plugin-modernizer-cli/src/test/java/io/jenkins/tools/pluginmodernizer/cli/utils/ModernizerTestWatcher.java @@ -0,0 +1,32 @@ +package io.jenkins.tools.pluginmodernizer.cli.utils; + +import java.util.Optional; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.TestWatcher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class ModernizerTestWatcher implements TestWatcher { + + private static final Logger LOG = LoggerFactory.getLogger(ModernizerTestWatcher.class); + + @Override + public void testDisabled(ExtensionContext context, Optional reason) { + LOG.info("Test disabled: {}", context.getDisplayName()); + } + + @Override + public void testSuccessful(ExtensionContext context) { + LOG.info("Test successful: {}", context.getDisplayName()); + } + + @Override + public void testAborted(ExtensionContext context, Throwable cause) { + LOG.info("Test aborted: {}", context.getDisplayName()); + } + + @Override + public void testFailed(ExtensionContext context, Throwable cause) { + LOG.error("Test failed: {}", context.getDisplayName(), cause); + } +} diff --git a/plugin-modernizer-cli/src/test/resources/empty/.github/CODEOWNERS b/plugin-modernizer-cli/src/test/resources/empty/.github/CODEOWNERS deleted file mode 100644 index 32321dea..00000000 --- a/plugin-modernizer-cli/src/test/resources/empty/.github/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ -* @jenkinsci/empty-plugin-developers diff --git a/plugin-modernizer-cli/src/test/resources/empty/.github/dependabot.yml b/plugin-modernizer-cli/src/test/resources/empty/.github/dependabot.yml deleted file mode 100644 index 03b4d66f..00000000 --- a/plugin-modernizer-cli/src/test/resources/empty/.github/dependabot.yml +++ /dev/null @@ -1,12 +0,0 @@ -# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuring-dependabot-version-updates - -version: 2 -updates: -- package-ecosystem: maven - directory: / - schedule: - interval: monthly -- package-ecosystem: github-actions - directory: / - schedule: - interval: monthly diff --git a/plugin-modernizer-cli/src/test/resources/empty/.github/release-drafter.yml b/plugin-modernizer-cli/src/test/resources/empty/.github/release-drafter.yml deleted file mode 100644 index a9b7ccc0..00000000 --- a/plugin-modernizer-cli/src/test/resources/empty/.github/release-drafter.yml +++ /dev/null @@ -1,2 +0,0 @@ -_extends: .github -tag-template: empty-$NEXT_MINOR_VERSION diff --git a/plugin-modernizer-cli/src/test/resources/empty/.github/workflows/jenkins-security-scan.yml b/plugin-modernizer-cli/src/test/resources/empty/.github/workflows/jenkins-security-scan.yml deleted file mode 100644 index af839d5b..00000000 --- a/plugin-modernizer-cli/src/test/resources/empty/.github/workflows/jenkins-security-scan.yml +++ /dev/null @@ -1,23 +0,0 @@ -# More information about the Jenkins security scan can be found at the developer docs: https://www.jenkins.io/redirect/jenkins-security-scan/ - -name: Jenkins Security Scan -on: - push: - branches: - - "master" - - "main" - pull_request: - types: [ opened, synchronize, reopened ] - workflow_dispatch: - -permissions: - security-events: write - contents: read - actions: read - -jobs: - security-scan: - uses: jenkins-infra/jenkins-security-scan/.github/workflows/jenkins-security-scan.yaml@v2 - with: - java-cache: 'maven' # Optionally enable use of a build dependency cache. Specify 'maven' or 'gradle' as appropriate. - java-version: 17 # What version of Java to set up for the build. diff --git a/plugin-modernizer-cli/src/test/resources/empty/.github/workflows/release-drafter.yml b/plugin-modernizer-cli/src/test/resources/empty/.github/workflows/release-drafter.yml deleted file mode 100644 index f8e19b47..00000000 --- a/plugin-modernizer-cli/src/test/resources/empty/.github/workflows/release-drafter.yml +++ /dev/null @@ -1,17 +0,0 @@ -# Automates creation of Release Drafts using Release Drafter -# More Info: https://github.com/jenkinsci/.github/blob/master/.github/release-drafter.adoc - -on: - push: - branches: - - master - - main - -jobs: - update_release_draft: - runs-on: ubuntu-latest - steps: - # Drafts your next Release notes as Pull Requests are merged into the default branch - - uses: release-drafter/release-drafter@v6 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/plugin-modernizer-cli/src/test/resources/empty/.mvn/extensions.xml b/plugin-modernizer-cli/src/test/resources/empty/.mvn/extensions.xml deleted file mode 100644 index 30a03ea1..00000000 --- a/plugin-modernizer-cli/src/test/resources/empty/.mvn/extensions.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - io.jenkins.tools.incrementals - git-changelist-maven-extension - 1.8 - - diff --git a/plugin-modernizer-cli/src/test/resources/empty/.mvn/maven.config b/plugin-modernizer-cli/src/test/resources/empty/.mvn/maven.config deleted file mode 100644 index 2a0299c4..00000000 --- a/plugin-modernizer-cli/src/test/resources/empty/.mvn/maven.config +++ /dev/null @@ -1,2 +0,0 @@ --Pconsume-incrementals --Pmight-produce-incrementals diff --git a/plugin-modernizer-cli/src/test/resources/empty/LICENSE.md b/plugin-modernizer-cli/src/test/resources/empty/LICENSE.md deleted file mode 100644 index a187bd6d..00000000 --- a/plugin-modernizer-cli/src/test/resources/empty/LICENSE.md +++ /dev/null @@ -1,9 +0,0 @@ -The MIT License - -Copyright 2024 - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/plugin-modernizer-cli/src/test/resources/empty/README.md b/plugin-modernizer-cli/src/test/resources/empty/README.md deleted file mode 100644 index 7b609332..00000000 --- a/plugin-modernizer-cli/src/test/resources/empty/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# empty - -## Introduction - -TODO Describe what your plugin does here - -## Getting started - -TODO Tell users how to configure your plugin here, include screenshots, pipeline examples and -configuration-as-code examples. - -## Issues - -TODO Decide where you're going to host your issues, the default is Jenkins JIRA, but you can also enable GitHub issues, -If you use GitHub issues there's no need for this section; else add the following line: - -Report issues and enhancements in the [Jenkins issue tracker](https://issues.jenkins.io/). - -## Contributing - -TODO review the default [CONTRIBUTING](https://github.com/jenkinsci/.github/blob/master/CONTRIBUTING.md) file and make sure it is appropriate for your plugin, if not then add your own one adapted from the base file - -Refer to our [contribution guidelines](https://github.com/jenkinsci/.github/blob/master/CONTRIBUTING.md) - -## LICENSE - -Licensed under MIT, see [LICENSE](LICENSE.md) - diff --git a/plugin-modernizer-cli/src/test/resources/empty/pom.xml b/plugin-modernizer-cli/src/test/resources/empty/pom.xml index 10b2d1c7..edf761f8 100644 --- a/plugin-modernizer-cli/src/test/resources/empty/pom.xml +++ b/plugin-modernizer-cli/src/test/resources/empty/pom.xml @@ -5,37 +5,20 @@ org.jenkins-ci.plugins plugin - 4.85 + 4.88 io.jenkins.plugins empty - ${revision}${changelist} + 1.0.0-SNAPSHOT hpi - TODO Plugin - https://github.com/jenkinsci/${project.artifactId}-plugin - - - MIT License - https://opensource.org/license/mit/ - - - - scm:git:https://github.com/${gitHubRepo} - scm:git:https://github.com/${gitHubRepo} - ${scmTag} - https://github.com/${gitHubRepo} - + Empty Plugin - 1.0 - -SNAPSHOT - - 2.440.3 - jenkinsci/${project.artifactId}-plugin - + 2.452 + ${jenkins.baseline}.4 false @@ -43,8 +26,8 @@ io.jenkins.tools.bom - bom-2.440.x - 3193.v330d8248d39e + bom-${jenkins.baseline}.x + 3814.v9563d972079a_ pom import diff --git a/plugin-modernizer-cli/src/test/resources/empty/rewrite.yml b/plugin-modernizer-cli/src/test/resources/empty/rewrite.yml new file mode 100644 index 00000000..3d04bbfa --- /dev/null +++ b/plugin-modernizer-cli/src/test/resources/empty/rewrite.yml @@ -0,0 +1,7 @@ +--- +type: specs.openrewrite.org/v1beta/recipe +name: io.jenkins.tools.pluginmodernizer.Debug +displayName: Debug recipe +description: Debug recipe +conditions: [] +recipeList: [] diff --git a/plugin-modernizer-cli/src/test/resources/replace-by-api-plugins/.gitignore b/plugin-modernizer-cli/src/test/resources/replace-by-api-plugins/.gitignore new file mode 100644 index 00000000..08343646 --- /dev/null +++ b/plugin-modernizer-cli/src/test/resources/replace-by-api-plugins/.gitignore @@ -0,0 +1,15 @@ +target + +# mvn hpi:run +work + +# IntelliJ IDEA project files +*.iml +*.iws +*.ipr +.idea + +# Eclipse project files +.settings +.classpath +.project diff --git a/plugin-modernizer-cli/src/test/resources/replace-by-api-plugins/pom.xml b/plugin-modernizer-cli/src/test/resources/replace-by-api-plugins/pom.xml index 88e6d9c2..b066c27d 100644 --- a/plugin-modernizer-cli/src/test/resources/replace-by-api-plugins/pom.xml +++ b/plugin-modernizer-cli/src/test/resources/replace-by-api-plugins/pom.xml @@ -11,32 +11,14 @@ io.jenkins.plugins replace-by-api-plugin - ${revision}${changelist} + 1.0.0-SNAPSHOT hpi - TODO Plugin - https://github.com/jenkinsci/${project.artifactId}-plugin - - - MIT License - https://opensource.org/license/mit/ - - - - scm:git:https://github.com/${gitHubRepo} - scm:git:https://github.com/${gitHubRepo} - ${scmTag} - https://github.com/${gitHubRepo} - + Replace By API Plugin - 1.0 - -SNAPSHOT - 2.452 ${jenkins.baseline}.4 - jenkinsci/${project.artifactId}-plugin - false @@ -60,17 +42,55 @@ 2.10.1 - + + + joda-time + joda-time + 2.13.0 + + + + + net.bytebuddy + byte-buddy + 1.15.11 + + + org.apache.commons commons-compress 1.26.1 + + + + org.apache.commons + commons-lang3 + 3.17.0 + + + + + org.apache.commons + commons-text + 1.13.0 + + + org.json json 20240303 + + + + org.ow2.asm + asm + 9.7.1 + + diff --git a/plugin-modernizer-cli/src/test/resources/replace-by-api-plugins/rewrite.yml b/plugin-modernizer-cli/src/test/resources/replace-by-api-plugins/rewrite.yml new file mode 100644 index 00000000..3d04bbfa --- /dev/null +++ b/plugin-modernizer-cli/src/test/resources/replace-by-api-plugins/rewrite.yml @@ -0,0 +1,7 @@ +--- +type: specs.openrewrite.org/v1beta/recipe +name: io.jenkins.tools.pluginmodernizer.Debug +displayName: Debug recipe +description: Debug recipe +conditions: [] +recipeList: [] 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 cb1675b0..cea4ab7c 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 @@ -101,6 +101,11 @@ recipeList: - io.jenkins.tools.pluginmodernizer.UseJsonApiPlugin - io.jenkins.tools.pluginmodernizer.UseGsonApiPlugin - io.jenkins.tools.pluginmodernizer.UseCompressApiPlugin + - io.jenkins.tools.pluginmodernizer.UseJodaTimeApiPlugin + - io.jenkins.tools.pluginmodernizer.UseAsmApiPlugin + - io.jenkins.tools.pluginmodernizer.UseByteBuddyApiPlugin + - io.jenkins.tools.pluginmodernizer.UseCommonsLangApiPlugin + - io.jenkins.tools.pluginmodernizer.UseCommonsTextApiPlugin --- type: specs.openrewrite.org/v1beta/recipe name: io.jenkins.tools.pluginmodernizer.UseJsonApiPlugin @@ -108,10 +113,7 @@ displayName: Use JSON API plugin instead of direct dependency description: Use JSON API plugin instead of direct dependency tags: ['developer'] preconditions: - - org.openrewrite.maven.FindDependency: - groupId: org.jenkins-ci.main - artifactId: jenkins-core - version: ">=2.452.4" + - io.jenkins.tools.pluginmodernizer.conditions.IsUsingRecommendCoreVersion recipeList: - org.openrewrite.jenkins.ReplaceLibrariesWithApiPlugin: pluginGroupId: io.jenkins.plugins @@ -122,15 +124,52 @@ recipeList: artifactId: json --- type: specs.openrewrite.org/v1beta/recipe +name: io.jenkins.tools.pluginmodernizer.UseAsmApiPlugin +displayName: Use ASM API plugin instead of direct dependency +description: Use ASM API plugin instead of direct dependency +tags: ['developer'] +preconditions: + - io.jenkins.tools.pluginmodernizer.conditions.IsUsingCoreVersionWithASMRemoved +recipeList: + - org.openrewrite.jenkins.ReplaceLibrariesWithApiPlugin: + pluginGroupId: io.jenkins.plugins + pluginArtifactId: asm-api + pluginVersion: 9.7.1-97.v4cc844130d97 + replaces: + - groupId: org.ow2.asm + artifactId: asm + - groupId: org.ow2.asm + artifactId: asm-analysis + - groupId: org.ow2.asm + artifactId: asm-commons + - groupId: org.ow2.asm + artifactId: asm-tree + - groupId: org.ow2.asm + artifactId: asm-util +--- +type: specs.openrewrite.org/v1beta/recipe +name: io.jenkins.tools.pluginmodernizer.UseJodaTimeApiPlugin +displayName: Use Joda Time API plugin instead of direct dependency +description: Use Joda Time API plugin instead of direct dependency +tags: ['developer'] +preconditions: + - io.jenkins.tools.pluginmodernizer.conditions.IsUsingRecommendCoreVersion +recipeList: + - org.openrewrite.jenkins.ReplaceLibrariesWithApiPlugin: + pluginGroupId: io.jenkins.plugins + pluginArtifactId: joda-time-api + pluginVersion: 2.13.0-93.v9934da_29b_a_e9 + replaces: + - groupId: joda-time + artifactId: joda-time +--- +type: specs.openrewrite.org/v1beta/recipe name: io.jenkins.tools.pluginmodernizer.UseGsonApiPlugin displayName: Use GSON API plugin instead of direct dependency description: Use GSON API plugin instead of direct dependency tags: ['developer'] preconditions: - - org.openrewrite.maven.FindDependency: - groupId: org.jenkins-ci.main - artifactId: jenkins-core - version: ">=2.452.4" + - io.jenkins.tools.pluginmodernizer.conditions.IsUsingRecommendCoreVersion recipeList: - org.openrewrite.jenkins.ReplaceLibrariesWithApiPlugin: pluginGroupId: io.jenkins.plugins @@ -146,10 +185,7 @@ displayName: Use Compress API plugin instead of direct dependency description: Use Compress API plugin instead of direct dependency tags: ['developer'] preconditions: - - org.openrewrite.maven.FindDependency: - groupId: org.jenkins-ci.main - artifactId: jenkins-core - version: ">=2.489" + - io.jenkins.tools.pluginmodernizer.conditions.IsUsingCoreVersionWithCommonsCompressRemoved recipeList: - org.openrewrite.jenkins.ReplaceLibrariesWithApiPlugin: pluginGroupId: io.jenkins.plugins @@ -160,13 +196,60 @@ recipeList: artifactId: commons-compress --- type: specs.openrewrite.org/v1beta/recipe +name: io.jenkins.tools.pluginmodernizer.UseCommonsLangApiPlugin +displayName: Use Commons Lang 3 API plugin instead of direct dependency +description: Use Commons Lang 3 API plugin instead of direct dependency +tags: ['developer'] +preconditions: + - org.openrewrite.jenkins.IsJenkinsPlugin: + version: "[2.361.4,)" +recipeList: + - org.openrewrite.jenkins.ReplaceLibrariesWithApiPlugin: + pluginGroupId: io.jenkins.plugins + pluginArtifactId: commons-lang3-api + pluginVersion: 3.17.0-84.vb_b_938040b_078 + replaces: + - groupId: org.apache.commons + artifactId: commons-lang3 +--- +type: specs.openrewrite.org/v1beta/recipe +name: io.jenkins.tools.pluginmodernizer.UseByteBuddyApiPlugin +displayName: Use Byte Buddy API plugin instead of direct dependency +description: Use Byte Buddy API plugin instead of direct dependency +tags: ['developer'] +preconditions: + - io.jenkins.tools.pluginmodernizer.conditions.IsUsingRecommendCoreVersion +recipeList: + - org.openrewrite.jenkins.ReplaceLibrariesWithApiPlugin: + pluginGroupId: io.jenkins.plugins + pluginArtifactId: byte-buddy-api + pluginVersion: 1.15.11-99.v078c614a_5258 + replaces: + - groupId: net.bytebuddy + artifactId: byte-buddy +--- +type: specs.openrewrite.org/v1beta/recipe +name: io.jenkins.tools.pluginmodernizer.UseCommonsTextApiPlugin +displayName: Use Commons Text API plugin instead of direct dependency +description: Use Commons Text API plugin instead of direct dependency +tags: ['developer'] +preconditions: + - io.jenkins.tools.pluginmodernizer.conditions.IsUsingRecommendCoreVersion +recipeList: + - org.openrewrite.jenkins.ReplaceLibrariesWithApiPlugin: + pluginGroupId: io.jenkins.plugins + pluginArtifactId: commons-text-api + pluginVersion: 1.12.0-129.v99a_50df237f7 + replaces: + - groupId: org.apache.commons + artifactId: commons-text +--- +type: specs.openrewrite.org/v1beta/recipe name: io.jenkins.tools.pluginmodernizer.UpgradeToRecommendCoreVersion displayName: Upgrade to latest recommended core version and ensure the bom is matching the core version description: Upgrade to latest recommended core version and ensure the bom is matching the core version tags: ['developer'] recipeList: - # TODO: https://github.com/jenkins-infra/jenkins.io/blob/master/updatecli/updatecli.d/jenkins-lts.yaml#L104 - # https://github.com/jenkins-infra/jenkins-version? - org.openrewrite.jenkins.UpgradeVersionProperty: key: jenkins.version minimumVersion: 2.452.4 @@ -180,8 +263,6 @@ displayName: Upgrade to latest LTS core version supporting Java 11 description: Upgrade to latest LTS core version supporting Java 11 tags: ['developer'] recipeList: - # TODO: https://github.com/jenkins-infra/jenkins.io/blob/master/updatecli/updatecli.d/jenkins-lts.yaml#L104 - # https://github.com/jenkins-infra/jenkins-version? - org.openrewrite.jenkins.UpgradeVersionProperty: key: jenkins.version minimumVersion: 2.462.3 @@ -256,3 +337,30 @@ tags: ['chore'] recipeList: - org.openrewrite.jenkins.CreateIndexJelly - org.openrewrite.jenkins.AddJellyXmlDeclaration +--- +type: specs.openrewrite.org/v1beta/recipe +name: io.jenkins.tools.pluginmodernizer.conditions.IsUsingRecommendCoreVersion +displayName: Check if the plugin is using the recommended core version +description: Check if the plugin is using the recommended core version +tags: ['condition'] +recipeList: + - org.openrewrite.jenkins.IsJenkinsPlugin: + version: "[2.452.4,)" +--- +type: specs.openrewrite.org/v1beta/recipe +name: io.jenkins.tools.pluginmodernizer.conditions.IsUsingCoreVersionWithASMRemoved +displayName: Check if the plugin is using a version with ASM removed +description: Check if the plugin is using a version with ASM removed +tags: ['condition'] +recipeList: + - org.openrewrite.jenkins.IsJenkinsPlugin: + version: "[2.479.1,)" +--- +type: specs.openrewrite.org/v1beta/recipe +name: io.jenkins.tools.pluginmodernizer.conditions.IsUsingCoreVersionWithCommonsCompressRemoved +displayName: Check if the plugin using using a version with commons-compress removed +description: Check if the plugin using using a version with commons-compress removed +tags: ['condition'] +recipeList: + - org.openrewrite.jenkins.IsJenkinsPlugin: + version: "[2.489,)" # Adapt when LTS