openrewrite / rewrite-gradle-plugin

OpenRewrite's Gradle plugin.
Apache License 2.0
60 stars 37 forks source link

GradleProjectParser run method can only be executed once #283

Closed blipper closed 6 months ago

blipper commented 6 months ago

What version of OpenRewrite are you using?

I am using

How are you running OpenRewrite?

What is the smallest, simplest way to reproduce the problem?

@CompileStatic
class InsisterRewriteRunTask extends AbstractRewriteTask {
     public InsisterRewriteRunTask() {
        super();
        setGroup("rewrite");
        setDescription("Apply the active refactoring recipes");
     }

    @TaskAction
    def public void run() {
        logger.info("Hello!")
        RewriteExtension liveExtension = super.extension;
        List<String> activeRecipes = new ArrayList(liveExtension.getActiveRecipes());
        liveExtension.clearActiveRecipes();
        activeRecipes.each {
            logger.info("Running ${it}")
            liveExtension.clearActiveRecipes();
            liveExtension.activeRecipe(it)
            GradleProjectParser myGpp = getProjectParser()
            myGpp.run({throwable -> logger.info("Error during rewrite run", throwable)} as Consumer<Throwable>)
            myGpp.shutdownRewrite();
            this.@gpp = null;
        }
    }
}
Caused by: org.gradle.api.InvalidUserDataException: Cannot change hierarchy of dependency configuration ':rewriteimplementation' after it has been resolved.
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.preventIllegalMutation(DefaultConfiguration.java:1487)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.validateMutation(DefaultConfiguration.java:1459)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.extendsFrom(DefaultConfiguration.java:433)
        at org.openrewrite.gradle.isolated.DefaultProjectParser.parse(DefaultProjectParser.java:695)

https://github.com/openrewrite/rewrite-gradle-plugin/blob/v6.6.3/plugin/src/main/java/org/openrewrite/gradle/isolated/DefaultProjectParser.java#L693

                rewriteImplementation.extendsFrom(implementation);

calls extendsFrom to add the config

You cannot change the configuraiton after resolution.

What did you expect to see?

It should check by calling the getter version of https://docs.gradle.org/current/dsl/org.gradle.api.artifacts.Configuration.html#org.gradle.api.artifacts.Configuration:extendsFrom

What did you see instead?

What is the full stack trace of any errors you encountered?

Are you interested in [contributing a fix to OpenRewrite]

Yes

blipper commented 6 months ago

Added a fix in #284

timtebeek commented 6 months ago

Thanks for the immediate proposed fix! And good to see the context of how you're using this above as well. Any reason you're wanting to apply recipes one at a time versus all at once? I imagine the above would be slower to run, although I haven't checked.

blipper commented 6 months ago

The use case is large enterprise repos which have a state of having many errors at the beginning. I am building a bootstrap mode that will run each recipe at time, apply the fixes, run the build to verify and then commit. This allows very clear and single atomic commits doing own thing which also allows straightforward rollback if something breaks.

timtebeek commented 6 months ago

That's understandable, and thanks for sharing that background. Always good to know how a tool is used to help inform where we might be able to help. We did add a similar section to the frequently asked question just this week, but I trust you know what you're doing and are fine with the implications given your context.