diff --git a/rewrite-core/src/main/java/org/openrewrite/config/DeclarativeRecipe.java b/rewrite-core/src/main/java/org/openrewrite/config/DeclarativeRecipe.java index 150575a3217..0ecfab865fd 100644 --- a/rewrite-core/src/main/java/org/openrewrite/config/DeclarativeRecipe.java +++ b/rewrite-core/src/main/java/org/openrewrite/config/DeclarativeRecipe.java @@ -270,7 +270,7 @@ public final List getRecipeList() { getName() + " declares the ScanningRecipe " + precondition.getName() + " as a precondition." + "ScanningRecipe cannot be used as Preconditions."); } - andPreconditions.add(precondition::getVisitor); + andPreconditions.add(() -> orVisitors(precondition)); } PreconditionBellwether bellwether = new PreconditionBellwether(Preconditions.and(andPreconditions.toArray(new Supplier[]{}))); List recipeListWithBellwether = new ArrayList<>(recipeList.size() + 1); @@ -279,6 +279,16 @@ public final List getRecipeList() { return recipeListWithBellwether; } + private static TreeVisitor orVisitors(Recipe recipe) { + List> conditions = new ArrayList<>(); + conditions.add(recipe.getVisitor()); + for (Recipe r : recipe.getRecipeList()) { + conditions.add(orVisitors(r)); + } + //noinspection unchecked + return Preconditions.or(conditions.toArray(new TreeVisitor[0])); + } + private static boolean isScanningRecipe(Recipe recipe) { if (recipe instanceof ScanningRecipe) { return true; diff --git a/rewrite-core/src/test/java/org/openrewrite/config/DeclarativeRecipeTest.java b/rewrite-core/src/test/java/org/openrewrite/config/DeclarativeRecipeTest.java index a70b9c7701d..22f8f6ee263 100644 --- a/rewrite-core/src/test/java/org/openrewrite/config/DeclarativeRecipeTest.java +++ b/rewrite-core/src/test/java/org/openrewrite/config/DeclarativeRecipeTest.java @@ -174,6 +174,65 @@ void yamlPrecondition() { ); } + @Test + void yamlDeclarativeRecipeAsPrecondition() { + rewriteRun( + spec -> spec.recipeFromYaml( + """ + type: specs.openrewrite.org/v1beta/recipe + name: org.openrewrite.PreconditionTest + description: Test. + preconditions: + - org.openrewrite.DeclarativePrecondition + recipeList: + - org.openrewrite.text.ChangeText: + toText: 3 + --- + type: specs.openrewrite.org/v1beta/recipe + name: org.openrewrite.DeclarativePrecondition + recipeList: + - org.openrewrite.text.Find: + find: 1 + """, + "org.openrewrite.PreconditionTest" + ), + text("1", "3"), + text("2") + ); + } + + @Test + void orPreconditions() { + // As documented https://docs.openrewrite.org/reference/yaml-format-reference#creating-or-preconditions-instead-of-and + rewriteRun( + spec -> spec.recipeFromYaml( + """ + type: specs.openrewrite.org/v1beta/recipe + name: org.sample.DoSomething + description: Test. + preconditions: + - org.sample.FindAnyJson + recipeList: + - org.openrewrite.text.ChangeText: + toText: 2 + --- + type: specs.openrewrite.org/v1beta/recipe + name: org.sample.FindAnyJson + recipeList: + - org.openrewrite.FindSourceFiles: + filePattern: "**/my.json" + - org.openrewrite.FindSourceFiles: + filePattern: "**/your.json" + - org.openrewrite.FindSourceFiles: + filePattern: "**/our.json" + """, + "org.sample.DoSomething" + ), + text("1", "2", spec -> spec.path("a/my.json")), + text("a", spec -> spec.path("a/not-my.json")) + ); + } + @Test void yamlPreconditionWithScanningRecipe() { rewriteRun(