Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse Recipe results from OpenRewrite Maven plugin output #74

Open
fabapp2 opened this issue Mar 18, 2024 · 3 comments
Open

Parse Recipe results from OpenRewrite Maven plugin output #74

fabapp2 opened this issue Mar 18, 2024 · 3 comments
Assignees
Labels
enhancement New feature or request

Comments

@fabapp2
Copy link
Contributor

fabapp2 commented Mar 18, 2024

What needs to be done

The console output of OpenRewrite's Maven plugins should be parsed and made available.

The PluginInvoker implementation from #73 provides access to the output of the build.

PluginInvocationResult result = RewritePlugin.run()...
String output = result.capturedOutput();

The MAven plugin prints information about the recipes that were applied.
This is an example for the output of OR's Maven plugin:

[INFO] Running recipe(s)...
[WARNING] Changes have been made to complete/pom.xml by:
[WARNING]     org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_1
[WARNING]         org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_0
[WARNING]             org.openrewrite.java.spring.boot2.UpgradeSpringBoot_2_7
[WARNING]                 org.openrewrite.maven.UpgradeParentVersion: {groupId=org.springframework.boot, artifactId=spring-boot-starter-parent, newVersion=2.7.x}
[WARNING]             org.openrewrite.java.migrate.UpgradeToJava17
[WARNING]                 org.openrewrite.java.migrate.Java8toJava11
[WARNING]                     org.openrewrite.java.migrate.JavaVersion11
[WARNING]                         org.openrewrite.java.migrate.UpgradeJavaVersion: {version=11}
[WARNING]                 org.openrewrite.java.migrate.JavaVersion17
[WARNING]                     org.openrewrite.java.migrate.UpgradeJavaVersion: {version=17}
[WARNING]             org.openrewrite.maven.UpgradeParentVersion: {groupId=org.springframework.boot, artifactId=spring-boot-starter-parent, newVersion=3.0.x, retainVersions=[org.thymeleaf:thymeleaf-spring5, org.thymeleaf.extras:thymeleaf-extras-springsecurity5]}
[WARNING]         org.openrewrite.maven.UpgradeParentVersion: {groupId=org.springframework.boot, artifactId=spring-boot-starter-parent, newVersion=3.1.x}
[WARNING] Changes have been made to complete/src/main/java/com/example/accessingdatarest/Person.java by:
[WARNING]     org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_1
[WARNING]         org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_0
[WARNING]             org.openrewrite.java.migrate.UpgradeToJava17
[WARNING]                 org.openrewrite.java.migrate.Java8toJava11
[WARNING]                     org.openrewrite.java.migrate.JavaVersion11
[WARNING]                         org.openrewrite.java.migrate.UpgradeJavaVersion: {version=11}
[WARNING]                 org.openrewrite.java.migrate.JavaVersion17
[WARNING]                     org.openrewrite.java.migrate.UpgradeJavaVersion: {version=17}
[WARNING]             org.openrewrite.java.migrate.jakarta.JavaxMigrationToJakarta
[WARNING]                 org.openrewrite.java.migrate.jakarta.JavaxPersistenceToJakartaPersistence
[WARNING]                     org.openrewrite.java.ChangePackage: {oldPackageName=javax.persistence, newPackageName=jakarta.persistence, recursive=true}
[WARNING] Please review and commit the results.

A new component RewritePluginOutputParser should parse the output of OpenRewrite Maven plugin and provide an API to access the extracted information:

  • The recipes that were applied in the hierarchy retrieved from output
  • Recipe parameters, if any
  • The files affected by a recipe
PluginInvocationResult result = RewritePlugin.run()...
String out = result.capturedOutput();
parser = new RewritePluginOutputParser();
RecipeRunDetails details = parser.parseOutput(out);

List<Path> affected = details.getAffectedFiles();
// AppliedRecipe can have itself a list of AppliedRecipe and parameters
List<AppliedRecipe> appliedRecipes = details.getAppliedRecipes(); 
// ...

What's next

  • The parser should be extended to parse Gradle output too.
  • The return types of RewritePlugin implementations should provide access to the parsed data

The return types can be made specific to the executed plugin goals that provide an API to the build information extracted from the plugin output.
E.g.
PluginInvocationResult result = RewritePlugin.run()...
would become

