Skip to content

Commit da11c2b

Browse files
committed
Ensure that ExcludeDependency can complete its work within a single cycle even when there are multiple places an exclusion is called for
1 parent 80dbfb3 commit da11c2b

File tree

3 files changed

+24
-13
lines changed

3 files changed

+24
-13
lines changed

rewrite-core/src/main/java/org/openrewrite/Repeat.java

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
import org.jspecify.annotations.Nullable;
1919

20+
import java.util.function.Supplier;
21+
2022
public class Repeat {
2123

2224
/**
@@ -29,20 +31,25 @@ public static TreeVisitor<?, ExecutionContext> repeatUntilStable(TreeVisitor<?,
2931
return repeatUntilStable(v, 3);
3032
}
3133

34+
public static TreeVisitor<?, ExecutionContext> repeatUntilStable(Supplier<TreeVisitor<?, ExecutionContext>> v) {
35+
return repeatUntilStable(v, 3);
36+
}
37+
3238
/**
3339
* Returns a new visitor which runs the supplied visitor in a loop until no more changes are made, or the maximum
3440
* number of cycles is reached.
3541
* Convenient when a visitor is designed to recursively apply itself to a tree to achieve its desired result.
3642
* Stops early if the visitor ceases to make changes to the tree before the maximum number of cycles is reached.
3743
*/
3844
public static TreeVisitor<?, ExecutionContext> repeatUntilStable(TreeVisitor<?, ExecutionContext> v, int maxCycles) {
45+
return repeatUntilStable(() -> v, maxCycles);
46+
}
47+
48+
public static TreeVisitor<?, ExecutionContext> repeatUntilStable(Supplier<TreeVisitor<?, ExecutionContext>> vp, int maxCycles) {
3949
return new TreeVisitor<Tree, ExecutionContext>() {
50+
4051
@Override
4152
public @Nullable Tree visit(@Nullable Tree tree, ExecutionContext ctx) {
42-
if (tree instanceof SourceFile && !v.isAcceptable((SourceFile) tree, ctx)) {
43-
return tree;
44-
}
45-
4653
if (tree != null && !(tree instanceof SourceFile) && getCursor().isRoot()) {
4754
throw new IllegalArgumentException(
4855
String.format(
@@ -56,6 +63,10 @@ public static TreeVisitor<?, ExecutionContext> repeatUntilStable(TreeVisitor<?,
5663
Tree previous = tree;
5764
Tree current = null;
5865
for (int i = 0; i < maxCycles; i++) {
66+
TreeVisitor<?, ExecutionContext> v = vp.get();
67+
if (tree instanceof SourceFile && !v.isAcceptable((SourceFile) tree, ctx)) {
68+
return tree;
69+
}
5970
current = v.visit(previous, ctx);
6071
if (current == previous) {
6172
break;
@@ -68,13 +79,13 @@ public static TreeVisitor<?, ExecutionContext> repeatUntilStable(TreeVisitor<?,
6879

6980
@Override
7081
public @Nullable Tree visit(@Nullable Tree tree, ExecutionContext ctx, Cursor parent) {
71-
if (tree instanceof SourceFile && !v.isAcceptable((SourceFile) tree, ctx)) {
72-
return tree;
73-
}
74-
7582
Tree previous = tree;
7683
Tree current = null;
7784
for (int i = 0; i < maxCycles; i++) {
85+
final TreeVisitor<?, ExecutionContext> v = vp.get();
86+
if (tree instanceof SourceFile && !v.isAcceptable((SourceFile) tree, ctx)) {
87+
return tree;
88+
}
7889
current = v.visit(previous, ctx, parent);
7990
if (current == previous) {
8091
break;

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,15 +86,15 @@ public String getDescription() {
8686

8787
@Override
8888
public TreeVisitor<?, ExecutionContext> getVisitor() {
89-
return new MavenVisitor<ExecutionContext>() {
89+
return Repeat.repeatUntilStable(() -> new MavenVisitor<ExecutionContext>() {
9090
@Nullable
9191
private final Scope scope = ExcludeDependency.this.scope == null ? null : Scope.fromName(ExcludeDependency.this.scope);
9292

9393
@Override
9494
public Xml visitDocument(Xml.Document document, ExecutionContext ctx) {
9595
Xml xml = super.visitDocument(document, ctx);
9696
if (xml != document) {
97-
maybeUpdateModel();
97+
xml = new UpdateMavenModel<>().visitNonNull(xml, ctx);
9898
}
9999
return xml;
100100
}
@@ -120,6 +120,7 @@ public Xml visitTag(Xml.Tag tag, ExecutionContext ctx) {
120120
"<artifactId>" + artifactId + "</artifactId>\n" +
121121
"</exclusion>"))
122122
.visitNonNull(exclusions, ctx, getCursor());
123+
//noinspection unchecked
123124
tag = tag.withContent(ListUtils.map((List<Content>) tag.getContent(), t -> t == exclusions ? newExclusions : t));
124125
}
125126
} else {
@@ -137,6 +138,6 @@ public Xml visitTag(Xml.Tag tag, ExecutionContext ctx) {
137138
}
138139
return super.visitTag(tag, ctx);
139140
}
140-
};
141+
});
141142
}
142143
}

rewrite-maven/src/test/java/org/openrewrite/maven/ExcludeDependencyTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,7 @@ void respectTransitiveDependencyOriginalScopeWhenDeterminingIfExclusionIsNecessa
196196
@Test
197197
void excludeAlsoWhereConflictOmitted() {
198198
rewriteRun(
199-
spec -> spec.expectedCyclesThatMakeChanges(2)
200-
.recipe(new ExcludeDependency("org.apache.logging.log4j", "log4j-api", null)),
199+
spec -> spec.recipe(new ExcludeDependency("org.apache.logging.log4j", "log4j-api", null)),
201200
pomXml(
202201
"""
203202
<project>

0 commit comments

Comments
 (0)