Skip to content

Commit

Permalink
Add FindParseFailures#createdAfter option
Browse files Browse the repository at this point in the history
This option allows restricting the reporting to source files that were created after a given date.
  • Loading branch information
knutwannheden committed Jan 31, 2025
1 parent 9869097 commit 6f8e2ed
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 5 deletions.
41 changes: 39 additions & 2 deletions rewrite-core/src/main/java/org/openrewrite/FindParseFailures.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@
import lombok.EqualsAndHashCode;
import lombok.Value;
import org.jspecify.annotations.Nullable;
import org.openrewrite.marker.BuildMetadata;
import org.openrewrite.marker.DeserializationError;
import org.openrewrite.marker.Markup;
import org.openrewrite.table.ParseFailures;

import java.time.LocalDate;
import java.time.ZoneOffset;
import java.util.Objects;

@Value
Expand All @@ -48,6 +51,13 @@ public class FindParseFailures extends Recipe {
@Nullable
String stackTrace;

@Option(displayName = "Created after",
description = "Only report on source files that were created after this date.",
example = "2025-01-01",
required = false)
@Nullable
String createdAfter;

transient ParseFailures failures = new ParseFailures(this);

@Override
Expand All @@ -61,9 +71,36 @@ public String getDescription() {
"failures that can occur and prioritizing fixes according to the most common problems.";
}

@Override
public Validated<Object> validate() {
return super.validate().and(Validated.test("createdAfter", "Must be empty or a valid date of format yyyy-MM-dd", createdAfter, date -> {
if (date != null && !date.isEmpty()) {
try {
LocalDate.parse(date);
} catch (Exception e) {
return false;
}
}
return true;
}));
}

@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
return new TreeVisitor<Tree, ExecutionContext>() {
TreeVisitor<?, ExecutionContext> precondition = new TreeVisitor<Tree, ExecutionContext>() {
final long createdAfterEpoch = createdAfter == null ? -1L : LocalDate.parse(createdAfter).atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli();

@Override
public @Nullable Tree visit(@Nullable Tree tree, ExecutionContext ctx) {
return createdAfterEpoch == -1L || tree != null && tree.getMarkers().findFirst(BuildMetadata.class)
.map(BuildMetadata::getMetadata)
.map(m -> m.get("createdAt"))
.map(Long::parseLong)
.map(t -> t >= createdAfterEpoch)
.orElse(false) ? null : tree;
}
};
return Preconditions.check(precondition, new TreeVisitor<Tree, ExecutionContext>() {

@Override
public Tree postVisit(Tree tree, ExecutionContext ctx) {
Expand Down Expand Up @@ -117,6 +154,6 @@ private Tree report(Tree tree, ParseExceptionResult exceptionResult, ExecutionCo

return Markup.info(tree, exceptionResult.getMessage());
}
};
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,29 @@
package org.openrewrite;

import org.junit.jupiter.api.Test;
import org.openrewrite.marker.BuildMetadata;
import org.openrewrite.marker.Markers;
import org.openrewrite.table.ParseFailures;
import org.openrewrite.test.RecipeSpec;
import org.openrewrite.test.RewriteTest;
import org.openrewrite.text.PlainText;
import org.openrewrite.text.PlainTextParser;

import java.time.LocalDate;
import java.time.ZoneOffset;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static org.assertj.core.api.Assertions.assertThat;
import static org.openrewrite.Tree.randomId;
import static org.openrewrite.test.SourceSpecs.text;

class FindParseFailuresTest implements RewriteTest {

@Override
public void defaults(RecipeSpec spec) {
spec.recipe(new FindParseFailures(5, null, null));
spec.recipe(new FindParseFailures(5, null, null, null));
}

@Test
Expand All @@ -53,8 +59,53 @@ void findParseFailures() {
spec -> spec
.mapBeforeRecipe(pt -> pt
.withSnippets(List.of(new PlainText.Snippet(
Tree.randomId(),
new Markers(Tree.randomId(), List.of(per)),
randomId(),
new Markers(randomId(), List.of(per)),
pt.getText())))
.withText("")
)
)
);
}

@Test
void findParseFailuresAfter() {
long t0 = LocalDate.parse("2025-01-01").atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli();
long t1 = LocalDate.parse("2025-01-02").atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli();
ParseExceptionResult per = ParseExceptionResult.build(PlainTextParser.class, new RuntimeException("boom"), null);
rewriteRun(
spec -> spec.recipe(new FindParseFailures(5, null, null, "2025-01-02"))
.dataTable(ParseFailures.Row.class, rows -> {
assertThat(rows).hasSize(1);
ParseFailures.Row row = rows.get(0);
assertThat(row.getParser()).isEqualTo("PlainTextParser");
assertThat(row.getSourcePath()).isEqualTo("file1.txt");
assertThat(row.getExceptionType()).isEqualTo("RuntimeException");
assertThat(row.getSnippet()).isEqualTo("hello");
}),
text(
"hello world!",
spec -> spec
.path("file0.txt")
.mapBeforeRecipe(pt -> pt
.withMarkers(Markers.build(Set.of(new BuildMetadata(randomId(), Map.of("createdAt", Long.toString(t0))))))
.withSnippets(List.of(new PlainText.Snippet(
randomId(),
new Markers(randomId(), List.of(per)),
pt.getText())))
.withText("")
)
),
text(
"hello world!",
"~~(%s)~~>hello world!".formatted(per.getMessage()),
spec -> spec
.path("file1.txt")
.mapBeforeRecipe(pt -> pt
.withMarkers(Markers.build(Set.of(new BuildMetadata(randomId(), Map.of("createdAt", Long.toString(t1))))))
.withSnippets(List.of(new PlainText.Snippet(
randomId(),
new Markers(randomId(), List.of(per)),
pt.getText())))
.withText("")
)
Expand Down

0 comments on commit 6f8e2ed

Please sign in to comment.