如何将OpenRewrite YAML配方与自定义配方合并为单一可执行配方?
问题:整合OpenRewrite自定义Java配方与rewrite.yml配方,实现单Maven命令执行
我想创建一个包含自定义配方与rewrite.yml配方的OpenRewrite迁移jar,无需修改现有项目的pom,仅通过一行Maven命令执行(示例命令如下):
mvn -U org.openrewrite.maven:rewrite-maven-plugin:run \ -Drewrite.recipeArtifactCoordinates=com.myorg:rewrite-migrate:1.0.0 \ -Drewrite.activeRecipes=com.myorg.My1To2Migration
目前我已完成以下操作:
- 在jar的
src/main/resources/META-INF/rewrite.yml路径下放置了带自定义配置的标准配方 - 编写了自定义配方
My1To2Migration,其getRecipeList方法返回部分标准配方:
@Override public List<Recipe> getRecipeList() { return Arrays.asList( new ChangeType("com.myorg.OldType", "com.myorg.NewType", false) ); }
但现在执行时必须在命令行同时指定两个配方为activeRecipes,或在pom中配置。我想知道是否可以把rewrite.yml中的配方纳入自定义配方的getRecipeList方法中,这样仅需在Maven命令中指定My1To2Migration即可执行所有配方?比如类似如下伪代码的实现:
@Override public List<Recipe> getRecipeList() { return Arrays.asList( new ChangeType("com.myorg.OldType", "com.myorg.NewType", false), new RecipeFromYaml("rewrite.yml") ); }
或者有没有其他实现机制?
解决方案
方法1:在Java配方中加载rewrite.yml的配方
OpenRewrite提供了YamlRecipeLoader工具类,可以直接从classpath加载并解析rewrite.yml中的配方。你可以在自定义Java配方的getRecipeList方法中,加载rewrite.yml里的所有配方并合并到返回列表中。
修改后的My1To2Migration代码示例:
import org.openrewrite.config.YamlRecipeLoader; import org.openrewrite.Recipe; import java.util.ArrayList; import java.util.List; import java.io.InputStream; public class My1To2Migration extends Recipe { @Override public List<Recipe> getRecipeList() { // 初始化基础配方列表 List<Recipe> recipes = new ArrayList<>(); recipes.add(new ChangeType("com.myorg.OldType", "com.myorg.NewType", false)); // 加载rewrite.yml中的配方 try (InputStream yamlStream = getClass().getClassLoader().getResourceAsStream("META-INF/rewrite.yml")) { if (yamlStream != null) { List<Recipe> yamlRecipes = YamlRecipeLoader.load(yamlStream); recipes.addAll(yamlRecipes); } } catch (Exception e) { // 处理加载异常,比如打印日志或抛出运行时异常 throw new RuntimeException("Failed to load rewrite.yml recipes", e); } return recipes; } @Override public String getDisplayName() { return "My 1.x to 2.x Migration"; } @Override public String getDescription() { return "Combines custom Java recipes and YAML-defined recipes for 1.x to 2.x migration"; } }
这样,当你在命令行指定com.myorg.My1To2Migration为activeRecipe时,Java配方会自动加载并执行rewrite.yml里的所有配方,无需额外配置。
方法2:在rewrite.yml中引用自定义Java配方
如果更倾向于以YAML配方作为入口,你可以在rewrite.yml中直接引用自定义Java配方,将两者整合为一个组合配方:
--- type: specs.openrewrite.org/v1beta/recipe name: com.myorg.CombinedMigration displayName: Combined 1.x to 2.x Migration description: Combines YAML recipes and custom Java migration recipe recipeList: - com.myorg.My1To2Migration - # 这里添加rewrite.yml中原有的配方,比如: - org.openrewrite.java.ChangeType: oldFullyQualifiedTypeName: com.myorg.AnotherOldType newFullyQualifiedTypeName: com.myorg.AnotherNewType
此时,命令行只需指定com.myorg.CombinedMigration作为activeRecipe即可执行所有整合后的配方:
mvn -U org.openrewrite.maven:rewrite-maven-plugin:run \ -Drewrite.recipeArtifactCoordinates=com.myorg:rewrite-migrate:1.0.0 \ -Drewrite.activeRecipes=com.myorg.CombinedMigration
注意事项
- 确保rewrite.yml的格式符合OpenRewrite的YAML配方规范,路径
src/main/resources/META-INF/rewrite.yml正确,能被classpath加载到 - 使用
YamlRecipeLoader时,需处理IO异常,避免因配置文件加载失败导致迁移中断 - 两种方法都能实现单命令执行的需求,可根据团队习惯选择其中一种
内容的提问来源于stack exchange,提问作者JStefan
相关产品推荐
相关产品推荐

