diff --git a/src/main/java/org/openrewrite/maven/AbstractRewriteDryRunMojo.java b/src/main/java/org/openrewrite/maven/AbstractRewriteDryRunMojo.java index ae2cd100..9e807ea3 100644 --- a/src/main/java/org/openrewrite/maven/AbstractRewriteDryRunMojo.java +++ b/src/main/java/org/openrewrite/maven/AbstractRewriteDryRunMojo.java @@ -49,12 +49,18 @@ public class AbstractRewriteDryRunMojo extends AbstractRewriteMojo { public void execute() throws MojoExecutionException { if (rewriteSkip) { getLog().info("Skipping execution"); + putState(State.SKIPPED); return; } + putState(State.TO_BE_PROCESSED); // If the plugin is configured to run over all projects (at the end of the build) only proceed if the plugin // is being run on the last project. - if (!runPerSubmodule && !isLastProjectInReactor()) { + if (!runPerSubmodule && !allProjectsMarked()) { + getLog().info("REWRITE: Delaying execution to the end of multi-module project for " + + project.getGroupId() + ":" + + project.getArtifactId()+ ":" + + project.getVersion()); return; } @@ -140,5 +146,6 @@ public void execute() throws MojoExecutionException { } else { getLog().info("Applying recipes would make no changes. No patch file generated."); } + putState(State.PROCESSED); } } diff --git a/src/main/java/org/openrewrite/maven/AbstractRewriteMojo.java b/src/main/java/org/openrewrite/maven/AbstractRewriteMojo.java index 214afa7c..041e7eaf 100644 --- a/src/main/java/org/openrewrite/maven/AbstractRewriteMojo.java +++ b/src/main/java/org/openrewrite/maven/AbstractRewriteMojo.java @@ -19,6 +19,7 @@ import org.apache.maven.artifact.DependencyResolutionRequiredException; import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; @@ -77,8 +78,31 @@ public abstract class AbstractRewriteMojo extends ConfigurableRewriteMojo { @Parameter(defaultValue = "${session}", readonly = true) protected MavenSession mavenSession; + @Parameter(defaultValue = "${plugin}", required = true, readonly = true) + protected PluginDescriptor pluginDescriptor; + private static final String RECIPE_NOT_FOUND_EXCEPTION_MSG = "Could not find recipe '%s' among available recipes"; + protected enum State { + SKIPPED, + PROCESSED, + TO_BE_PROCESSED + } + private static final String OPENREWRITE_PROCESSED_MARKER = "openrewrite.processed"; + + protected void putState(State state) { + getPluginContext().put(OPENREWRITE_PROCESSED_MARKER, state.name()); + } + + private boolean hasState(MavenProject project) { + Map pluginContext = mavenSession.getPluginContext(pluginDescriptor, project); + return pluginContext.containsKey(OPENREWRITE_PROCESSED_MARKER); + } + + protected boolean allProjectsMarked() { + return mavenSession.getProjects().stream().allMatch(this::hasState); + } + protected Environment environment() throws MojoExecutionException { return environment(getRecipeArtifactCoordinatesClassloader()); } @@ -118,26 +142,6 @@ Config getConfig() throws IOException { return null; } - /** - * Is this project the last project in the reactor? - * - * @return true if last project (including only project) - */ - protected boolean isLastProjectInReactor() { - List sortedProjects = mavenSession.getProjectDependencyGraph().getSortedProjects(); - - MavenProject lastProject = sortedProjects.isEmpty() - ? mavenSession.getCurrentProject() - : sortedProjects.get(sortedProjects.size() - 1); - - if (getLog().isDebugEnabled()) { - getLog().debug("Current project: '" + mavenSession.getCurrentProject().getName() + - "', Last project to execute based on dependency graph: '" + lastProject.getName() + "'"); - } - - return mavenSession.getCurrentProject().equals(lastProject); - } - protected Environment environment(@Nullable ClassLoader recipeClassLoader) throws MojoExecutionException { Environment.Builder env = Environment.builder(project.getProperties()); if (recipeClassLoader == null) { diff --git a/src/main/java/org/openrewrite/maven/AbstractRewriteRunMojo.java b/src/main/java/org/openrewrite/maven/AbstractRewriteRunMojo.java index fa5829fe..0974172d 100644 --- a/src/main/java/org/openrewrite/maven/AbstractRewriteRunMojo.java +++ b/src/main/java/org/openrewrite/maven/AbstractRewriteRunMojo.java @@ -40,12 +40,18 @@ public class AbstractRewriteRunMojo extends AbstractRewriteMojo { public void execute() throws MojoExecutionException { if (rewriteSkip) { getLog().info("Skipping execution"); + putState(State.SKIPPED); return; } + putState(State.TO_BE_PROCESSED); // If the plugin is configured to run over all projects (at the end of the build) only proceed if the plugin // is being run on the last project. - if (!runPerSubmodule && !isLastProjectInReactor()) { + if (!runPerSubmodule && !allProjectsMarked()) { + getLog().info("REWRITE: Delaying execution to the end of multi-module project for " + + project.getGroupId() + ":" + + project.getArtifactId()+ ":" + + project.getVersion()); return; } @@ -150,6 +156,7 @@ public void execute() throws MojoExecutionException { throw new RuntimeException("Unable to rewrite source files", e); } } + putState(State.PROCESSED); } private static void writeAfter(Path root, Result result, ExecutionContext ctx) { diff --git a/src/test/java/org/openrewrite/maven/RewriteRunParallelIT.java b/src/test/java/org/openrewrite/maven/RewriteRunParallelIT.java new file mode 100644 index 00000000..885b36d0 --- /dev/null +++ b/src/test/java/org/openrewrite/maven/RewriteRunParallelIT.java @@ -0,0 +1,48 @@ +/* + * Copyright 2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.maven; + +import com.soebes.itf.jupiter.extension.*; +import com.soebes.itf.jupiter.maven.MavenExecutionResult; +import org.junit.jupiter.api.condition.DisabledOnOs; +import org.junit.jupiter.api.condition.OS; + +import static com.soebes.itf.extension.assertj.MavenITAssertions.assertThat; + +@MavenJupiterExtension +@MavenOption(value = MavenCLIOptions.THREADS, parameter = "2") +@MavenOption(MavenCLIOptions.NO_TRANSFER_PROGRESS) +@MavenOption(MavenCLIExtra.MUTE_PLUGIN_VALIDATION_WARNING) +@DisabledOnOs(OS.WINDOWS) +@MavenGoal("${project.groupId}:${project.artifactId}:${project.version}:run") +@SuppressWarnings("NewClassNamingConvention") +class RewriteRunParallelIT { + + @MavenTest + void multi_module_project(MavenExecutionResult result) { + assertThat(result) + .isSuccessful() + .out() + .info() + .anySatisfy(line -> assertThat(line).contains("Delaying execution to the end of multi-module project for org.openrewrite.maven:b:1.0")); + + assertThat(result) + .isSuccessful() + .out() + .warn() + .anySatisfy(line -> assertThat(line).contains("org.openrewrite.staticanalysis.SimplifyBooleanExpression")); + } +} diff --git a/src/test/resources-its/org/openrewrite/maven/RewriteRunParallelIT/multi_module_project/a/pom.xml b/src/test/resources-its/org/openrewrite/maven/RewriteRunParallelIT/multi_module_project/a/pom.xml new file mode 100644 index 00000000..77fec72c --- /dev/null +++ b/src/test/resources-its/org/openrewrite/maven/RewriteRunParallelIT/multi_module_project/a/pom.xml @@ -0,0 +1,38 @@ + + + 4.0.0 + + + org.openrewrite.maven + multi_module_project + 1.0 + + + a + + + + + org.apache.maven.plugins + maven-antrun-plugin + 3.0.0 + + + simulate-sleep + validate + + run + + + + + + + + + + + + + diff --git a/src/test/resources-its/org/openrewrite/maven/RewriteRunParallelIT/multi_module_project/a/src/main/java/sample/MyInterface.java b/src/test/resources-its/org/openrewrite/maven/RewriteRunParallelIT/multi_module_project/a/src/main/java/sample/MyInterface.java new file mode 100644 index 00000000..10bfc7aa --- /dev/null +++ b/src/test/resources-its/org/openrewrite/maven/RewriteRunParallelIT/multi_module_project/a/src/main/java/sample/MyInterface.java @@ -0,0 +1,4 @@ +package sample; + +public interface MyInterface { +} diff --git a/src/test/resources-its/org/openrewrite/maven/RewriteRunParallelIT/multi_module_project/a/src/main/java/sample/SimplifyBooleanSample.java b/src/test/resources-its/org/openrewrite/maven/RewriteRunParallelIT/multi_module_project/a/src/main/java/sample/SimplifyBooleanSample.java new file mode 100644 index 00000000..6eed11ed --- /dev/null +++ b/src/test/resources-its/org/openrewrite/maven/RewriteRunParallelIT/multi_module_project/a/src/main/java/sample/SimplifyBooleanSample.java @@ -0,0 +1,20 @@ +package sample; + +public class SimplifyBooleanSample { + boolean ifNoElse() { + if (isOddMillis()) { + return true; + } + return false; + } + + static boolean isOddMillis() { + boolean even = System.currentTimeMillis() % 2 == 0; + if (even == true) { + return false; + } + else { + return true; + } + } +} \ No newline at end of file diff --git a/src/test/resources-its/org/openrewrite/maven/RewriteRunParallelIT/multi_module_project/b/pom.xml b/src/test/resources-its/org/openrewrite/maven/RewriteRunParallelIT/multi_module_project/b/pom.xml new file mode 100644 index 00000000..08d7b697 --- /dev/null +++ b/src/test/resources-its/org/openrewrite/maven/RewriteRunParallelIT/multi_module_project/b/pom.xml @@ -0,0 +1,14 @@ + + + 4.0.0 + + + org.openrewrite.maven + multi_module_project + 1.0 + + + b + + diff --git a/src/test/resources-its/org/openrewrite/maven/RewriteRunParallelIT/multi_module_project/b/src/main/java/sample/EmptyBlockSample.java b/src/test/resources-its/org/openrewrite/maven/RewriteRunParallelIT/multi_module_project/b/src/main/java/sample/EmptyBlockSample.java new file mode 100644 index 00000000..2bdf4c5a --- /dev/null +++ b/src/test/resources-its/org/openrewrite/maven/RewriteRunParallelIT/multi_module_project/b/src/main/java/sample/EmptyBlockSample.java @@ -0,0 +1,14 @@ +package sample; + +import java.util.Random; + +public class EmptyBlockSample { + int n = sideEffect(); + + static { + } + + int sideEffect() { + return new Random().nextInt(); + } +} diff --git a/src/test/resources-its/org/openrewrite/maven/RewriteRunParallelIT/multi_module_project/pom.xml b/src/test/resources-its/org/openrewrite/maven/RewriteRunParallelIT/multi_module_project/pom.xml new file mode 100644 index 00000000..426d8ad8 --- /dev/null +++ b/src/test/resources-its/org/openrewrite/maven/RewriteRunParallelIT/multi_module_project/pom.xml @@ -0,0 +1,46 @@ + + + 4.0.0 + + org.openrewrite.maven + multi_module_project + 1.0 + pom + + + a + b + + + + 1.8 + 1.8 + UTF-8 + + + + + + @project.groupId@ + @project.artifactId@ + @project.version@ + + + com.example.RewriteRunIT.CodeCleanup + + + ${maven.multiModuleProjectDirectory}/src/test/resources-its/org/openrewrite/maven/RewriteRunIT/multi_module_project/rewrite.yml + + + + + org.openrewrite.recipe + rewrite-static-analysis + 1.0.4 + + + + + + diff --git a/src/test/resources-its/org/openrewrite/maven/RewriteRunParallelIT/multi_module_project/rewrite.yml b/src/test/resources-its/org/openrewrite/maven/RewriteRunParallelIT/multi_module_project/rewrite.yml new file mode 100644 index 00000000..78026180 --- /dev/null +++ b/src/test/resources-its/org/openrewrite/maven/RewriteRunParallelIT/multi_module_project/rewrite.yml @@ -0,0 +1,7 @@ +--- +type: specs.openrewrite.org/v1beta/recipe +name: com.example.RewriteRunIT.CodeCleanup +recipeList: + - org.openrewrite.staticanalysis.SimplifyBooleanExpression + - org.openrewrite.staticanalysis.SimplifyBooleanReturn + - org.openrewrite.staticanalysis.UnnecessaryParentheses