RewritePluginRunResult result = RewritePlugin.run()...
appliedRecipes = result.getRecipesApplied();
affectedFiles = result.getAffectedFiles();
@fabapp2 fabapp2 added the enhancement New feature or request label Mar 18, 2024
@bsmahi
Copy link
Contributor

bsmahi commented Mar 19, 2024

@fabapp2 I will work on this, please assign it to me.

Thanks,
Mahi

@bsmahi
Copy link
Contributor

bsmahi commented Mar 28, 2024

@fabapp2 I need to create RewritePluginOutputParser in separately in spring-rewrite-commons-plugin-invoker-maven and spring-rewrite-commons-plugin-invoker-gradle or spring-rewrite-commons-plugin-invoker-polyglot?

Could you please confirm?

Thanks,
Mahi

@fabapp2
Copy link
Contributor Author

fabapp2 commented Apr 2, 2024

@fabapp2 I need to create RewritePluginOutputParser in separately in spring-rewrite-commons-plugin-invoker-maven and spring-rewrite-commons-plugin-invoker-gradle or spring-rewrite-commons-plugin-invoker-polyglot?

Could you please confirm?

Thanks, Mahi

Hi @bsmahi
That's correct.
I don't see the need for a PolyglotParser as it would use either RewriteGradlePluginOutputParser or RewriteMavenPluginOutputParser.

I didn't think much about the resulting data structure, but I it should allow to access the information provided in the concole output.

String consoleOutput = ...
RewriteMavenPluginOutputParser parser = ...
RewriteMavenPluginExecutionResult result = parser.parse(consoleOutput);

// was recipe run successful
boolean success = result.succeeded()
assertThat(success).isTrue();

// get changed files
List<ChangedResource> changedResources = result.getChangedResources();
assertThat(changedResources.get(0).getPath().toString()).isEqualTo("complete/pom.xml");
assertThat(changedResources.get(1).getPath().toString()).isEqualTo("complete/src/main/java/com/example/accessingdatarest/Person.java");

// get recipes that made changes to a file
assertThat(changedResources.get(0).getRecipesThatMadeChanges().stream().map(r -> r.getName()).toList()).containsExactly(
    "org.openrewrite.maven.UpgradeParentVersion".
    "org.openrewrite.java.migrate.UpgradeJavaVersion", // 11
    "org.openrewrite.java.migrate.UpgradeJavaVersion", // 17
    "org.openrewrite.maven.UpgradeParentVersion",  // 3.0.x
    "org.openrewrite.maven.UpgradeParentVersion". // 3.1.x
);

// details about recipe(s) that made changes:



List<AppliedRecipe> recipesThatMadeChanges = changedResources.get(1).getRecipesThatMadeChanges();
assertThat(recipesThatMadeChanges.get(1).getName()).isEqualTo("org.openrewrite.java.migrate.UpgradeJavaVersion");
assertThat(recipesThatMadeChanges.get(1).getParams()).hasSize(1);
assertThat(recipesThatMadeChanges.get(1).getParams()).contains("version")
assertThat(recipesThatMadeChanges.get(1).getParams().get("version")).isEqualTo(11);
assertThat(recipesThatMadeChanges.get(1).getParent().getName()).isEqualTo("org.openrewrite.java.migrate.JavaVersion11");

// get applied recipes
List<AppliedRecipe> appliedRecipes = result.getAppliedRecipes();
appliedRecipes.forEach(appliedRecipe -> {
    String recipeName = appliedRecipe.getName();
    List<ChangedResource> changedResources =  appliedRecipe.getChangedResources();
    changedResources.forEach(changedResource -> {
        assertThat(changedResource.getAppliedRecipes()).contains(appliedRecipe);
    });
});

Optional<AppliedRecipe> optUpgradeRecipe = result.getAppliedRecipe("org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_0");

assertThat(optUpgradeRecipe).isPresent();
AppliedRecipe upgradeRecipe = optUpgradeRecipe.get();
assertThat(upgradeRecipe.getChangedResources()).contains("complete/pom.xml", ""complete/src/main/java/com/example/accessingdatarest/Person.java");

So, we need a structure that allows navigating in both directions (recipes -> resources and resources -> recipes) and provides the hierarchy plus properties of the recipes.

Thoughts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants