diff --git a/rewrite-maven/src/main/java/org/openrewrite/maven/AddAnnotationProcessor.java b/rewrite-maven/src/main/java/org/openrewrite/maven/AddAnnotationProcessor.java index fbc2644eb39..6bcac007942 100644 --- a/rewrite-maven/src/main/java/org/openrewrite/maven/AddAnnotationProcessor.java +++ b/rewrite-maven/src/main/java/org/openrewrite/maven/AddAnnotationProcessor.java @@ -28,6 +28,7 @@ import org.openrewrite.xml.tree.Xml; import java.util.List; +import java.util.concurrent.atomic.AtomicReference; import static org.openrewrite.maven.trait.Traits.mavenPlugin; @@ -49,7 +50,7 @@ public class AddAnnotationProcessor extends Recipe { @Option(displayName = "Version", description = "The third part of a coordinate 'org.projectlombok:lombok-mapstruct-binding:0.2.0' of the processor to add. " + - "Note that an exact version is expected", + "Note that an exact version is expected", example = "0.2.0") String version; @@ -61,8 +62,8 @@ public String getDisplayName() { @Override public String getDescription() { return "Add an annotation processor to the maven compiler plugin. Will not do anything if it already exists. " + - "Also doesn't add anything when no other annotation processors are defined yet. " + - "(Perhaps `ChangePluginConfiguration` can be used)."; + "Also doesn't add anything when no other annotation processors are defined yet. " + + "(Perhaps `ChangePluginConfiguration` can be used)."; } @Override @@ -73,8 +74,9 @@ public Xml visitTag(Xml.Tag tag, ExecutionContext ctx) { Xml.Tag plugins = (Xml.Tag) super.visitTag(tag, ctx); plugins = (Xml.Tag) mavenPlugin().asVisitor(plugin -> { if (MAVEN_COMPILER_PLUGIN_GROUP_ID.equals(plugin.getGroupId()) && - MAVEN_COMPILER_PLUGIN_ARTIFACT_ID.equals(plugin.getArtifactId())) { - return new XmlIsoVisitor() { + MAVEN_COMPILER_PLUGIN_ARTIFACT_ID.equals(plugin.getArtifactId())) { + AtomicReference> afterVisitor = new AtomicReference<>(); + Xml.Tag modifiedPlugin = new XmlIsoVisitor() { @Override public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) { Xml.Tag tg = super.visitTag(tag, ctx); @@ -82,14 +84,22 @@ public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) { for (int i = 0; i < tg.getChildren().size(); i++) { Xml.Tag child = tg.getChildren().get(i); if (groupId.equals(child.getChildValue("groupId").orElse(null)) && - artifactId.equals(child.getChildValue("artifactId").orElse(null))) { + artifactId.equals(child.getChildValue("artifactId").orElse(null))) { if (!version.equals(child.getChildValue("version").orElse(null))) { String oldVersion = child.getChildValue("version").orElse(""); - VersionComparator comparator = Semver.validate(oldVersion, null).getValue(); - if (comparator.compare(version, oldVersion) > 0) { - List tags = tg.getChildren(); - tags.set(i, child.withChildValue("version", version)); - return tg.withContent(tags); + boolean oldVersionUsesProperty = oldVersion.startsWith("${"); + String lookupVersion = oldVersionUsesProperty ? + getResolutionResult().getPom().getValue(oldVersion.trim()) : + oldVersion; + VersionComparator comparator = Semver.validate(lookupVersion, null).getValue(); + if (comparator.compare(version, lookupVersion) > 0) { + if (oldVersionUsesProperty) { + afterVisitor.set(new ChangePropertyValue(oldVersion, version, null, null).getVisitor()); + } else { + List tags = tg.getChildren(); + tags.set(i, child.withChildValue("version", version)); + return tg.withContent(tags); + } } } return tg; @@ -102,6 +112,10 @@ public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) { return tg; } }.visitTag(plugin.getTree(), ctx); + if (afterVisitor.get() != null) { + doAfterVisit(afterVisitor.get()); + } + return modifiedPlugin; } return plugin.getTree(); }).visitNonNull(plugins, 0); diff --git a/rewrite-maven/src/test/java/org/openrewrite/maven/AddAnnotationProcessorTest.java b/rewrite-maven/src/test/java/org/openrewrite/maven/AddAnnotationProcessorTest.java index b164cb28f98..851e394da5d 100644 --- a/rewrite-maven/src/test/java/org/openrewrite/maven/AddAnnotationProcessorTest.java +++ b/rewrite-maven/src/test/java/org/openrewrite/maven/AddAnnotationProcessorTest.java @@ -178,4 +178,111 @@ void shouldUpdateProcessorVersionAlreadyPresent() { ) ); } + + @Test + void addAnnotationWithOlderVersionAsMavenProperty() { + rewriteRun( + spec -> spec.recipe(new AddAnnotationProcessor( + "org.projectlombok", + "lombok-mapstruct-binding", + "0.2.0" + )), + pomXml( + """ + + 4.0.0 + com.mycompany.app + my-app + 1 + + 0.1.0 + + + + + maven-compiler-plugin + + + + org.projectlombok + lombok-mapstruct-binding + ${version.lombok.mapstruct.binding} + + + + + + + + """, + """ + + 4.0.0 + com.mycompany.app + my-app + 1 + + 0.2.0 + + + + + maven-compiler-plugin + + + + org.projectlombok + lombok-mapstruct-binding + ${version.lombok.mapstruct.binding} + + + + + + + + """ + ) + ); + } + + @Test + void addAnnotationWithSameVersionAsMavenProperty() { + rewriteRun( + spec -> spec.recipe(new AddAnnotationProcessor( + "org.projectlombok", + "lombok-mapstruct-binding", + "0.2.0" + )), + pomXml( + """ + + 4.0.0 + com.mycompany.app + my-app + 1 + + 0.2.0 + + + + + maven-compiler-plugin + + + + org.projectlombok + lombok-mapstruct-binding + ${version.lombok.mapstruct.binding} + + + + + + + + """ + ) + ); + } }