-
Notifications
You must be signed in to change notification settings - Fork 455
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
Dont break config avoidance for other tasks #463
Changes from all commits
bde9f48
8b2aa5c
4d23bcf
c4c226e
e97a580
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -18,112 +18,45 @@ | |||
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 org.gradle.util.GradleVersion; | ||||
|
||||
import com.diffplug.spotless.SpotlessCache; | ||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; | ||||
import groovy.lang.Closure; | ||||
|
||||
public class SpotlessPlugin implements Plugin<Project> { | ||||
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 | ||||
public void apply(Project project) { | ||||
// make sure there's a `clean` task | ||||
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 -> { | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there value in doing this in an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think so. People can have multiple spotless/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java Line 244 in e97a580
We used to do all the config in |
||||
// 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) { | ||||
if (GradleVersion.current().compareTo(SpotlessPluginLegacy.CONFIG_AVOIDANCE_INTRODUCED) >= 0) { | ||||
SpotlessPluginConfigAvoidance.enforceCheck(spotlessExtension, project); | ||||
} else { | ||||
SpotlessPluginLegacy.enforceCheck(spotlessExtension, project); | ||||
} | ||||
} | ||||
}); | ||||
} | ||||
|
||||
/** The extension for this plugin. */ | ||||
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); | ||||
} | ||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<Task> check = project.getTasks().named(JavaBasePlugin.CHECK_TASK_NAME); | ||
check.configure(task -> task.dependsOn(extension.rootCheckTask)); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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'"); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there's a
whenReady
that supports anAction
now isn't there?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is, but not in Gradle 2.x, which we still support.