diff --git a/plugin-modernizer-cli/pom.xml b/plugin-modernizer-cli/pom.xml index 02f5463d..24db2817 100644 --- a/plugin-modernizer-cli/pom.xml +++ b/plugin-modernizer-cli/pom.xml @@ -65,6 +65,12 @@ org.slf4j slf4j-api + + commons-io + commons-io + 2.18.0 + test + io.github.sparsick.testcontainers.gitserver 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 4eb08259..96de3060 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 @@ -25,6 +25,7 @@ import java.security.Security; import java.util.Properties; import java.util.stream.Stream; +import org.apache.commons.io.FileUtils; import org.apache.maven.shared.invoker.DefaultInvocationRequest; import org.apache.maven.shared.invoker.DefaultInvoker; import org.apache.maven.shared.invoker.InvocationRequest; @@ -119,7 +120,6 @@ public void testVersion() throws Exception { () -> assertEquals(0, result2.getExitCode()), () -> assertTrue(Files.readAllLines(logFile).stream() .anyMatch(line -> line.matches("plugin modernizer ([a-zA-Z0-9.\\-_]+) (.*)")))); - InvocationResult result3 = invoker.execute(buildRequest("version --short", logFile)); assertAll( () -> assertEquals(0, result3.getExitCode()), @@ -286,7 +286,8 @@ public void testBuildMetadata(PluginMetadata expectedMetadata, WireMockRuntimeIn @Test public void testDryRunReplaceLibrariesWithApiPlugin(WireMockRuntimeInfo wmRuntimeInfo) throws Exception { - Path logFile = setupLogs("testDryRunReplaceLibrariesWithApiPlugin"); + Path logFile1 = setupLogs("testDryRunReplaceLibrariesWithApiPlugin1"); + Path logFile2 = setupLogs("testDryRunReplaceLibrariesWithApiPlugin2"); final String plugin = "replace-by-api-plugins"; final String recipe = "ReplaceLibrariesWithApiPlugin"; @@ -294,7 +295,8 @@ public void testDryRunReplaceLibrariesWithApiPlugin(WireMockRuntimeInfo wmRuntim // 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()); + System.out.printf("[[ATTACHMENT|%s]]%n", logFile1.toAbsolutePath()); + System.out.printf("[[ATTACHMENT|%s]]%n", logFile2.toAbsolutePath()); try (GitHubServerContainer gitRemote = new GitHubServerContainer(wmRuntimeInfo, keysPath, plugin, "main")) { @@ -302,11 +304,38 @@ public void testDryRunReplaceLibrariesWithApiPlugin(WireMockRuntimeInfo wmRuntim Invoker invoker = buildInvoker(); InvocationRequest request = buildRequest( - "dry-run --recipe %s %s".formatted(recipe, getRunArgs(wmRuntimeInfo, plugin)), logFile); + "dry-run --recipe %s %s".formatted(recipe, getRunArgs(wmRuntimeInfo, plugin)), logFile1); InvocationResult result = invoker.execute(request); // Assert output - assertAll(() -> assertEquals(0, result.getExitCode())); + assertAll( + () -> assertEquals(0, result.getExitCode()), + () -> assertTrue(Files.readAllLines(logFile1).stream() + .anyMatch(line -> line.matches("(.*)Dry run mode. Changes were commited on (.*)")))); + + // Delete target folder to use data from cache + File targetDirectory = cachePath + .resolve("jenkins-plugin-modernizer-cli") + .resolve(plugin) + .resolve("sources") + .resolve("target") + .toFile(); + FileUtils.deleteDirectory(targetDirectory); + + // Ensure metadata is still present on cache + assertTrue(Files.exists(cachePath + .resolve("jenkins-plugin-modernizer-cli") + .resolve(plugin) + .resolve(CacheManager.PLUGIN_METADATA_CACHE_KEY))); + + // Ensure it still works after running again (with caching) + InvocationRequest request2 = buildRequest( + "dry-run --recipe %s %s".formatted(recipe, getRunArgs(wmRuntimeInfo, plugin)), logFile2); + InvocationResult result2 = invoker.execute(request2); + assertAll( + () -> assertEquals(0, result2.getExitCode()), + () -> assertTrue(Files.readAllLines(logFile2).stream() + .anyMatch(line -> line.matches("(.*)Dry run mode. Changes were commited on (.*)")))); } } diff --git a/plugin-modernizer-cli/src/test/resources/replace-by-api-plugins/Jenkinsfile b/plugin-modernizer-cli/src/test/resources/replace-by-api-plugins/Jenkinsfile new file mode 100644 index 00000000..09032da7 --- /dev/null +++ b/plugin-modernizer-cli/src/test/resources/replace-by-api-plugins/Jenkinsfile @@ -0,0 +1,11 @@ +/* + See the documentation for more options: + https://github.com/jenkins-infra/pipeline-library/ +*/ +buildPlugin( + forkCount: '1C', // run this number of tests in parallel for faster feedback. If the number terminates with a 'C', the value will be multiplied by the number of available CPU cores + useContainerAgent: true, // Set to `false` if you need to use Docker for containerized tests + configurations: [ + [platform: 'linux', jdk: 21], + [platform: 'windows', jdk: 17], +]) diff --git a/plugin-modernizer-core/pom.xml b/plugin-modernizer-core/pom.xml index c34e4136..d318f466 100644 --- a/plugin-modernizer-core/pom.xml +++ b/plugin-modernizer-core/pom.xml @@ -165,6 +165,27 @@ logback-classic 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 @@ -177,6 +198,7 @@ 2.1.7 test + @@ -206,6 +228,27 @@ + + + + org.apache.maven.plugins + maven-dependency-plugin + 3.8.1 + + + copy-dependencies + + copy-dependencies + + validate + + ${project.build.directory}/openrewrite-classpath + + javax.servlet,jakarta.servlet,org.kohsuke.stapler + + + + gg.jte jte-maven-plugin diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/config/Settings.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/config/Settings.java index 93d5b092..a3dee333 100644 --- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/config/Settings.java +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/config/Settings.java @@ -192,6 +192,10 @@ private static Path getDefaultMavenLocalRepo() { return readProperty("jenkins.parent.version", "versions.properties"); } + public static @Nullable String getBomVersion() { + return readProperty("bom.version", "versions.properties"); + } + private static @Nullable URL getUpdateCenterUrl() throws MalformedURLException { String url = System.getenv("JENKINS_UC"); if (url != null) { diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/MetadataVisitor.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/MetadataVisitor.java index a8bb0adf..8f053590 100644 --- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/MetadataVisitor.java +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/MetadataVisitor.java @@ -66,7 +66,7 @@ public Tree visit(Tree tree, ExecutionContext executionContext) { // Extract metadata from POM else if (PathUtils.matchesGlob(sourceFile.getSourcePath(), "**/pom.xml")) { LOG.debug("Visiting POM {}", sourceFile.getSourcePath()); - PluginMetadata pomMetadata = new PomVisitor().reduce(tree, pluginMetadata); + PluginMetadata pomMetadata = new PomResolutionVisitor().reduce(tree, pluginMetadata); LOG.debug("POM metadata: {}", JsonUtils.toJson(pomMetadata)); executionContext.putMessage("pomMetadata", pomMetadata); // Is there better than context messaging ? return tree; diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/PomVisitor.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/PomResolutionVisitor.java similarity index 82% rename from plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/PomVisitor.java rename to plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/PomResolutionVisitor.java index 5bf913cf..7cd68908 100644 --- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/PomVisitor.java +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/PomResolutionVisitor.java @@ -12,13 +12,24 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class PomVisitor extends MavenIsoVisitor { +/** + * A pom visitor that accumulate PluginMetadata using maven resolution result. + * Maven resolution might not get updated if the tree is modified by other visitor + * So it's best used in preconditons recipes to avoid side effect + * An other implementation of this visitor could be extraction from the tree instead of maven resolution result + */ +public class PomResolutionVisitor extends MavenIsoVisitor { - private static final Logger LOG = LoggerFactory.getLogger(PomVisitor.class); + /** + * LOGGER. + */ + private static final Logger LOG = LoggerFactory.getLogger(PomResolutionVisitor.class); @Override public Xml.Document visitDocument(Xml.Document document, PluginMetadata pluginMetadata) { + document = super.visitDocument(document, pluginMetadata); + Markers markers = getCursor().firstEnclosingOrThrow(Xml.Document.class).getMarkers(); // Ensure maven resolution result is present diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/recipes/IsMissingBom.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/recipes/IsMissingBom.java index 62b5e77b..ea01e9b2 100644 --- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/recipes/IsMissingBom.java +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/recipes/IsMissingBom.java @@ -1,7 +1,7 @@ package io.jenkins.tools.pluginmodernizer.core.recipes; import io.jenkins.tools.pluginmodernizer.core.extractor.PluginMetadata; -import io.jenkins.tools.pluginmodernizer.core.extractor.PomVisitor; +import io.jenkins.tools.pluginmodernizer.core.extractor.PomResolutionVisitor; import org.openrewrite.ExecutionContext; import org.openrewrite.Recipe; import org.openrewrite.TreeVisitor; @@ -37,7 +37,7 @@ public TreeVisitor getVisitor() { @Override public Xml.Document visitDocument(Xml.Document document, ExecutionContext ctx) { - PluginMetadata pluginMetadata = new PomVisitor().reduce(document, new PluginMetadata()); + PluginMetadata pluginMetadata = new PomResolutionVisitor().reduce(document, new PluginMetadata()); if (pluginMetadata.getBomVersion() == null) { LOG.info("Project is missing Jenkins BOM"); diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/recipes/IsMissingJenkinsBaselineProperty.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/recipes/IsMissingJenkinsBaselineProperty.java index 0b71fd0e..aaf952ea 100644 --- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/recipes/IsMissingJenkinsBaselineProperty.java +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/recipes/IsMissingJenkinsBaselineProperty.java @@ -1,7 +1,7 @@ package io.jenkins.tools.pluginmodernizer.core.recipes; import io.jenkins.tools.pluginmodernizer.core.extractor.PluginMetadata; -import io.jenkins.tools.pluginmodernizer.core.extractor.PomVisitor; +import io.jenkins.tools.pluginmodernizer.core.extractor.PomResolutionVisitor; import org.openrewrite.ExecutionContext; import org.openrewrite.Recipe; import org.openrewrite.TreeVisitor; @@ -37,7 +37,7 @@ public TreeVisitor getVisitor() { @Override public Xml.Document visitDocument(Xml.Document document, ExecutionContext ctx) { - PluginMetadata pluginMetadata = new PomVisitor().reduce(document, new PluginMetadata()); + PluginMetadata pluginMetadata = new PomResolutionVisitor().reduce(document, new PluginMetadata()); if (!pluginMetadata.getProperties().containsKey("jenkins.baseline")) { LOG.info("Project is missing jenkins.baseline property"); diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/recipes/IsUsingBom.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/recipes/IsUsingBom.java index 2b3f05a5..589dc684 100644 --- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/recipes/IsUsingBom.java +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/recipes/IsUsingBom.java @@ -1,7 +1,7 @@ package io.jenkins.tools.pluginmodernizer.core.recipes; import io.jenkins.tools.pluginmodernizer.core.extractor.PluginMetadata; -import io.jenkins.tools.pluginmodernizer.core.extractor.PomVisitor; +import io.jenkins.tools.pluginmodernizer.core.extractor.PomResolutionVisitor; import org.openrewrite.ExecutionContext; import org.openrewrite.Recipe; import org.openrewrite.TreeVisitor; @@ -37,7 +37,7 @@ public TreeVisitor getVisitor() { @Override public Xml.Document visitDocument(Xml.Document document, ExecutionContext ctx) { - PluginMetadata pluginMetadata = new PomVisitor().reduce(document, new PluginMetadata()); + PluginMetadata pluginMetadata = new PomResolutionVisitor().reduce(document, new PluginMetadata()); if (pluginMetadata.getBomVersion() != null) { LOG.info("Project is using Jenkins bom at version {}", pluginMetadata.getBomVersion()); diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/recipes/MigrateToJenkinsBaseLineProperty.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/recipes/MigrateToJenkinsBaseLineProperty.java index a611f146..75130a07 100644 --- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/recipes/MigrateToJenkinsBaseLineProperty.java +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/recipes/MigrateToJenkinsBaseLineProperty.java @@ -1,31 +1,40 @@ package io.jenkins.tools.pluginmodernizer.core.recipes; import io.jenkins.tools.pluginmodernizer.core.extractor.PluginMetadata; -import io.jenkins.tools.pluginmodernizer.core.extractor.PomVisitor; +import io.jenkins.tools.pluginmodernizer.core.extractor.PomResolutionVisitor; import io.jenkins.tools.pluginmodernizer.core.visitors.AddBeforePropertyVisitor; import io.jenkins.tools.pluginmodernizer.core.visitors.AddPropertyCommentVisitor; import org.jspecify.annotations.Nullable; import org.openrewrite.*; import org.openrewrite.Cursor; import org.openrewrite.maven.AddPropertyVisitor; +import org.openrewrite.maven.ChangeManagedDependencyGroupIdAndArtifactId; import org.openrewrite.maven.MavenIsoVisitor; -import org.openrewrite.xml.ChangeTagValueVisitor; import org.openrewrite.xml.tree.Xml; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * A recipe to migrate the pom.xml to use the jenkins.baseLine property. + * Doesn't upgrade the jenkins version or bom version. + * If the plugin is not using the bom or using the weekly baseline, it will skip the update. + * This will also fix the bom version if it doesn't match the jenkins.version. + */ public class MigrateToJenkinsBaseLineProperty extends Recipe { + /** + * Logger for the class. + */ public static final Logger LOG = LoggerFactory.getLogger(MigrateToJenkinsBaseLineProperty.class); @Override public String getDisplayName() { - return "Migrate to Jenkins baseline property"; + return "Update the pom.xml to use newly introduced jenkins.baseline property"; } @Override public String getDescription() { - return "Migrate to Jenkins baseline property."; + return "Update the pom.xml to use newly introduced jenkins.baseline property."; } @Override @@ -47,8 +56,8 @@ private static class MigrateToJenkinsBaseLinePropertyVisitor extends MavenIsoVis public Xml.Document visitDocument(Xml.Document document, ExecutionContext ctx) { Xml.Document d = super.visitDocument(document, ctx); - // Skip if not bom or weekly bom - PluginMetadata pluginMetadata = new PomVisitor().reduce(document, new PluginMetadata()); + // Skip if not using bom or using weekly baseline + PluginMetadata pluginMetadata = new PomResolutionVisitor().reduce(document, new PluginMetadata()); if (pluginMetadata.getBomArtifactId() == null || "bom-weekly".equals(pluginMetadata.getBomArtifactId())) { LOG.debug("Project is using Jenkins weekly bom or not bom, skipping"); return d; @@ -58,6 +67,10 @@ public Xml.Document visitDocument(Xml.Document document, ExecutionContext ctx) { return document; } + /** + * Perform the update. + * @param document The document to update. + */ private void performUpdate(Xml.Document document) { Xml.Tag jenkinsVersionTag = document.getRoot() @@ -71,7 +84,7 @@ private void performUpdate(Xml.Document document) { // Keep only major and minor and ignore patch version String jenkinsVersion = jenkinsVersionTag.getValue().get(); - String jenkinsBaseline = jenkinsVersionTag.getValue().get(); + String jenkinsBaseline = jenkinsVersion; String jenkinsPatch = null; // It's a LTS, extract patch @@ -102,20 +115,31 @@ private void performUpdate(Xml.Document document) { } // Change the bom artifact ID - Xml.Tag artifactIdTag = document.getRoot() + Xml.Tag bom = document.getRoot() .getChild("dependencyManagement") .flatMap(dm -> dm.getChild("dependencies")) .flatMap(deps -> deps.getChild("dependency")) .filter(dep -> dep.getChildValue("groupId") .map("io.jenkins.tools.bom"::equals) .orElse(false)) - .flatMap(dep -> dep.getChild("artifactId")) .orElseThrow(); + Xml.Tag artifactIdTag = bom.getChild("artifactId").orElseThrow(); + Xml.Tag version = bom.getChild("version").orElseThrow(); + LOG.debug("Artifact ID is {}", artifactIdTag.getValue().get()); + LOG.debug("Version is {}", version.getValue().get()); + // Change the artifact and perform upgrade if (!artifactIdTag.getValue().get().equals("bom-${jenkins.baseline}.x")) { - doAfterVisit(new ChangeTagValueVisitor<>(artifactIdTag, "bom-${jenkins.baseline}.x")); + doAfterVisit(new ChangeManagedDependencyGroupIdAndArtifactId( + "io.jenkins.tools.bom", + artifactIdTag.getValue().get(), + "io.jenkins.tools.bom", + "bom-${jenkins.baseline}.x", + version.getValue().get(), + "\\.v[a-f0-9_]+") + .getVisitor()); } } } diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/recipes/UpdateBom.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/recipes/UpdateBom.java new file mode 100644 index 00000000..5b398f6a --- /dev/null +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/recipes/UpdateBom.java @@ -0,0 +1,26 @@ +package io.jenkins.tools.pluginmodernizer.core.recipes; + +import io.jenkins.tools.pluginmodernizer.core.visitors.UpdateBomVersionVisitor; +import org.openrewrite.*; +import org.openrewrite.maven.table.MavenMetadataFailures; + +/** + * A recipe that update the bom version to latest available. + */ +public class UpdateBom extends Recipe { + + @Override + public @NlsRewrite.DisplayName String getDisplayName() { + return "Update bom recipe"; + } + + @Override + public @NlsRewrite.Description String getDescription() { + return "Update bom recipe."; + } + + @Override + public TreeVisitor getVisitor() { + return Preconditions.check(new IsUsingBom(), new UpdateBomVersionVisitor(new MavenMetadataFailures(this))); + } +} diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/recipes/UpgradeJenkinsVersion.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/recipes/UpgradeJenkinsVersion.java new file mode 100644 index 00000000..29d6017f --- /dev/null +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/recipes/UpgradeJenkinsVersion.java @@ -0,0 +1,61 @@ +package io.jenkins.tools.pluginmodernizer.core.recipes; + +import org.openrewrite.*; +import org.openrewrite.jenkins.UpgradeVersionProperty; +import org.openrewrite.maven.MavenIsoVisitor; +import org.openrewrite.xml.tree.Xml; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A recipe to upgrade the Jenkins version in the pom.xml. + * Take care of updating the bom or adding the bom if it's not present. + * Not changing anything if the version is already higher than the minimum version. + */ +public class UpgradeJenkinsVersion extends Recipe { + + /** + * LOGGER. + */ + private static final Logger LOG = LoggerFactory.getLogger(UpgradeJenkinsVersion.class); + + /** + * The minimum version. + */ + @Option(displayName = "Version", description = "The version.", example = "2.452.4") + String minimumVersion; + + /** + * Constructor. + * @param minimumVersion The minimum version. + */ + public UpgradeJenkinsVersion(String minimumVersion) { + this.minimumVersion = minimumVersion; + } + + @Override + public String getDisplayName() { + return "Upgrade Jenkins version"; + } + + @Override + public String getDescription() { + return "Upgrade Jenkins version."; + } + + @Override + public TreeVisitor getVisitor() { + return new MavenIsoVisitor<>() { + + @Override + public Xml.Document visitDocument(Xml.Document document, ExecutionContext ctx) { + + // Return another tree with jenkins version updated + document = (Xml.Document) new UpgradeVersionProperty("jenkins.version", minimumVersion) + .getVisitor() + .visitNonNull(document, ctx); + return (Xml.Document) new UpdateBom().getVisitor().visitNonNull(document, ctx); + } + }; + } +} diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/visitors/RemovePropertyCommentVisitor.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/visitors/RemovePropertyCommentVisitor.java index c737cc42..97be1ef5 100644 --- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/visitors/RemovePropertyCommentVisitor.java +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/visitors/RemovePropertyCommentVisitor.java @@ -7,10 +7,21 @@ import org.openrewrite.xml.tree.Content; import org.openrewrite.xml.tree.Xml; +/** + * A visitor that remove a comment from a property in a maven pom file. + * Only a comment with exact match will be removed inside the properties block. + */ public class RemovePropertyCommentVisitor extends MavenIsoVisitor { - private String comment; + /** + * The comment to remove. + */ + private final String comment; + /** + * Constructor of the visitor. + * @param comment The comment to remove. + */ public RemovePropertyCommentVisitor(String comment) { this.comment = comment; } @@ -20,7 +31,7 @@ public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext executionContext) { tag = super.visitTag(tag, executionContext); if (tag.getName().equals("properties")) { - List contents = new ArrayList<>(tag.getContent()); + List contents = new ArrayList<>(tag.getContent() != null ? tag.getContent() : List.of()); // Remove the comment if needed boolean containsComment = contents.stream() diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/visitors/UpdateBomVersionVisitor.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/visitors/UpdateBomVersionVisitor.java new file mode 100644 index 00000000..23a2ed87 --- /dev/null +++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/visitors/UpdateBomVersionVisitor.java @@ -0,0 +1,109 @@ +package io.jenkins.tools.pluginmodernizer.core.visitors; + +import org.openrewrite.ExecutionContext; +import org.openrewrite.maven.*; +import org.openrewrite.maven.table.MavenMetadataFailures; +import org.openrewrite.maven.trait.MavenDependency; +import org.openrewrite.semver.LatestRelease; +import org.openrewrite.semver.VersionComparator; +import org.openrewrite.xml.ChangeTagValueVisitor; +import org.openrewrite.xml.tree.Xml; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A visitor that updates the BOM version in a maven pom file. + */ +public class UpdateBomVersionVisitor extends MavenIsoVisitor { + + /** + * LOGGER. + */ + private static final Logger LOG = LoggerFactory.getLogger(UpdateBomVersionVisitor.class); + + private transient MavenMetadataFailures metadataFailures; + + /** + * Contructor + */ + public UpdateBomVersionVisitor(MavenMetadataFailures metadataFailures) { + this.metadataFailures = metadataFailures; + } + + @Override + public Xml.Document visitDocument(Xml.Document document, ExecutionContext ctx) { + document = super.visitDocument(document, ctx); + + // Resolve artifact id + Xml.Tag bomTag = getBomTag(document); + Xml.Tag versionTag = bomTag.getChild("version").orElseThrow(); + Xml.Tag getProperties = getProperties(document); + + String artifactId = + bomTag.getChild("artifactId").orElseThrow().getValue().orElseThrow(); + String version = bomTag.getChild("version").orElseThrow().getValue().orElseThrow(); + LOG.debug("Updating bom version from {} to latest.release", version); + if (artifactId.equals("bom-${jenkins.baseline}.x")) { + artifactId = + "bom-" + getProperties.getChildValue("jenkins.baseline").orElseThrow() + ".x"; + } + + String newBomVersionAvailable = findNewerBomVersion(artifactId, version, ctx); + if (newBomVersionAvailable == null) { + LOG.debug("No newer version available for {}", artifactId); + return document; + } + + return (Xml.Document) + new ChangeTagValueVisitor<>(versionTag, newBomVersionAvailable).visitNonNull(document, ctx); + } + + /** + * Find the newer bom version + * @param artifactId The artifact id + * @param currentVersion The current version + * @param ctx The execution context + * @return The newer bom version + */ + private String findNewerBomVersion(String artifactId, String currentVersion, ExecutionContext ctx) { + VersionComparator latestRelease = new LatestRelease("\\.v[a-f0-9_]+"); + try { + return MavenDependency.findNewerVersion( + "io.jenkins.tools.bom", + artifactId, + currentVersion, + getResolutionResult(), + metadataFailures, + latestRelease, + ctx); + } catch (MavenDownloadingException e) { + LOG.warn("Failed to download metadata for {}", artifactId, e); + return null; + } + } + + /** + * Get the bom tag from the document + * @param document The document + * @return The bom tag + */ + private Xml.Tag getBomTag(Xml.Document document) { + return document.getRoot() + .getChild("dependencyManagement") + .flatMap(dm -> dm.getChild("dependencies")) + .flatMap(deps -> deps.getChild("dependency")) + .filter(dep -> dep.getChildValue("groupId") + .map("io.jenkins.tools.bom"::equals) + .orElse(false)) + .orElseThrow(); + } + + /** + * Get the properties tag from the document + * @param document The document + * @return The properties tag + */ + private Xml.Tag getProperties(Xml.Document document) { + return document.getRoot().getChild("properties").orElseThrow(); + } +} 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 9e68c72b..bfb4a809 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 @@ -61,12 +61,21 @@ recipeList: groupId: org.jenkins-ci.plugins artifactId: plugin newVersion: 5.X - - org.openrewrite.jenkins.UpgradeVersionProperty: - key: jenkins.version + - io.jenkins.tools.pluginmodernizer.core.recipes.UpgradeJenkinsVersion: minimumVersion: 2.479.1 - org.openrewrite.java.ChangeType: oldFullyQualifiedTypeName: org.kohsuke.stapler.StaplerRequest newFullyQualifiedTypeName: org.kohsuke.stapler.StaplerRequest2 + - org.openrewrite.java.ChangeMethodName: + methodPattern: org.kohsuke.stapler.Stapler getCurrentRequest() + newMethodName: getCurrentRequest2 + - org.openrewrite.java.ChangeMethodName: + methodPattern: org.kohsuke.stapler.Stapler getCurrentResponse() + newMethodName: getCurrentResponse2 + - org.openrewrite.java.ChangePackage: + oldPackageName: javax.servlet + newPackageName: jakarta.servlet + recursive: false - io.jenkins.tools.pluginmodernizer.RemoveDependencyVersionOverride - org.openrewrite.maven.RemoveProperty: # Set by 5.x parent, ensure it's removed propertyName: maven.compiler.release @@ -79,11 +88,7 @@ tags: ['dependencies'] preconditions: - io.jenkins.tools.pluginmodernizer.core.recipes.IsUsingBom recipeList: - - org.openrewrite.maven.UpgradeDependencyVersion: - groupId: io.jenkins.tools.bom - artifactId: "bom-*" - newVersion: latest.release - versionPattern: "\\.v[a-f0-9_]+" + - io.jenkins.tools.pluginmodernizer.core.recipes.UpdateBom - io.jenkins.tools.pluginmodernizer.RemoveDependencyVersionOverride --- type: specs.openrewrite.org/v1beta/recipe @@ -283,11 +288,11 @@ tags: ['developer'] recipeList: - io.jenkins.tools.pluginmodernizer.MigrateToJenkinsBaseLineProperty - io.jenkins.tools.pluginmodernizer.UpgradeParentVersion - - org.openrewrite.jenkins.UpgradeVersionProperty: - key: jenkins.version + - io.jenkins.tools.pluginmodernizer.core.recipes.UpgradeJenkinsVersion: minimumVersion: 2.452.4 - io.jenkins.tools.pluginmodernizer.RemoveDependencyVersionOverride - io.jenkins.tools.pluginmodernizer.RemoveExtraMavenProperties + - io.jenkins.tools.pluginmodernizer.UpgradeBomVersion --- type: specs.openrewrite.org/v1beta/recipe name: io.jenkins.tools.pluginmodernizer.UpgradeToLatestJava11CoreVersion @@ -297,11 +302,11 @@ tags: ['developer'] recipeList: - io.jenkins.tools.pluginmodernizer.MigrateToJenkinsBaseLineProperty - io.jenkins.tools.pluginmodernizer.UpgradeParentVersion - - org.openrewrite.jenkins.UpgradeVersionProperty: - key: jenkins.version + - io.jenkins.tools.pluginmodernizer.core.recipes.UpgradeJenkinsVersion: minimumVersion: 2.462.3 - io.jenkins.tools.pluginmodernizer.RemoveDependencyVersionOverride - io.jenkins.tools.pluginmodernizer.RemoveExtraMavenProperties + - io.jenkins.tools.pluginmodernizer.UpgradeBomVersion --- type: specs.openrewrite.org/v1beta/recipe name: io.jenkins.tools.pluginmodernizer.UpgradeToJava17 diff --git a/plugin-modernizer-core/src/main/resources/versions.properties b/plugin-modernizer-core/src/main/resources/versions.properties index 77c00409..2c31b83b 100644 --- a/plugin-modernizer-core/src/main/resources/versions.properties +++ b/plugin-modernizer-core/src/main/resources/versions.properties @@ -1,5 +1,6 @@ openrewrite.maven.plugin.version = ${openrewrite.maven.plugin.version} jenkins.parent.version = 5.4 +bom.version = 3850.vb_c5319efa_e29 remediation.jenkins.minimum.version = 2.440.3 remediation.jenkins.plugin.parent.version = 4.51 remediation.bom.version = 3413.v0d896b_76a_30d 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 09c029ca..46c50a77 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,9 +1,15 @@ package io.jenkins.tools.pluginmodernizer.core.recipes; +import static org.openrewrite.java.Assertions.java; import static org.openrewrite.maven.Assertions.pomXml; import io.jenkins.tools.pluginmodernizer.core.config.Settings; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; import org.junit.jupiter.api.Test; +import org.openrewrite.java.JavaParser; import org.openrewrite.test.RewriteTest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -161,7 +167,7 @@ void upgradeToRecommendCoreVersionTestWithBaseline() { io.jenkins.tools.bom bom-${jenkins.baseline}.x - 3435.v238d66a_043fb_ + %s pom import @@ -180,7 +186,8 @@ void upgradeToRecommendCoreVersionTestWithBaseline() { - """)); + """ + .formatted(Settings.getBomVersion()))); } @Test @@ -258,7 +265,7 @@ void upgradeToUpgradeToLatestJava11CoreVersion() { io.jenkins.tools.bom bom-${jenkins.baseline}.x - 3435.v238d66a_043fb_ + %s pom import @@ -277,15 +284,38 @@ void upgradeToUpgradeToLatestJava11CoreVersion() { - """)); + """ + .formatted(Settings.getBomVersion()))); + } + + /** + * Collect rewrite test dependencies from target/openrewrite-classpath directory + * @return List of Path + * @throws Exception if an I/O error occurs + */ + private List collectRewriteTestDependencies() { + try { + List entries = Files.list(Path.of("target/openrewrite-classpath")) + .filter(p -> p.toString().endsWith(".jar")) + .toList(); + LOG.debug("Collected rewrite test dependencies: {}", entries); + return entries; + } catch (IOException e) { + throw new RuntimeException(e); + } } @Test void upgradeNextMajorParentVersionTest() { rewriteRun( - spec -> spec.recipeFromResource( - "/META-INF/rewrite/recipes.yml", - "io.jenkins.tools.pluginmodernizer.UpgradeNextMajorParentVersion"), + spec -> { + var parser = JavaParser.fromJavaVersion().logCompilationWarningsAndErrors(true); + collectRewriteTestDependencies().forEach(parser::addClasspathEntry); + spec.recipeFromResource( + "/META-INF/rewrite/recipes.yml", + "io.jenkins.tools.pluginmodernizer.UpgradeNextMajorParentVersion") + .parser(parser); + }, pomXml( """ @@ -352,7 +382,128 @@ void upgradeNextMajorParentVersionTest() { """ - .formatted(Settings.getJenkinsParentVersion()))); + .formatted(Settings.getJenkinsParentVersion())), + java( + """ + import javax.servlet.ServletException; + import org.kohsuke.stapler.Stapler; + import org.kohsuke.stapler.StaplerRequest; + + public class Foo { + public void foo() { + StaplerRequest req = Stapler.getCurrentRequest(); + } + } + """, + """ + import jakarta.servlet.ServletException; + import org.kohsuke.stapler.Stapler; + import org.kohsuke.stapler.StaplerRequest2; + + public class Foo { + public void foo() { + StaplerRequest2 req = Stapler.getCurrentRequest2(); + } + } + """)); + } + + @Test + void upgradeNextMajorParentVersionTestWithBom() { + rewriteRun( + spec -> spec.recipeFromResource( + "/META-INF/rewrite/recipes.yml", + "io.jenkins.tools.pluginmodernizer.UpgradeNextMajorParentVersion"), + pomXml( + """ + + + 4.0.0 + + org.jenkins-ci.plugins + plugin + 4.87 + + + io.jenkins.plugins + empty + 1.0.0-SNAPSHOT + hpi + Empty Plugin + + 2.440.3 + + + + + io.jenkins.tools.bom + bom-2.440.x + 3435.v238d66a_043fb_ + pom + import + + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + + """, + """ + + + 4.0.0 + + org.jenkins-ci.plugins + plugin + %s + + + io.jenkins.plugins + empty + 1.0.0-SNAPSHOT + hpi + Empty Plugin + + + 2.479 + ${jenkins.baseline}.1 + + + + + io.jenkins.tools.bom + bom-${jenkins.baseline}.x + %s + pom + import + + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + + """ + .formatted(Settings.getJenkinsParentVersion(), Settings.getBomVersion()))); } @Test @@ -378,7 +529,7 @@ void upgradeNextMajorParentVersionTestWithBaseline() { hpi Empty Plugin - 2.462 + 2.440 ${jenkins.baseline}.3 @@ -431,7 +582,7 @@ void upgradeNextMajorParentVersionTestWithBaseline() { io.jenkins.tools.bom bom-${jenkins.baseline}.x - 3435.v238d66a_043fb_ + %s pom import @@ -451,7 +602,7 @@ void upgradeNextMajorParentVersionTestWithBaseline() { """ - .formatted(Settings.getJenkinsParentVersion()))); + .formatted(Settings.getJenkinsParentVersion(), Settings.getBomVersion()))); } @Test diff --git a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/recipes/MigrateToJenkinsBaseLinePropertyTest.java b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/recipes/MigrateToJenkinsBaseLinePropertyTest.java index 8e263230..756243c8 100644 --- a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/recipes/MigrateToJenkinsBaseLinePropertyTest.java +++ b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/recipes/MigrateToJenkinsBaseLinePropertyTest.java @@ -5,6 +5,9 @@ import org.junit.jupiter.api.Test; import org.openrewrite.test.RewriteTest; +/** + * Test for {@link MigrateToJenkinsBaseLineProperty} + */ public class MigrateToJenkinsBaseLinePropertyTest implements RewriteTest { @Test diff --git a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/recipes/UpgradeJenkinsVersionTest.java b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/recipes/UpgradeJenkinsVersionTest.java new file mode 100644 index 00000000..69e100ba --- /dev/null +++ b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/recipes/UpgradeJenkinsVersionTest.java @@ -0,0 +1,351 @@ +package io.jenkins.tools.pluginmodernizer.core.recipes; + +import static org.openrewrite.maven.Assertions.pomXml; + +import io.jenkins.tools.pluginmodernizer.core.config.Settings; +import org.junit.jupiter.api.Test; +import org.openrewrite.test.RewriteTest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Test for {@link UpgradeJenkinsVersion}. + */ +public class UpgradeJenkinsVersionTest implements RewriteTest { + + private static final Logger LOG = LoggerFactory.getLogger(UpgradeJenkinsVersionTest.class); + + @Test + void testPerformUpgradeWithoutBom() { + rewriteRun( + spec -> spec.recipe(new UpgradeJenkinsVersion("2.452.4")), + pomXml( + """ + + + 4.0.0 + + org.jenkins-ci.plugins + plugin + 4.87 + + + io.jenkins.plugins + empty + 1.0.0-SNAPSHOT + hpi + Empty Plugin + + 2.440.3 + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + + """, + """ + + + 4.0.0 + + org.jenkins-ci.plugins + plugin + 4.87 + + + io.jenkins.plugins + empty + 1.0.0-SNAPSHOT + hpi + Empty Plugin + + 2.452.4 + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + + """)); + } + + @Test + void testPerformUpgradeWithBaselineWithoutBom() { + rewriteRun( + spec -> spec.recipe(new UpgradeJenkinsVersion("2.452.4")), + pomXml( + """ + + + 4.0.0 + + org.jenkins-ci.plugins + plugin + 4.87 + + + io.jenkins.plugins + empty + 1.0.0-SNAPSHOT + hpi + Empty Plugin + + 2.440 + ${jenkins.baseline}.3 + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + + """, + """ + + + 4.0.0 + + org.jenkins-ci.plugins + plugin + 4.87 + + + io.jenkins.plugins + empty + 1.0.0-SNAPSHOT + hpi + Empty Plugin + + 2.452 + ${jenkins.baseline}.4 + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + + """)); + } + + @Test + void testPerformUpgradeWithoutBaselineWithBomAndUpgradeBomIfDoesntExistsForNewJenkinsVersion() { + rewriteRun( + spec -> spec.recipe(new UpgradeJenkinsVersion("2.452.4")), + pomXml( + """ + + + 4.0.0 + + org.jenkins-ci.plugins + plugin + 4.87 + + + io.jenkins.plugins + empty + 1.0.0-SNAPSHOT + hpi + Empty Plugin + + 2.440.3 + + + + + io.jenkins.tools.bom + bom-2.440.x + 3435.v238d66a_043fb_ + pom + import + + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + + """, + """ + + + 4.0.0 + + org.jenkins-ci.plugins + plugin + 4.87 + + + io.jenkins.plugins + empty + 1.0.0-SNAPSHOT + hpi + Empty Plugin + + 2.452.4 + + + + + io.jenkins.tools.bom + bom-2.452.x + %s + pom + import + + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + + """ + .formatted(Settings.getBomVersion()))); + } + + @Test + void testPerformUpgradeWithBaselineWithBomAndUpgradeBomIfDoesntExistsForNewJenkinsVersion() { + rewriteRun( + spec -> spec.recipe(new UpgradeJenkinsVersion("2.452.4")), + pomXml( + """ + + + 4.0.0 + + org.jenkins-ci.plugins + plugin + 4.87 + + + io.jenkins.plugins + empty + 1.0.0-SNAPSHOT + hpi + Empty Plugin + + 2.440 + ${jenkins.baseline}.3 + + + + + io.jenkins.tools.bom + bom-2.440.x + 3435.v238d66a_043fb_ + pom + import + + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + + """, + """ + + + 4.0.0 + + org.jenkins-ci.plugins + plugin + 4.87 + + + io.jenkins.plugins + empty + 1.0.0-SNAPSHOT + hpi + Empty Plugin + + 2.452 + ${jenkins.baseline}.4 + + + + + io.jenkins.tools.bom + bom-${jenkins.baseline}.x + %s + pom + import + + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + + """ + .formatted(Settings.getBomVersion()))); + } +} diff --git a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/visitors/AddBeforePropertyTest.java b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/visitors/AddBeforePropertyTest.java index d37b3e61..856f902b 100644 --- a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/visitors/AddBeforePropertyTest.java +++ b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/visitors/AddBeforePropertyTest.java @@ -10,7 +10,7 @@ import org.openrewrite.xml.tree.Xml; /** - * A visitor that add a maven property before another property. + * Test for {@link AddBeforePropertyVisitor} */ public class AddBeforePropertyTest implements RewriteTest { diff --git a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/visitors/RemovePropertyCommentVisitorTest.java b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/visitors/RemovePropertyCommentVisitorTest.java index c28c1acf..aa91636d 100644 --- a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/visitors/RemovePropertyCommentVisitorTest.java +++ b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/visitors/RemovePropertyCommentVisitorTest.java @@ -10,7 +10,7 @@ import org.openrewrite.xml.tree.Xml; /** - * A visitor that remove a property comment. + * Test for {@link RemovePropertyCommentVisitor} */ public class RemovePropertyCommentVisitorTest implements RewriteTest { @@ -61,4 +61,86 @@ public Xml.Document visitDocument(Xml.Document x, ExecutionContext ctx) { """)); } + + @Test + void notChangesIfCommentIsNotMatching() { + rewriteRun( + spec -> spec.recipe(toRecipe(() -> new MavenIsoVisitor<>() { + @Override + public Xml.Document visitDocument(Xml.Document x, ExecutionContext ctx) { + doAfterVisit(new RemovePropertyCommentVisitor(" Comment 1 ")); + doAfterVisit(new RemovePropertyCommentVisitor(" Comment 2 ")); + return super.visitDocument(x, ctx); + } + })), + pomXml( + """ + + + 4.0.0 + io.jenkins.plugins + empty + 1.0.0-SNAPSHOT + hpi + Empty Plugin + + + + value + + 2.440 + + + """)); + } + + @Test + void noChangesIfEmptyProperties() { + rewriteRun( + spec -> spec.recipe(toRecipe(() -> new MavenIsoVisitor<>() { + @Override + public Xml.Document visitDocument(Xml.Document x, ExecutionContext ctx) { + doAfterVisit(new RemovePropertyCommentVisitor(" No property here ")); + return super.visitDocument(x, ctx); + } + })), + pomXml( + """ + + + 4.0.0 + io.jenkins.plugins + empty + 1.0.0-SNAPSHOT + hpi + Empty Plugin + + + + """)); + } + + @Test + void noChangesIfNoProperties() { + rewriteRun( + spec -> spec.recipe(toRecipe(() -> new MavenIsoVisitor<>() { + @Override + public Xml.Document visitDocument(Xml.Document x, ExecutionContext ctx) { + doAfterVisit(new RemovePropertyCommentVisitor(" No property here ")); + return super.visitDocument(x, ctx); + } + })), + pomXml( + """ + + + 4.0.0 + io.jenkins.plugins + empty + 1.0.0-SNAPSHOT + hpi + Empty Plugin + + """)); + } }