You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 16:42:52