diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3aaa82366e..b0d22a3efd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -115,6 +115,57 @@ The gist of it is that you will have to: If you get something running, we'd love to host your plugin within this repo as a peer to `plugin-gradle` and `plugin-maven`. +## Integration testing + +### Locally + +First, run `./gradlew publishToMavenLocal` in your local checkout of Spotless. Now, in any other project on your machine, you can use the following snippet in your `settings.gradle` (for Gradle 6.0+). + +``` +pluginManagement { + repositories { + mavenLocal { + content { + includeGroup 'com.diffplug.spotless' + } + } + gradlePluginPortal() + } + resolutionStrategy { + eachPlugin { + if (requested.id.id == 'com.diffplug.gradle.spotless') { + useModule('com.diffplug.spotless:spotless-plugin-gradle:{latest-SNAPSHOT}') + } + } + } +} +``` + +### Any commit in a public GitHub repo (this one, or any fork) + +In Gradle 6.0+, you can use the following snippet in your `settings.gradle`. TODO: broken until [jitpack/jitpack.io#4112](https://github.com/jitpack/jitpack.io/issues/4112) is resolved. + +```gradle +pluginManagement { + repositories { + maven { + url 'https://jitpack.io' + content { + includeGroup 'com.github.{{user-or-org}}.spotless' + } + } + gradlePluginPortal() + } + resolutionStrategy { + eachPlugin { + if (requested.id.id == 'com.diffplug.gradle.spotless') { + useModule('com.github.{{user-or-org}}.spotless:spotless-plugin-gradle:SHA_OF_COMMIT_YOU_WANT') + } + } + } +} +``` + ## License By contributing your code, you agree to license your contribution under the terms of the APLv2: https://github.com/diffplug/spotless/blob/master/LICENSE.txt diff --git a/lib/src/main/java/com/diffplug/spotless/markdown/LibMarkdownPreconditions.java b/lib/src/main/java/com/diffplug/spotless/markdown/LibMarkdownPreconditions.java index 330ff80990..576535b1cb 100644 --- a/lib/src/main/java/com/diffplug/spotless/markdown/LibMarkdownPreconditions.java +++ b/lib/src/main/java/com/diffplug/spotless/markdown/LibMarkdownPreconditions.java @@ -25,8 +25,9 @@ private LibMarkdownPreconditions() {} static Map requireKeysAndValuesNonNull(Map map) { Objects.requireNonNull(map); map.forEach((key, value) -> { - Objects.requireNonNull(key); - Objects.requireNonNull(value); + String errorMessage = key + "=" + value; + Objects.requireNonNull(key, errorMessage); + Objects.requireNonNull(value, errorMessage); }); return map; } diff --git a/plugin-gradle/CHANGES.md b/plugin-gradle/CHANGES.md index 7e50c46112..979979e44f 100644 --- a/plugin-gradle/CHANGES.md +++ b/plugin-gradle/CHANGES.md @@ -2,6 +2,8 @@ ### Version 3.27.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/)) +* Added method `FormatExtension.createIndependentTask(String taskName)` which allows creating a Spotless task outside of the `check`/`apply` lifecycle. See [javadoc](https://github.com/diffplug/spotless/blob/91ed7203994e52058ea6c2e0f88d023ed290e433/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java#L613-L639) for details. + ### Version 3.26.1 - November 27th 2019 ([javadoc](https://diffplug.github.io/spotless/javadoc/spotless-plugin-gradle/3.26.1/), [jcenter](https://bintray.com/diffplug/opensource/spotless-plugin-gradle/3.26.1)) * Revert the change in console display of errors from 3.26.0 ([#485](https://github.com/diffplug/spotless/pull/485)) because [of these problems](https://github.com/diffplug/spotless/pull/485#issuecomment-552925932). diff --git a/plugin-gradle/README.md b/plugin-gradle/README.md index 4a796b3ca0..f4c93f0e36 100644 --- a/plugin-gradle/README.md +++ b/plugin-gradle/README.md @@ -611,6 +611,8 @@ If you use `custom` or `customLazy`, you might want to take a look at [this java See [`JavaExtension.java`](src/main/java/com/diffplug/gradle/spotless/JavaExtension.java) if you'd like to see how a language-specific set of custom rules is implemented. We'd love PR's which add support for other languages. +If you'd like to create a one-off Spotless task outside of the `check`/`apply` framework, see [`FormatExtension.createIndependentTask`](https://github.com/diffplug/spotless/blob/91ed7203994e52058ea6c2e0f88d023ed290e433/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java#L613-L639). + ## Line endings and encodings (invisible stuff) diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java index 11fb290ca6..3723d89526 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java @@ -27,7 +27,9 @@ import org.gradle.api.GradleException; import org.gradle.api.Project; +import org.gradle.api.Task; import org.gradle.api.file.FileCollection; +import org.gradle.api.plugins.BasePlugin; import org.gradle.api.tasks.util.PatternFilterable; import com.diffplug.spotless.FormatExceptionPolicyStrict; @@ -607,4 +609,32 @@ protected void setupTask(SpotlessTask task) { protected Project getProject() { return root.project; } + + /** + * Creates an independent {@link SpotlessTask} for (very) unusual circumstances. + * + * Most users will not want this method. In the rare case that you want to create + * a SpotlessTask which is independent of the normal Spotless machinery, this will + * let you do that. + * + * The returned task will have no dependencies on any other task. + * You need to call {@link SpotlessTask#setApply()} and/or {@link SpotlessTask#setCheck()} + * on the return value, otherwise you will get a runtime error when the task tries to run. + * + * NOTE: does not respect the rarely-used [`spotlessFiles` property](https://github.com/diffplug/spotless/blob/b7f8c551a97dcb92cc4b0ee665448da5013b30a3/plugin-gradle/README.md#can-i-apply-spotless-to-specific-files). + */ + public SpotlessTask createIndependentTask(String taskName) { + // create and setup the task + SpotlessTask spotlessTask = root.project.getTasks().create(taskName, SpotlessTask.class); + setupTask(spotlessTask); + + // enforce the clean ordering + Task clean = root.project.getTasks().getByName(BasePlugin.CLEAN_TASK_NAME); + spotlessTask.mustRunAfter(clean); + + // ignore the filePatterns + spotlessTask.setFilePatterns(""); + + return spotlessTask; + } } diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/IndependentTaskTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/IndependentTaskTest.java new file mode 100644 index 0000000000..c354437b89 --- /dev/null +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/IndependentTaskTest.java @@ -0,0 +1,43 @@ +/* + * 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.junit.Test; + +public class IndependentTaskTest extends GradleIntegrationTest { + @Test + public void independent() throws IOException { + setFile("build.gradle").toLines( + "buildscript { repositories { mavenCentral() } }", + "plugins {", + " id 'com.diffplug.gradle.spotless'", + "}", + "", + "import com.diffplug.gradle.spotless.JavaExtension", + "", + "def underTest = new JavaExtension(spotless)", + "underTest.target file('test.java')", + "underTest.googleJavaFormat('1.2')", + "", + "def independent = underTest.createIndependentTask('independent')", + "independent.setApply()"); + setFile("test.java").toResource("java/googlejavaformat/JavaCodeUnformatted.test"); + gradleRunner().withArguments("independent").build(); + assertFile("test.java").sameAsResource("java/googlejavaformat/JavaCodeFormatted.test"); + } +}