From e9354016440e170c29029d80d944c304db18970f Mon Sep 17 00:00:00 2001 From: Laurens Westerlaken Date: Fri, 18 Oct 2024 00:21:29 +0200 Subject: [PATCH] `AddPlugin` now prefers to add plugins to the parent pom if it is in the same repository (#4583) --------- Co-authored-by: Sam Snyder --- .../java/org/openrewrite/maven/AddPlugin.java | 12 +- .../maven/tree/MavenResolutionResult.java | 19 ++- .../org/openrewrite/maven/AddPluginTest.java | 121 ++++++++++++++++++ 3 files changed, 149 insertions(+), 3 deletions(-) diff --git a/rewrite-maven/src/main/java/org/openrewrite/maven/AddPlugin.java b/rewrite-maven/src/main/java/org/openrewrite/maven/AddPlugin.java index 51eae9cbc73..c66349116ad 100644 --- a/rewrite-maven/src/main/java/org/openrewrite/maven/AddPlugin.java +++ b/rewrite-maven/src/main/java/org/openrewrite/maven/AddPlugin.java @@ -20,6 +20,7 @@ import org.intellij.lang.annotations.Language; import org.jspecify.annotations.Nullable; import org.openrewrite.*; +import org.openrewrite.maven.tree.MavenResolutionResult; import org.openrewrite.xml.AddToTagVisitor; import org.openrewrite.xml.ChangeTagValueVisitor; import org.openrewrite.xml.XPathMatcher; @@ -109,6 +110,12 @@ public boolean isAcceptable(SourceFile sourceFile, ExecutionContext ctx) { if (filePattern != null) { return PathUtils.matchesGlob(sourceFile.getSourcePath(), filePattern) && super.isAcceptable(sourceFile, ctx); } + + MavenResolutionResult mrr = sourceFile.getMarkers().findFirst(MavenResolutionResult.class).orElse(null); + if (mrr == null || mrr.parentPomIsProjectPom()) { + return false; + } + return super.isAcceptable(sourceFile, ctx); } @@ -129,7 +136,7 @@ public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) { if (BUILD_MATCHER.matches(getCursor())) { Optional maybePlugins = t.getChild("plugins"); Xml.Tag plugins; - if(maybePlugins.isPresent()) { + if (maybePlugins.isPresent()) { plugins = maybePlugins.get(); } else { t = (Xml.Tag) new AddToTagVisitor<>(t, Xml.Tag.build("")).visitNonNull(t, ctx, getCursor().getParentOrThrow()); @@ -153,7 +160,8 @@ public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) { } } } else { - Xml.Tag pluginTag = Xml.Tag.build("\n" + + Xml.Tag pluginTag = Xml.Tag.build( + "\n" + "" + groupId + "\n" + "" + artifactId + "\n" + (version != null ? "" + version + "\n" : "") + diff --git a/rewrite-maven/src/main/java/org/openrewrite/maven/tree/MavenResolutionResult.java b/rewrite-maven/src/main/java/org/openrewrite/maven/tree/MavenResolutionResult.java index d0bef4177b6..2530580ec43 100644 --- a/rewrite-maven/src/main/java/org/openrewrite/maven/tree/MavenResolutionResult.java +++ b/rewrite-maven/src/main/java/org/openrewrite/maven/tree/MavenResolutionResult.java @@ -30,6 +30,7 @@ import java.util.function.Predicate; import static java.util.Collections.emptyList; +import static java.util.Objects.requireNonNull; import static org.openrewrite.internal.StringUtils.matchesGlob; @SuppressWarnings("unused") @@ -192,8 +193,24 @@ public Map getProjectPoms() { return getProjectPomsRecursive(new HashMap<>()); } + /** + * Often recipes operating on multi-module projects will prefer to make changes to the parent pom rather than in multiple child poms. + * But if the parent isn't in the same repository as the child, the recipe would need to be applied to the child poms. + * + * @return true when the parent pom of the current pom is present in the same repository as the current pom + */ + public boolean parentPomIsProjectPom() { + if (getParent() == null) { + return false; + } + ResolvedGroupArtifactVersion parentGav = getParent().getPom().getGav(); + return getProjectPoms().values().stream() + .map(Pom::getGav) + .anyMatch(gav -> gav.equals(parentGav)); + } + private Map getProjectPomsRecursive(Map projectPoms) { - projectPoms.put(pom.getRequested().getSourcePath(), pom.getRequested()); + projectPoms.put(requireNonNull(pom.getRequested().getSourcePath()), pom.getRequested()); if (parent != null) { parent.getProjectPomsRecursive(projectPoms); } diff --git a/rewrite-maven/src/test/java/org/openrewrite/maven/AddPluginTest.java b/rewrite-maven/src/test/java/org/openrewrite/maven/AddPluginTest.java index fb3517169c0..3a909977fcc 100644 --- a/rewrite-maven/src/test/java/org/openrewrite/maven/AddPluginTest.java +++ b/rewrite-maven/src/test/java/org/openrewrite/maven/AddPluginTest.java @@ -20,6 +20,7 @@ import org.openrewrite.test.RecipeSpec; import org.openrewrite.test.RewriteTest; +import static org.openrewrite.java.Assertions.mavenProject; import static org.openrewrite.maven.Assertions.pomXml; class AddPluginTest implements RewriteTest { @@ -361,4 +362,124 @@ void addPluginWithExistingPlugin() { ) ); } + + @Test + void addPluginOnlyToRootPom() { + rewriteRun( + spec -> spec.recipe(new AddPlugin("org.springframework.boot", "spring-boot-maven-plugin", "3.1.5", null, null, null, null)), + pomXml( + """ + + com.mycompany.app + my-app + 1 + + + + + + """, + """ + + com.mycompany.app + my-app + 1 + + + + org.springframework.boot + spring-boot-maven-plugin + 3.1.5 + + + + + """, + spec -> spec.path("pom.xml") + ), + mavenProject("my-app-child", + pomXml( + """ + + com.mycompany.app + my-app-child + 1 + + com.mycompany.app + my-app + 1 + + + + + + + """)) + ); + } + + @Test + void addPluginOnlyToRootPomWithParent() { + rewriteRun( + spec -> spec.recipe(new AddPlugin("org.springframework.boot", "spring-boot-maven-plugin", "3.1.5", null, null, null, null)), + pomXml( + """ + + com.mycompany.app + my-app + 1 + + org.springframework.boot + spring-boot-starter-parent + 3.1.5 + + + + + + + """, + """ + + com.mycompany.app + my-app + 1 + + org.springframework.boot + spring-boot-starter-parent + 3.1.5 + + + + + org.springframework.boot + spring-boot-maven-plugin + 3.1.5 + + + + + """, + spec -> spec.path("pom.xml") + ), + mavenProject("my-app-child", + pomXml( + """ + + com.mycompany.app + my-app-child + 1 + + com.mycompany.app + my-app + 1 + + + + + + + """)) + ); + } }