Skip to content

Commit e0d7e9a

Browse files
RemoveRedundantDependencyVersions recipe removes unused properties (#5645)
* RemoveRedundantDependencyVersions recipe removes unused properties if the recipe removes a version with said properties * More test * More test * More test * Parent pom test * Add scanning phase for RemoveUnusedProperties * Polish * Polish * Only replace properties for jar packaging * Polish * Support multiple properties removal * Update rewrite-maven/src/main/java/org/openrewrite/maven/RemoveRedundantDependencyVersions.java Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Update rewrite-core/src/main/java/org/openrewrite/internal/PropertyPlaceholderHelper.java Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Polish --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 4491ae6 commit e0d7e9a

4 files changed

Lines changed: 297 additions & 49 deletions

File tree

rewrite-core/src/main/java/org/openrewrite/internal/PropertyPlaceholderHelper.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020

2121
import java.util.*;
2222
import java.util.function.Function;
23+
import java.util.regex.Matcher;
24+
import java.util.regex.Pattern;
25+
26+
import static java.util.Collections.emptyList;
2327

2428
/**
2529
* Simplified from Spring's PropertyPlaceholderHelper.
@@ -29,6 +33,7 @@
2933
*/
3034
public class PropertyPlaceholderHelper {
3135
private static final Map<String, String> wellKnownSimplePrefixes = new HashMap<>(4);
36+
private static final Pattern PROPERTY_PATTERN = Pattern.compile("\\$\\{([^}]+)}");
3237

3338
static {
3439
wellKnownSimplePrefixes.put("}", "{");
@@ -66,6 +71,19 @@ public boolean hasPlaceholders(@Nullable String value) {
6671
return startIndex > -1 && value.indexOf(placeholderSuffix, startIndex) > startIndex;
6772
}
6873

74+
public List<String> getPlaceholders(@Nullable String value) {
75+
if (value == null) {
76+
return emptyList();
77+
}
78+
79+
List<String> placeholders = new ArrayList<>();
80+
Matcher matcher = PROPERTY_PATTERN.matcher(value);
81+
while (matcher.find()) {
82+
placeholders.add(matcher.group(1));
83+
}
84+
return placeholders;
85+
}
86+
6987
public String replacePlaceholders(String value, final Properties properties) {
7088
return replacePlaceholders(value, properties::getProperty);
7189
}

rewrite-maven/src/main/java/org/openrewrite/maven/MavenVisitor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ protected Xml.Tag changeChildTagValue(Xml.Tag tag, String childTagName, @Nullabl
335335

336336
@Contract("null -> false")
337337
protected boolean isProperty(@Nullable String value) {
338-
return value != null && value.startsWith("${") && !IMPLICITLY_DEFINED_VERSION_PROPERTIES.contains(value);
338+
return !IMPLICITLY_DEFINED_VERSION_PROPERTIES.contains(value) && ResolvedPom.placeholderHelper.hasPlaceholders(value);
339339
}
340340

341341
public @Nullable ResolvedDependency findDependency(Xml.Tag tag) {

rewrite-maven/src/main/java/org/openrewrite/maven/RemoveRedundantDependencyVersions.java

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.openrewrite.semver.LatestIntegration;
2929
import org.openrewrite.semver.Semver;
3030
import org.openrewrite.semver.VersionComparator;
31+
import org.openrewrite.xml.tree.Content;
3132
import org.openrewrite.xml.tree.Xml;
3233

3334
import java.util.*;
@@ -146,6 +147,7 @@ private Comparator determineComparator() {
146147

147148
@Override
148149
public TreeVisitor<?, ExecutionContext> getVisitor() {
150+
ArrayList<String> properties = new ArrayList<>();
149151
Comparator comparator = determineComparator();
150152
return new MavenIsoVisitor<ExecutionContext>() {
151153
@Override
@@ -154,6 +156,12 @@ public Xml.Document visitDocument(Xml.Document document, ExecutionContext ctx) {
154156
if (d != document) {
155157
d = (Xml.Document) new RemoveEmptyDependenciesTags().visitNonNull(d, ctx);
156158
d = (Xml.Document) new RemoveEmptyPluginsTags().visitNonNull(d, ctx);
159+
if (!properties.isEmpty() && "jar".equals(getResolutionResult().getPom().getPackaging())) {
160+
RemoveUnusedProperties removeUnusedProperties = new RemoveUnusedProperties("(" + String.join("|", properties) + ")");
161+
RemoveUnusedProperties.Accumulator acc = removeUnusedProperties.getInitialValue(ctx);
162+
removeUnusedProperties.getScanner(acc).visit(d, ctx);
163+
d = (Xml.Document) removeUnusedProperties.getVisitor(acc).visitNonNull(d, ctx);
164+
}
157165
if (comparator != Comparator.EQ) {
158166
maybeUpdateModel();
159167
}
@@ -171,7 +179,7 @@ public Xml.Document visitDocument(Xml.Document document, ExecutionContext ctx) {
171179
matchesVersion(d) &&
172180
isNotExcepted(d.getGroupId(), d.getArtifactId())) {
173181
Xml.Tag version = tag.getChild("version").orElse(null);
174-
return tag.withContent(ListUtils.map(tag.getContent(), c -> c == version ? null : c));
182+
return tag.withContent(withoutVersion(tag, version));
175183
}
176184
} else if (isManagedDependencyTag()) {
177185
ResolvedManagedDependency managed = findManagedDependency(tag);
@@ -200,19 +208,32 @@ public Xml.Document visitDocument(Xml.Document document, ExecutionContext ctx) {
200208
return null;
201209
}
202210
// some other element is also declared (executions, configuration, dependencies…), so just remove the version
203-
return tag.withContent(ListUtils.map(tag.getContent(), c -> c == version ? null : c));
211+
return tag.withContent(withoutVersion(tag, version));
204212
}
205213
} else {
206214
Plugin p = findPlugin(tag);
207215
if (p != null && matchesGroup(p) && matchesArtifact(p) && matchesVersion(p)) {
208216
Xml.Tag version = tag.getChild("version").orElse(null);
209-
return tag.withContent(ListUtils.map(tag.getContent(), c -> c == version ? null : c));
217+
return tag.withContent(withoutVersion(tag, version));
210218
}
211219
}
212220
}
213221
return super.visitTag(tag, ctx);
214222
}
215223

224+
private @Nullable List<? extends Content> withoutVersion(Xml.Tag tag, Xml.@Nullable Tag version) {
225+
return ListUtils.map(tag.getContent(), c -> {
226+
if (c == version) {
227+
Optional<String> value = ((Xml.Tag) c).getValue();
228+
if (value.isPresent() && isProperty(value.get())) {
229+
properties.addAll(ResolvedPom.placeholderHelper.getPlaceholders(value.get()));
230+
}
231+
return null;
232+
}
233+
return c;
234+
});
235+
}
236+
216237
private boolean matchesGroup(ResolvedManagedDependency d) {
217238
return StringUtils.isNullOrEmpty(groupPattern) || matchesGlob(d.getGroupId(), groupPattern);
218239
}

0 commit comments

Comments
 (0)