Skip to content

Commit

Permalink
Correctly override parent property to set Java version (#549)
Browse files Browse the repository at this point in the history
* Added test case for #523 Java version not detected in parent

* Partially revert "Only bring down properties from the parent that are referenced explicitly"

This partially reverts commit 12c8f37

* fix #523 restore behaviour of overriding properties from parent, but smartly

- only override numeric values
- if any property is detected, don't add maven.compiler.release

* Formatting from github-actions

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Apply formatter to minimize diff

* Fix failing UpgradeToJava17Test

Need to update the model because we are working with the resolved properties now, not the requested ones.

* Inline the optionals

* Simplify visitTag

* Inline pathToLocalParent variable and get propertyValue once

* Remove unused imports

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Tim te Beek <[email protected]>
  • Loading branch information
3 people authored Sep 21, 2024
1 parent 07542d2 commit 4f49e0c
Show file tree
Hide file tree
Showing 2 changed files with 191 additions and 96 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@
import org.openrewrite.TreeVisitor;
import org.openrewrite.maven.AddProperty;
import org.openrewrite.maven.MavenIsoVisitor;
import org.openrewrite.maven.tree.MavenResolutionResult;
import org.openrewrite.xml.XPathMatcher;
import org.openrewrite.xml.tree.Xml;

import java.util.*;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Value
Expand Down Expand Up @@ -73,13 +74,12 @@ public String getDescription() {
" * `maven.compiler.target`\n" +
" * `maven.compiler.release`\n" +
" * `release.version`\n\n" +
"If none of these properties are in use and the maven compiler plugin is not otherwise configured adds the `maven.compiler.release` property.";
"If none of these properties are in use and the maven compiler plugin is not otherwise configured, adds the `maven.compiler.release` property.";
}

@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
return new MavenIsoVisitor<ExecutionContext>() {
final Set<String> propertiesExplicitlyReferenced = new HashSet<>();
boolean compilerPluginConfiguredExplicitly;

@Override
Expand All @@ -88,93 +88,57 @@ public Xml.Document visitDocument(Xml.Document document, ExecutionContext ctx) {
Xml.Document d = super.visitDocument(document, ctx);

// Return early if the parent appears to be within the current repository, as properties defined there will be updated
Optional<String> pathToLocalParent = d.getRoot().getChild("parent")
if (d.getRoot().getChild("parent")
.flatMap(parent -> parent.getChild("relativePath"))
.flatMap(Xml.Tag::getValue);
if (pathToLocalParent.isPresent()) {
.flatMap(Xml.Tag::getValue)
.isPresent()) {
return d;
}

// Otherwise override remote parent's properties locally
MavenResolutionResult mrr = getResolutionResult();
Map<String, String> currentProperties = mrr.getPom().getRequested().getProperties();
Map<String, String> currentProperties = getResolutionResult().getPom().getProperties();
boolean foundProperty = false;
for (String property : JAVA_VERSION_PROPERTIES) {
if (currentProperties.containsKey(property) || !propertiesExplicitlyReferenced.contains(property)) {
continue;
String propertyValue = currentProperties.get(property);
if (propertyValue != null) {
foundProperty = true;
try {
if (Float.parseFloat(propertyValue) < version) {
d = (Xml.Document) new AddProperty(property, String.valueOf(version), null, false)
.getVisitor()
.visitNonNull(d, ctx);
maybeUpdateModel();
}
} catch (NumberFormatException ex) {
// either an expression or something else, don't touch
}
}
d = (Xml.Document) new AddProperty(property, String.valueOf(version), null, false)
.getVisitor()
.visitNonNull(d, ctx);
}

// When none of the relevant properties are explicitly configured Maven defaults to Java 8
// The release option was added in 9
// If no properties have yet been updated then set release explicitly
if (version >= 9 &&
!compilerPluginConfiguredExplicitly &&
currentProperties.keySet()
.stream()
.noneMatch(JAVA_VERSION_PROPERTIES::contains)) {
if (!foundProperty && version >= 9 && !compilerPluginConfiguredExplicitly) {
d = (Xml.Document) new AddProperty("maven.compiler.release", String.valueOf(version), null, false)
.getVisitor()
.visitNonNull(d, ctx);
HashMap<String, String> updatedProps = new HashMap<>(currentProperties);
updatedProps.put("maven.compiler.release", version.toString());
mrr = mrr.withPom(mrr.getPom().withRequested(mrr.getPom().getRequested().withProperties(updatedProps)));

d = d.withMarkers(d.getMarkers().setByType(mrr));
maybeUpdateModel();
}

return d;
}

@Override
public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) {
Xml.Tag t = super.visitTag(tag, ctx);
Optional<String> s = t.getValue()
.map(it -> it.replace("${", "").replace("}", "").trim())
.filter(JAVA_VERSION_PROPERTIES::contains);
if (s.isPresent()) {
propertiesExplicitlyReferenced.add(s.get());
} else if (JAVA_VERSION_XPATH_MATCHERS.stream().anyMatch(matcher -> matcher.matches(getCursor()))) {
Optional<Float> maybeVersion = t.getValue().flatMap(
value -> {
try {
return Optional.of(Float.parseFloat(value));
} catch (NumberFormatException e) {
return Optional.empty();
}
}
);

if (!maybeVersion.isPresent()) {
return t;
}
float currentVersion = maybeVersion.get();
if (currentVersion >= version) {
return t;
}
return t.withValue(String.valueOf(version));
} else if (PLUGINS_MATCHER.matches(getCursor())) {
Optional<Xml.Tag> maybeCompilerPlugin = t.getChildren().stream()
.filter(plugin ->
"plugin".equals(plugin.getName()) &&
"org.apache.maven.plugins".equals(plugin.getChildValue("groupId").orElse("org.apache.maven.plugins")) &&
"maven-compiler-plugin".equals(plugin.getChildValue("artifactId").orElse(null)))
.findAny();
Optional<Xml.Tag> maybeCompilerPluginConfig = maybeCompilerPlugin
.flatMap(it -> it.getChild("configuration"));
if (!maybeCompilerPluginConfig.isPresent()) {
return t;
}
Xml.Tag compilerPluginConfig = maybeCompilerPluginConfig.get();
Optional<String> source = compilerPluginConfig.getChildValue("source");
Optional<String> target = compilerPluginConfig.getChildValue("target");
Optional<String> release = compilerPluginConfig.getChildValue("release");
if (source.isPresent()
|| target.isPresent()
|| release.isPresent()) {
compilerPluginConfiguredExplicitly = true;
}
if (isPluginTag("org.apache.maven.plugins", "maven-compiler-plugin")) {
t.getChild("configuration").ifPresent(compilerPluginConfig -> {
if (compilerPluginConfig.getChildValue("source").isPresent() ||
compilerPluginConfig.getChildValue("target").isPresent() ||
compilerPluginConfig.getChildValue("release").isPresent()) {
compilerPluginConfiguredExplicitly = true;
}
});
}
return t;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,57 @@ void basic() {
<release.version>17</release.version>
</properties>
</project>
"""
)
);
}

@Test
void basicWithVariables() {
rewriteRun(
//language=xml
pomXml(
"""
<project>
<groupId>com.example</groupId>
<artifactId>foo</artifactId>
<version>1.0.0</version>
<modelVersion>4.0</modelVersion>
<properties>
<java.version>${release.version}</java.version>
<jdk.version>11</jdk.version>
<javaVersion>${release.version}</javaVersion>
<jdkVersion>${jdk.version}</jdkVersion>
<maven.compiler.source>${maven.compiler.release}</maven.compiler.source>
<maven.compiler.target>${maven.compiler.release}</maven.compiler.target>
<maven.compiler.release>11</maven.compiler.release>
<release.version>11</release.version>
</properties>
</project>
""",
"""
<project>
<groupId>com.example</groupId>
<artifactId>foo</artifactId>
<version>1.0.0</version>
<modelVersion>4.0</modelVersion>
<properties>
<java.version>${release.version}</java.version>
<jdk.version>17</jdk.version>
<javaVersion>${release.version}</javaVersion>
<jdkVersion>${jdk.version}</jdkVersion>
<maven.compiler.source>${maven.compiler.release}</maven.compiler.source>
<maven.compiler.target>${maven.compiler.release}</maven.compiler.target>
<maven.compiler.release>17</maven.compiler.release>
<release.version>17</release.version>
</properties>
</project>
""")
);
}

@Test
void bringsDownExplicitlyUsedPropertyFromRemoteParent() {
void overrideRemoteParent() {
rewriteRun(
//language=xml
pomXml(
Expand All @@ -103,7 +148,8 @@ void bringsDownExplicitlyUsedPropertyFromRemoteParent() {
SourceSpec::skip),
mavenProject("example-child",
//language=xml
pomXml("""
pomXml(
"""
<project>
<parent>
<groupId>com.example</groupId>
Expand All @@ -116,18 +162,6 @@ void bringsDownExplicitlyUsedPropertyFromRemoteParent() {
<artifactId>example-child</artifactId>
<version>1.0.0</version>
<modelVersion>4.0</modelVersion>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>${java.version}</release>
</configuration>
</plugin>
</plugins>
</build>
</project>
""",
"""
Expand All @@ -145,21 +179,49 @@ void bringsDownExplicitlyUsedPropertyFromRemoteParent() {
<modelVersion>4.0</modelVersion>
<properties>
<java.version>17</java.version>
<javaVersion>17</javaVersion>
<jdk.version>17</jdk.version>
<jdkVersion>17</jdkVersion>
<maven.compiler.release>17</maven.compiler.release>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<release.version>17</release.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>${java.version}</release>
</configuration>
</plugin>
</plugins>
</build>
</project>
""")
"""
)
)
);
}

@Test
void doNothingForExplicitPluginConfiguration() {
// Use UseMavenCompilerPluginReleaseConfiguration for this case
rewriteRun(
//language=xml
pomXml(
"""
<project>
<groupId>com.example</groupId>
<artifactId>example-child</artifactId>
<version>1.0.0</version>
<modelVersion>4.0</modelVersion>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>11</release>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
"""
)
);
}
Expand Down Expand Up @@ -192,4 +254,73 @@ void addReleaseIfNoOtherChangeIsMade() {
)
);
}

@Test
void springBoot3ParentToJava17() {
// Spring Boot Starter Parent already enforces Java 17
rewriteRun(
pomXml(
//language=xml
"""
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
</project>
"""
)
);
}

@Test
void springBoot3ParentToJava21() {
rewriteRun(
spec -> spec.recipe(new UpdateMavenProjectPropertyJavaVersion(21)),
pomXml(
//language=xml
"""
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
</project>
""",
//language=xml
"""
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<properties>
<java.version>21</java.version>
</properties>
</project>
"""
)
);
}
}

0 comments on commit 4f49e0c

Please sign in to comment.