From bde9f4880436f3e8160b98f6fbc9a7201704894e Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sun, 29 Sep 2019 21:49:26 -0700 Subject: [PATCH 1/5] All tasks are now created immediately, rather than in `project.afterEvaluate`, for easier management by other scripts. --- .../gradle/spotless/SpotlessExtension.java | 69 ++++++++++- .../gradle/spotless/SpotlessPlugin.java | 107 ++++-------------- .../gradle/spotless/SpotlessTask.java | 8 +- .../gradle/spotless/PaddedCellTaskTest.java | 4 +- .../diffplug/gradle/spotless/SelfTest.java | 1 - 5 files changed, 97 insertions(+), 92 deletions(-) diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java index a9b7e82eb1..f934ab06dd 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java @@ -26,15 +26,36 @@ import org.gradle.api.Action; import org.gradle.api.GradleException; import org.gradle.api.Project; +import org.gradle.api.Task; +import org.gradle.api.execution.TaskExecutionGraph; +import org.gradle.api.plugins.BasePlugin; import com.diffplug.common.base.Errors; import com.diffplug.spotless.LineEnding; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import groovy.lang.Closure; + public class SpotlessExtension { final Project project; + final Task rootCheckTask, rootApplyTask; + + static final String EXTENSION = "spotless"; + static final String CHECK = "Check"; + static final String APPLY = "Apply"; + + private static final String TASK_GROUP = "Verification"; + private static final String CHECK_DESCRIPTION = "Checks that sourcecode satisfies formatting steps."; + private static final String APPLY_DESCRIPTION = "Applies code formatting steps to sourcecode in-place."; public SpotlessExtension(Project project) { this.project = requireNonNull(project); + rootCheckTask = project.task(EXTENSION + CHECK); + rootCheckTask.setGroup(TASK_GROUP); + rootCheckTask.setDescription(CHECK_DESCRIPTION); + rootApplyTask = project.task(EXTENSION + APPLY); + rootApplyTask.setGroup(TASK_GROUP); + rootApplyTask.setDescription(APPLY_DESCRIPTION); } /** Line endings (if any). */ @@ -188,7 +209,7 @@ private void configure(String name, Class clazz, configure.execute(value); } - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked"}) private T maybeCreate(String name, Class clazz) { FormatExtension existing = formats.get(name); if (existing != null) { @@ -201,9 +222,10 @@ private T maybeCreate(String name, Class clazz) { } else { try { Constructor constructor = clazz.getConstructor(SpotlessExtension.class); - T newlyCreated = constructor.newInstance(this); - formats.put(name, newlyCreated); - return newlyCreated; + T formatExtension = constructor.newInstance(this); + formats.put(name, formatExtension); + createFormatTask(name, formatExtension); + return formatExtension; } catch (NoSuchMethodException e) { throw new GradleException("Must have a constructor " + clazz.getSimpleName() + "(SpotlessExtension root)", e); } catch (Exception e) { @@ -211,4 +233,43 @@ private T maybeCreate(String name, Class clazz) { } } } + + @SuppressWarnings("rawtypes") + private void createFormatTask(String name, FormatExtension formatExtension) { + // create the SpotlessTask + String taskName = EXTENSION + SpotlessPlugin.capitalize(name); + SpotlessTask spotlessTask = project.getTasks().create(taskName, SpotlessTask.class); + project.afterEvaluate(unused -> formatExtension.setupTask(spotlessTask)); + + // clean removes the SpotlessCache, so we have to run after clean + Task clean = project.getTasks().getByName(BasePlugin.CLEAN_TASK_NAME); + spotlessTask.mustRunAfter(clean); + + // create the check and apply control tasks + Task checkTask = project.getTasks().create(taskName + CHECK); + Task applyTask = project.getTasks().create(taskName + APPLY); + + checkTask.dependsOn(spotlessTask); + applyTask.dependsOn(spotlessTask); + // when the task graph is ready, we'll configure the spotlessTask appropriately + project.getGradle().getTaskGraph().whenReady(new Closure(null) { + private static final long serialVersionUID = 1L; + + // called by gradle + @SuppressFBWarnings("UMAC_UNCALLABLE_METHOD_OF_ANONYMOUS_CLASS") + public Object doCall(TaskExecutionGraph graph) { + if (graph.hasTask(checkTask)) { + spotlessTask.setCheck(); + } + if (graph.hasTask(applyTask)) { + spotlessTask.setApply(); + } + return Closure.DONE; + } + }); + + // the root tasks depend on the control tasks + rootCheckTask.dependsOn(checkTask); + rootApplyTask.dependsOn(applyTask); + } } diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessPlugin.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessPlugin.java index 31cede4d52..0e9f670c6c 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessPlugin.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessPlugin.java @@ -18,25 +18,14 @@ import org.gradle.api.Plugin; import org.gradle.api.Project; import org.gradle.api.Task; -import org.gradle.api.execution.TaskExecutionGraph; import org.gradle.api.plugins.BasePlugin; import org.gradle.api.plugins.JavaBasePlugin; import com.diffplug.spotless.SpotlessCache; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import groovy.lang.Closure; - public class SpotlessPlugin implements Plugin { SpotlessExtension spotlessExtension; - static final String EXTENSION = "spotless"; - static final String CHECK = "Check"; - static final String APPLY = "Apply"; - - private static final String TASK_GROUP = "Verification"; - private static final String CHECK_DESCRIPTION = "Checks that sourcecode satisfies formatting steps."; - private static final String APPLY_DESCRIPTION = "Applies code formatting steps to sourcecode in-place."; private static final String FILES_PROPERTY = "spotlessFiles"; @Override @@ -45,10 +34,32 @@ public void apply(Project project) { project.getPlugins().apply(BasePlugin.class); // setup the extension - spotlessExtension = project.getExtensions().create(EXTENSION, SpotlessExtension.class, project); + spotlessExtension = project.getExtensions().create(SpotlessExtension.EXTENSION, SpotlessExtension.class, project); + + // clear spotless' cache when the user does a clean + Task clean = project.getTasks().getByName(BasePlugin.CLEAN_TASK_NAME); + clean.doLast(unused -> SpotlessCache.clear()); - // after the project has been evaluated, configure the check and format tasks per source set - project.afterEvaluate(this::createTasks); + project.afterEvaluate(unused -> { + // set the filePatterns property + String filePatterns; + if (project.hasProperty(FILES_PROPERTY) && project.property(FILES_PROPERTY) instanceof String) { + filePatterns = (String) project.property(FILES_PROPERTY); + } else { + // needs to be non-null since it is an @Input property of the task + filePatterns = ""; + } + project.getTasks().withType(SpotlessTask.class, task -> task.setFilePatterns(filePatterns)); + + // Add our check task as a dependency on the global check task + // getTasks() returns a "live" collection, so this works even if the + // task doesn't exist at the time this call is made + if (spotlessExtension.enforceCheck) { + project.getTasks() + .matching(task -> task.getName().equals(JavaBasePlugin.CHECK_TASK_NAME)) + .all(task -> task.dependsOn(spotlessExtension.rootCheckTask)); + } + }); } /** The extension for this plugin. */ @@ -56,74 +67,6 @@ public SpotlessExtension getExtension() { return spotlessExtension; } - @SuppressWarnings("rawtypes") - void createTasks(Project project) { - Task rootCheckTask = project.task(EXTENSION + CHECK); - rootCheckTask.setGroup(TASK_GROUP); - rootCheckTask.setDescription(CHECK_DESCRIPTION); - Task rootApplyTask = project.task(EXTENSION + APPLY); - rootApplyTask.setGroup(TASK_GROUP); - rootApplyTask.setDescription(APPLY_DESCRIPTION); - String filePatterns; - if (project.hasProperty(FILES_PROPERTY) && project.property(FILES_PROPERTY) instanceof String) { - filePatterns = (String) project.property(FILES_PROPERTY); - } else { - // needs to be non-null since it is an @Input property of the task - filePatterns = ""; - } - - spotlessExtension.formats.forEach((key, value) -> { - // create the task that does the work - String taskName = EXTENSION + capitalize(key); - SpotlessTask spotlessTask = project.getTasks().create(taskName, SpotlessTask.class); - value.setupTask(spotlessTask); - spotlessTask.setFilePatterns(filePatterns); - - // create the check and apply control tasks - Task checkTask = project.getTasks().create(taskName + CHECK); - Task applyTask = project.getTasks().create(taskName + APPLY); - // the root tasks depend on them - rootCheckTask.dependsOn(checkTask); - rootApplyTask.dependsOn(applyTask); - // and they depend on the work task - checkTask.dependsOn(spotlessTask); - applyTask.dependsOn(spotlessTask); - - // when the task graph is ready, we'll configure the spotlessTask appropriately - project.getGradle().getTaskGraph().whenReady(new Closure(null) { - private static final long serialVersionUID = 1L; - - // called by gradle - @SuppressFBWarnings("UMAC_UNCALLABLE_METHOD_OF_ANONYMOUS_CLASS") - public Object doCall(TaskExecutionGraph graph) { - if (graph.hasTask(checkTask)) { - spotlessTask.setCheck(); - } - if (graph.hasTask(applyTask)) { - spotlessTask.setApply(); - } - return Closure.DONE; - } - }); - }); - - // Add our check task as a dependency on the global check task - // getTasks() returns a "live" collection, so this works even if the - // task doesn't exist at the time this call is made - if (spotlessExtension.enforceCheck) { - project.getTasks() - .matching(task -> task.getName().equals(JavaBasePlugin.CHECK_TASK_NAME)) - .all(task -> task.dependsOn(rootCheckTask)); - } - - // clear spotless' cache when the user does a clean, but only after any spotless tasks - Task clean = project.getTasks().getByName(BasePlugin.CLEAN_TASK_NAME); - clean.doLast(unused -> SpotlessCache.clear()); - project.getTasks() - .withType(SpotlessTask.class) - .all(task -> task.mustRunAfter(clean)); - } - static String capitalize(String input) { return Character.toUpperCase(input.charAt(0)) + input.substring(1); } diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTask.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTask.java index eef52f64f0..a351e3218a 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTask.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTask.java @@ -169,8 +169,8 @@ public void setApply() { /** Returns the name of this format. */ String formatName() { String name = getName(); - if (name.startsWith(SpotlessPlugin.EXTENSION)) { - return name.substring(SpotlessPlugin.EXTENSION.length()).toLowerCase(Locale.ROOT); + if (name.startsWith(SpotlessExtension.EXTENSION)) { + return name.substring(SpotlessExtension.EXTENSION.length()).toLowerCase(Locale.ROOT); } else { return name; } @@ -179,10 +179,10 @@ String formatName() { @TaskAction public void performAction(IncrementalTaskInputs inputs) throws Exception { if (target == null) { - throw new GradleException("You must specify 'Iterable toFormat'"); + throw new GradleException("You must specify 'Iterable target'"); } if (!check && !apply) { - throw new GradleException("Don't call " + getName() + " directly, call " + getName() + SpotlessPlugin.CHECK + " or " + getName() + SpotlessPlugin.APPLY); + throw new GradleException("Don't call " + getName() + " directly, call " + getName() + SpotlessExtension.CHECK + " or " + getName() + SpotlessExtension.APPLY); } Predicate shouldInclude; diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/PaddedCellTaskTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/PaddedCellTaskTest.java index 4b5f16430c..1d05b4419c 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/PaddedCellTaskTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/PaddedCellTaskTest.java @@ -57,6 +57,8 @@ private class Bundle { } private SpotlessTask createCheckTask(String name, FormatterStep step) { + // we don't add Check to the end because SpotlessTask normally doesn't have + // "Check" or "Apply", and it matters for generating the failure files SpotlessTask task = project.getTasks().create("spotless" + SpotlessPlugin.capitalize(name), SpotlessTask.class); task.setCheck(); task.addStep(step); @@ -66,7 +68,7 @@ private SpotlessTask createCheckTask(String name, FormatterStep step) { } private SpotlessTask createApplyTask(String name, FormatterStep step) { - SpotlessTask task = project.getTasks().create("spotless" + SpotlessPlugin.capitalize(name) + SpotlessPlugin.APPLY, SpotlessTask.class); + SpotlessTask task = project.getTasks().create("spotless" + SpotlessPlugin.capitalize(name) + "Apply", SpotlessTask.class); task.setApply(); task.addStep(step); task.setLineEndingsPolicy(LineEnding.UNIX.createPolicy()); diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/SelfTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/SelfTest.java index ba2010f3d8..a3e5bbcd24 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/SelfTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/SelfTest.java @@ -122,7 +122,6 @@ private static Project createProject(Consumer test) throws Ex SpotlessPlugin plugin = project.getPlugins().apply(SpotlessPlugin.class); // setup the plugin test.accept(plugin.getExtension()); - plugin.createTasks(project); // return the configured plugin return project; } From 8b2aa5ce27137031ec4b7940ff42f405f5ed06b0 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sun, 29 Sep 2019 22:57:33 -0700 Subject: [PATCH 2/5] When running on gradle >= 4.9, use the config avoidance API to avoid configuring other tasks. --- .../gradle/spotless/SpotlessPlugin.java | 10 +-- .../SpotlessPluginConfigAvoidance.java | 28 ++++++++ .../gradle/spotless/SpotlessPluginLegacy.java | 30 +++++++++ .../gradle/spotless/ConfigAvoidanceTest.java | 64 +++++++++++++++++++ 4 files changed, 128 insertions(+), 4 deletions(-) create mode 100644 plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessPluginConfigAvoidance.java create mode 100644 plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessPluginLegacy.java create mode 100644 plugin-gradle/src/test/java/com/diffplug/gradle/spotless/ConfigAvoidanceTest.java diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessPlugin.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessPlugin.java index 0e9f670c6c..43d593284c 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessPlugin.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessPlugin.java @@ -19,7 +19,7 @@ import org.gradle.api.Project; import org.gradle.api.Task; import org.gradle.api.plugins.BasePlugin; -import org.gradle.api.plugins.JavaBasePlugin; +import org.gradle.util.GradleVersion; import com.diffplug.spotless.SpotlessCache; @@ -55,9 +55,11 @@ public void apply(Project project) { // getTasks() returns a "live" collection, so this works even if the // task doesn't exist at the time this call is made if (spotlessExtension.enforceCheck) { - project.getTasks() - .matching(task -> task.getName().equals(JavaBasePlugin.CHECK_TASK_NAME)) - .all(task -> task.dependsOn(spotlessExtension.rootCheckTask)); + if (GradleVersion.current().compareTo(SpotlessPluginLegacy.CONFIG_AVOIDANCE_INTRODUCED) >= 0) { + SpotlessPluginConfigAvoidance.enforceCheck(spotlessExtension, project); + } else { + SpotlessPluginLegacy.enforceCheck(spotlessExtension, project); + } } }); } diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessPluginConfigAvoidance.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessPluginConfigAvoidance.java new file mode 100644 index 0000000000..da8b6c1f29 --- /dev/null +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessPluginConfigAvoidance.java @@ -0,0 +1,28 @@ +/* + * Copyright 2016 DiffPlug + * + * 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 + * + * http://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 com.diffplug.gradle.spotless; + +import org.gradle.api.Project; +import org.gradle.api.Task; +import org.gradle.api.plugins.JavaBasePlugin; +import org.gradle.api.tasks.TaskProvider; + +class SpotlessPluginConfigAvoidance { + static void enforceCheck(SpotlessExtension extension, Project project) { + TaskProvider check = project.getTasks().named(JavaBasePlugin.CHECK_TASK_NAME); + check.configure(task -> task.dependsOn(extension.rootCheckTask)); + } +} diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessPluginLegacy.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessPluginLegacy.java new file mode 100644 index 0000000000..5c6f4db8a8 --- /dev/null +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessPluginLegacy.java @@ -0,0 +1,30 @@ +/* + * Copyright 2016 DiffPlug + * + * 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 + * + * http://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 com.diffplug.gradle.spotless; + +import org.gradle.api.Project; +import org.gradle.api.Task; +import org.gradle.api.plugins.JavaBasePlugin; +import org.gradle.util.GradleVersion; + +class SpotlessPluginLegacy { + static final GradleVersion CONFIG_AVOIDANCE_INTRODUCED = GradleVersion.version("4.9"); + + static void enforceCheck(SpotlessExtension extension, Project project) { + Task check = project.getTasks().getByName(JavaBasePlugin.CHECK_TASK_NAME); + check.dependsOn(extension.rootCheckTask); + } +} diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/ConfigAvoidanceTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/ConfigAvoidanceTest.java new file mode 100644 index 0000000000..f11e556034 --- /dev/null +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/ConfigAvoidanceTest.java @@ -0,0 +1,64 @@ +/* + * Copyright 2016 DiffPlug + * + * 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 + * + * http://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 com.diffplug.gradle.spotless; + +import java.io.IOException; + +import org.assertj.core.api.Assertions; +import org.gradle.testkit.runner.GradleRunner; +import org.junit.Test; + +public class ConfigAvoidanceTest extends GradleIntegrationTest { + protected final GradleRunner gradleRunnerConfigAvoidance() throws IOException { + return gradleRunner().withGradleVersion(SpotlessPluginLegacy.CONFIG_AVOIDANCE_INTRODUCED.getVersion()); + } + + @Test + public void noConfigOnHelp() throws IOException { + setFile("build.gradle").toLines( + "buildscript { repositories { mavenCentral() } }", + "plugins {", + " id 'com.diffplug.gradle.spotless'", + "}", + "apply plugin: 'java'", + "spotless {", + " java {", + " googleJavaFormat('1.2')", + " }", + "}", + "", + "class ConfigureCanary extends DefaultTask {", + " ConfigureCanary() {", + " println('Canary was configured')", + " }", + "", + " @TaskAction", + " def action() {", + " println('Canary ran')", + " }", + "}", + "def canary = tasks.register('canary', ConfigureCanary) {}", + "tasks.named('check').configure {", + " dependsOn(canary)", + "}"); + setFile("src/main/java/test.java").toResource("java/googlejavaformat/JavaCodeUnformatted.test"); + + String help_4_9 = gradleRunnerConfigAvoidance().withArguments("help").build().getOutput(); + Assertions.assertThat(help_4_9).doesNotContain("Canary was configured"); + String check_4_9 = gradleRunnerConfigAvoidance().withArguments("check").buildAndFail().getOutput(); + Assertions.assertThat(check_4_9).contains("Canary was configured", "Canary ran", "Execution failed for task ':spotlessJava'"); + } +} From 4d23bcf42c14ede1513e3aea700ca78720bf0520 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sun, 29 Sep 2019 23:06:26 -0700 Subject: [PATCH 3/5] Update changelog. --- plugin-gradle/CHANGES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugin-gradle/CHANGES.md b/plugin-gradle/CHANGES.md index 914b2404e4..9eafbf2037 100644 --- a/plugin-gradle/CHANGES.md +++ b/plugin-gradle/CHANGES.md @@ -2,6 +2,9 @@ ### Version 3.25.0-SNAPSHOT - TBD ([javadoc](https://diffplug.github.io/spotless/javadoc/snapshot/), [snapshot](https://oss.sonatype.org/content/repositories/snapshots/com/diffplug/spotless/spotless-plugin-gradle/)) +* Spotless no longer breaks configuration avoidance for other tasks (specifically the `check` task and all of its dependees) ([#463](https://github.com/diffplug/spotless/pull/463)). + * Important change: **Formerly, Spotless did not create its tasks until the `afterEvaluate` phase. Spotless now creates them as soon as the plugin is applied**, and it creates the format-specific tasks as soon as the formats are defined. There is no performance degradation associated with this change, and it makes configuring Spotless easier. + ### Version 3.24.3 - September 23rd 2019 ([javadoc](https://diffplug.github.io/spotless/javadoc/spotless-plugin-gradle/3.24.3/), [jcenter](https://bintray.com/diffplug/opensource/spotless-plugin-gradle/3.24.3)) * Update jgit from `5.3.2.201906051522-r` to `5.5.0.201909110433-r`. ([#445](https://github.com/diffplug/spotless/pull/445)) From c4c226e7c154ba22bbe84d87841e88ae9d9129ab Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sun, 29 Sep 2019 23:10:59 -0700 Subject: [PATCH 4/5] Remove unnecessary change. --- .../java/com/diffplug/gradle/spotless/SpotlessExtension.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java index f934ab06dd..1eba446222 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java @@ -209,7 +209,7 @@ private void configure(String name, Class clazz, configure.execute(value); } - @SuppressWarnings({"unchecked"}) + @SuppressWarnings("unchecked") private T maybeCreate(String name, Class clazz) { FormatExtension existing = formats.get(name); if (existing != null) { From e97a580229601ec031c551c46a23217245117888 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sun, 29 Sep 2019 23:15:02 -0700 Subject: [PATCH 5/5] Move the `FILES_PROPERTY` support into the task creation point, so that we can avoid `getTasks().withType(SpotlessTask.class`. Allegedly `withType` triggers task configuration, although our test indicates that it doesn't at least in 4.9. Better to use the recommended API regardless, especially since we can do so without breaking 2.x support. --- .../gradle/spotless/SpotlessExtension.java | 14 ++++++++++++++ .../diffplug/gradle/spotless/SpotlessPlugin.java | 12 ------------ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java index 1eba446222..7d34a93caa 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java @@ -48,6 +48,8 @@ public class SpotlessExtension { private static final String CHECK_DESCRIPTION = "Checks that sourcecode satisfies formatting steps."; private static final String APPLY_DESCRIPTION = "Applies code formatting steps to sourcecode in-place."; + private static final String FILES_PROPERTY = "spotlessFiles"; + public SpotlessExtension(Project project) { this.project = requireNonNull(project); rootCheckTask = project.task(EXTENSION + CHECK); @@ -268,6 +270,18 @@ public Object doCall(TaskExecutionGraph graph) { } }); + // set the filePatterns property + project.afterEvaluate(unused -> { + String filePatterns; + if (project.hasProperty(FILES_PROPERTY) && project.property(FILES_PROPERTY) instanceof String) { + filePatterns = (String) project.property(FILES_PROPERTY); + } else { + // needs to be non-null since it is an @Input property of the task + filePatterns = ""; + } + spotlessTask.setFilePatterns(filePatterns); + }); + // the root tasks depend on the control tasks rootCheckTask.dependsOn(checkTask); rootApplyTask.dependsOn(applyTask); diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessPlugin.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessPlugin.java index 43d593284c..43874e1f35 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessPlugin.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessPlugin.java @@ -26,8 +26,6 @@ public class SpotlessPlugin implements Plugin { SpotlessExtension spotlessExtension; - private static final String FILES_PROPERTY = "spotlessFiles"; - @Override public void apply(Project project) { // make sure there's a `clean` task @@ -41,16 +39,6 @@ public void apply(Project project) { clean.doLast(unused -> SpotlessCache.clear()); project.afterEvaluate(unused -> { - // set the filePatterns property - String filePatterns; - if (project.hasProperty(FILES_PROPERTY) && project.property(FILES_PROPERTY) instanceof String) { - filePatterns = (String) project.property(FILES_PROPERTY); - } else { - // needs to be non-null since it is an @Input property of the task - filePatterns = ""; - } - project.getTasks().withType(SpotlessTask.class, task -> task.setFilePatterns(filePatterns)); - // Add our check task as a dependency on the global check task // getTasks() returns a "live" collection, so this works even if the // task doesn't exist at the time this call is made