OpenRewrite: problem with custom Recipe and doAfterVisit method

784 Views Asked by At

I am trying to make a custom recipe with the following logic:

If I find a specific value for a property found in a yaml file, then I add a maven dependency to pom.xml.

In principle it seems to be an easy case, but I can't get it to work...

For this I have created the following recipe:

public class CustomRecipe extends Recipe {


  public CustomRecipe() {}


  @Override
  protected TreeVisitor<?, ExecutionContext> getSingleSourceApplicableTest() {
    return new HasSourcePath<>("**/application-*.yml");
  }

  @Override
  public YamlVisitor<ExecutionContext> getVisitor() {
    return new YamlIsoVisitor<ExecutionContext>() {
      @Override
      public Yaml.Mapping.Entry visitMappingEntry(final Yaml.Mapping.Entry entry, final ExecutionContext context) {
        final Yaml.Mapping.Entry e = super.visitMappingEntry(entry, context);
        if (e.getValue() instanceof Yaml.Scalar && ((Yaml.Scalar) e.getValue()).getValue().contains("ENC(")) {
          // if jasypt usage is found in a .yml file then the Jasypt starter is added to pom.xml.
          this.doAfterVisit(
              new AddDependency("com.google.guava", "guava", "29.X", null, null, null,
                  null, null, null, null, null));
        }
        return e;
      }
    };
  }

}

After correctly configuring the plugin in the final project to run the above recipe and running the mvn rewrite:run command in DEBUG mode I notice that the yaml visitor correctly runs through the yaml file properties, including finding the property value, and therefore the maven recipe AddDependency is added in the this.doAfterVisit(...) method.

However, the dependency is never added to the pom.xml of the project...

I'm new to OpenRewrite and maybe I'm not understanding correctly how to do this...

any ideas?

I am using:

  • maven 3.6.3
  • Open rewrite plugin: 4.23.0
  • Open rewrite: 7.22.0
2

There are 2 best solutions below

0
On

I seem to have found a way to do what I wanted to do:

Use doNext instead of doAfterVisit to glue the Recipe to add the Maven dependency. Also, some parameters were missing to add to the AddDependency recipe like version and ifOnlyUsing:

    @Override
    public YamlVisitor<ExecutionContext> getVisitor() {
      return new YamlIsoVisitor<ExecutionContext>() {
        @Override
        public Yaml.Mapping.Entry visitMappingEntry(final Yaml.Mapping.Entry entry, final ExecutionContext context) {
          final Yaml.Mapping.Entry e = super.visitMappingEntry(entry, context);
          if (e.getValue() instanceof Yaml.Scalar && ((Yaml.Scalar) e.getValue()).getValue().startsWith("ENC(")) {
            CustomRecipe.this.doNext(new AddDependency("com.google.guava", "guava",
                "29.X" , null, null, false, "org.junit.jupiter.api.*", null, null, false, null);
          }
          return e;
        }
      };
    }
0
On

After some research i was able to reproduce similar issue and after debugging and throughly following the documentation and github testcases of addDependency openrewrite, found that AddDependency needs one more extra field onlyIfUsing which is missing in your constructor.

onlyIfUsing usage:: As shown in below example link, if there is some import we are using in code, we check for such import to get the desired dependency added to pom.xml.

onlyIfUsing : "com.google.common.math.IntMath"

https://github.com/openrewrite/rewrite/blob/main/rewrite-maven/src/test/java/org/openrewrite/maven/AddDependencyTest.java