diff --git a/CHANGES.md b/CHANGES.md
index 641d7207c..7f0283257 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -7,6 +7,8 @@ You might be looking for:
### Version 1.3.0-SNAPSHOT - TBD (javadoc [lib](https://diffplug.github.io/spotless/javadoc/spotless-lib/snapshot/) [lib-extra](https://diffplug.github.io/spotless/javadoc/spotless-lib-extra/snapshot/), [snapshot repo](https://oss.sonatype.org/content/repositories/snapshots/com/diffplug/spotless/))
+* Added support for Groovy via [greclipse](https://github.com/groovy/groovy-eclipse).
+
### Version 1.2.0 - April 3rd 2017 (javadoc [lib](https://diffplug.github.io/spotless/javadoc/spotless-lib/1.2.0/) [lib-extra](https://diffplug.github.io/spotless/javadoc/spotless-lib-extra/1.2.0/), artifact [lib]([jcenter](https://bintray.com/diffplug/opensource/spotless-lib), [lib-extra]([jcenter](https://bintray.com/diffplug/opensource/spotless-lib-extra)))
* Deprecated `FileSignature.from` in favor of `FileSignature.signAsSet` and the new `FileSignature.signAsList`.
diff --git a/README.md b/README.md
index cf0cad947..f694e42fd 100644
--- a/README.md
+++ b/README.md
@@ -38,6 +38,7 @@ lib('generic.LicenseHeaderStep') +'{{yes}} | {{no}}
lib('generic.ReplaceRegexStep') +'{{yes}} | {{no}} | {{no}} |',
lib('generic.ReplaceStep') +'{{yes}} | {{no}} | {{no}} |',
lib('generic.TrimTrailingWhitespaceStep') +'{{yes}} | {{no}} | {{no}} |',
+extra('groovy.GrEclipseFormatterStep') +'{{yes}} | {{no}} | {{no}} |',
lib('java.GoogleJavaFormatStep') +'{{yes}} | {{no}} | {{no}} |',
lib('java.ImportOrderStep') +'{{yes}} | {{no}} | {{no}} |',
extra('java.EclipseFormatterStep') +'{{yes}} | {{no}} | {{no}} |',
@@ -58,6 +59,7 @@ lib('scala.ScalaFmtStep') +'{{yes}} | {{no}}
| [`generic.ReplaceRegexStep`](lib/src/main/java/com/diffplug/spotless/generic/ReplaceRegexStep.java) | :+1: | :white_large_square: | :white_large_square: |
| [`generic.ReplaceStep`](lib/src/main/java/com/diffplug/spotless/generic/ReplaceStep.java) | :+1: | :white_large_square: | :white_large_square: |
| [`generic.TrimTrailingWhitespaceStep`](lib/src/main/java/com/diffplug/spotless/generic/TrimTrailingWhitespaceStep.java) | :+1: | :white_large_square: | :white_large_square: |
+| [`groovy.GrEclipseFormatterStep`](lib-extra/src/main/java/com/diffplug/spotless/extra/groovy/GrEclipseFormatterStep.java) | :+1: | :white_large_square: | :white_large_square: |
| [`java.GoogleJavaFormatStep`](lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java) | :+1: | :white_large_square: | :white_large_square: |
| [`java.ImportOrderStep`](lib/src/main/java/com/diffplug/spotless/java/ImportOrderStep.java) | :+1: | :white_large_square: | :white_large_square: |
| [`java.EclipseFormatterStep`](lib-extra/src/main/java/com/diffplug/spotless/extra/java/EclipseFormatterStep.java) | :+1: | :white_large_square: | :white_large_square: |
@@ -75,6 +77,7 @@ lib('scala.ScalaFmtStep') +'{{yes}} | {{no}}
+ implementing up-to-date checking [#31](https://github.com/diffplug/spotless/issues/31)
+ breaking spotless into libraries [#56](https://github.com/diffplug/spotless/issues/56)
+ lots of other things, but especially the diff support in `spotlessCheck`
+* Huge thanks to [Frank Vennemeyer](https://github.com/fvgh) for [Groovy support via greclipse](https://github.com/diffplug/spotless/issues/13).
* Huge thanks to [Stefan Oehme](https://github.com/oehme) for tons of help on the internal mechanics of Gradle.
* Formatting by Eclipse
+ Special thanks to [Mateusz Matela](https://waynebeaton.wordpress.com/2015/03/15/great-fixes-for-mars-winners-part-i/) for huge improvements to the eclipse code formatter!
diff --git a/_ext/greclipse/gradle.properties b/_ext/greclipse/gradle.properties
index 3244358d4..dbffb524c 100644
--- a/_ext/greclipse/gradle.properties
+++ b/_ext/greclipse/gradle.properties
@@ -1,6 +1,6 @@
# Mayor/Minor versions are in line with the Groovy version values.
# Patch version is an incremental counter for the Spotless plugin.
-grec_version=2.3.0-SNAPSHOT
+grec_version=2.3.0
grec_artifactId=spotless-ext-greclipse
grec_description=Groovy Eclipse's formatter bundled for Spotless
diff --git a/build.gradle b/build.gradle
index b4c6ac9a6..4a36eaea7 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,5 +1,5 @@
buildscript {
- repositories { maven { url 'https://plugins.gradle.org/m2/' } }
+ repositories { maven { url 'https://plugins.gradle.org/m2/' }}
dependencies {
classpath "com.diffplug.gradle:goomph:${VER_GOOMPH}"
classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:${VER_BINTRAY}"
diff --git a/gradle/java-publish.gradle b/gradle/java-publish.gradle
index 5e8da50ce..affc2da74 100644
--- a/gradle/java-publish.gradle
+++ b/gradle/java-publish.gradle
@@ -20,7 +20,7 @@ javadoc {
// use markdown in javadoc
def makeLink = { url, text -> "${text}" }
def javadocInfo = '
' + makeLink("https://github.com/${org}/${name}", "${group}:${project.ext.artifactId}:${ext.version}") +
-' by ' + makeLink('http://www.diffplug.com', 'DiffPlug') + '
'
+ ' by ' + makeLink('http://www.diffplug.com', 'DiffPlug') + ''
String version_str = ext.version.endsWith('-SNAPSHOT') ? 'snapshot' : ext.version
apply plugin: 'ch.raffael.pegdown-doclet'
@@ -110,13 +110,14 @@ model {
}
if (project.ext.isSnapshot) {
// upload snapshots to oss.sonatype.org
- repositories { maven {
- url = 'https://oss.sonatype.org/content/repositories/snapshots'
- credentials {
- username = cred('nexus_user')
- password = cred('nexus_pass')
- }
- } }
+ repositories {
+ maven {
+ url = 'https://oss.sonatype.org/content/repositories/snapshots'
+ credentials {
+ username = cred('nexus_user')
+ password = cred('nexus_pass')
+ }
+ }}
}
}
}
@@ -126,7 +127,9 @@ if (!ext.isSnapshot) {
bintray {
user = cred('bintray_user')
key = cred('bintray_pass')
- publications = ['pluginMaven']
+ publications = [
+ 'pluginMaven'
+ ]
publish = true
pkg {
repo = 'opensource'
@@ -143,5 +146,10 @@ if (!ext.isSnapshot) {
}
publish.dependsOn(bintrayUpload)
- bintrayUpload.dependsOn(['generatePomFileForPluginMavenPublication', jar, sourcesJar, javadocJar])
+ bintrayUpload.dependsOn([
+ 'generatePomFileForPluginMavenPublication',
+ jar,
+ sourcesJar,
+ javadocJar
+ ])
}
diff --git a/gradle/java-setup.gradle b/gradle/java-setup.gradle
index 305c4ec33..1de634c08 100644
--- a/gradle/java-setup.gradle
+++ b/gradle/java-setup.gradle
@@ -1,18 +1,14 @@
//////////
// JAVA //
//////////
-repositories {
- jcenter()
-}
+repositories { jcenter() }
// setup java
apply plugin: 'java'
sourceCompatibility = VER_JAVA
targetCompatibility = VER_JAVA
-tasks.withType(JavaCompile) {
- options.encoding = 'UTF-8'
-}
+tasks.withType(JavaCompile) { options.encoding = 'UTF-8' }
/////////////
// ECLIPSE //
@@ -38,7 +34,10 @@ eclipseResourceFilters {
apply plugin: 'findbugs'
findbugs {
toolVersion = VER_FINDBUGS
- sourceSets = [sourceSets.main] // don't check the test code
+ sourceSets = [
+ // don't check the test code
+ sourceSets.main
+ ]
ignoreFailures = false // bug free or it doesn't ship!
reportsDir = file('build/findbugs')
effort = 'max' // min|default|max
diff --git a/lib-extra/build.gradle b/lib-extra/build.gradle
index ac0328a50..38bbaa2ab 100644
--- a/lib-extra/build.gradle
+++ b/lib-extra/build.gradle
@@ -22,6 +22,5 @@ dependencies {
}
// we'll hold the core lib to a high standard
-findbugs {
- reportLevel = 'low' // low|medium|high (low = sensitive to even minor mistakes)
-}
+findbugs { reportLevel = 'low' } // low|medium|high (low = sensitive to even minor mistakes)
+
diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/groovy/GrEclipseFormatterStep.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/groovy/GrEclipseFormatterStep.java
new file mode 100644
index 000000000..aa6d82ddb
--- /dev/null
+++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/groovy/GrEclipseFormatterStep.java
@@ -0,0 +1,91 @@
+/*
+ * 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.spotless.extra.groovy;
+
+import java.io.File;
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Objects;
+import java.util.Properties;
+
+import com.diffplug.spotless.FileSignature;
+import com.diffplug.spotless.FormatterFunc;
+import com.diffplug.spotless.FormatterProperties;
+import com.diffplug.spotless.FormatterStep;
+import com.diffplug.spotless.JarState;
+import com.diffplug.spotless.Provisioner;
+
+/** Formatter step which calls out to the Groovy-Eclipse formatter. */
+public class GrEclipseFormatterStep {
+ public static final String defaultVersion() {
+ return DEFAULT_VERSION;
+ }
+
+ private static final String NAME = "groovy-eclipse formatter";
+ private static final String FORMATTER_CLASS = "com.diffplug.gradle.spotless.groovy.eclipse.GrEclipseFormatterStepImpl";
+ private static final String DEFAULT_VERSION = "2.3.0";
+ private static final String MAVEN_COORDINATE = "com.diffplug.spotless:spotless-ext-greclipse:";
+ private static final String FORMATTER_METHOD = "format";
+
+ /** Creates a formatter step using the default version for the given settings file. */
+ public static FormatterStep create(Iterable settingsFiles, Provisioner provisioner) {
+ return create(defaultVersion(), settingsFiles, provisioner);
+ }
+
+ /** Creates a formatter step for the given version and settings file. */
+ public static FormatterStep create(String version, Iterable settingsFiles, Provisioner provisioner) {
+ return FormatterStep.createLazy(
+ NAME,
+ () -> new State(JarState.from(MAVEN_COORDINATE + version, provisioner), settingsFiles),
+ State::createFormat);
+ }
+
+ private static class State implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /** The jar that contains the eclipse formatter. */
+ final JarState jarState;
+ /** The signature of the settings file. */
+ final FileSignature settings;
+
+ State(JarState jar, final Iterable settingsFiles) throws Exception {
+ this.jarState = Objects.requireNonNull(jar);
+ this.settings = FileSignature.signAsList(settingsFiles);
+ }
+
+ FormatterFunc createFormat() throws Exception {
+ FormatterProperties preferences = FormatterProperties.from(settings.files());
+
+ ClassLoader classLoader = jarState.getClassLoader();
+
+ // instantiate the formatter and get its format method
+ Class> formatterClazz = classLoader.loadClass(FORMATTER_CLASS);
+ Object formatter = formatterClazz.getConstructor(Properties.class).newInstance(preferences.getProperties());
+ Method method = formatterClazz.getMethod(FORMATTER_METHOD, String.class);
+ return input -> {
+ try {
+ return (String) method.invoke(formatter, input);
+ } catch (InvocationTargetException exceptionWrapper) {
+ Throwable throwable = exceptionWrapper.getTargetException();
+ Exception exception = (throwable instanceof Exception) ? (Exception) throwable : null;
+ throw (null == exception) ? exceptionWrapper : exception;
+ }
+ };
+ }
+ }
+
+}
diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/groovy/package-info.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/groovy/package-info.java
new file mode 100644
index 000000000..6712109bb
--- /dev/null
+++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/groovy/package-info.java
@@ -0,0 +1,7 @@
+@ParametersAreNonnullByDefault
+@ReturnValuesAreNonnullByDefault
+package com.diffplug.spotless.extra.groovy;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
+import com.diffplug.spotless.annotations.ReturnValuesAreNonnullByDefault;
diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/groovy/GrEclipseFormatterStepTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/groovy/GrEclipseFormatterStepTest.java
new file mode 100644
index 000000000..4ba349f8d
--- /dev/null
+++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/groovy/GrEclipseFormatterStepTest.java
@@ -0,0 +1,88 @@
+/*
+ * 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.spotless.extra.groovy;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import org.junit.Test;
+
+import com.diffplug.spotless.FormatterStep;
+import com.diffplug.spotless.Provisioner;
+import com.diffplug.spotless.ResourceHarness;
+import com.diffplug.spotless.SerializableEqualityTester;
+import com.diffplug.spotless.StepHarness;
+import com.diffplug.spotless.TestProvisioner;
+
+public class GrEclipseFormatterStepTest extends ResourceHarness {
+
+ private static final String RESOURCE_PATH = "groovy/greclipse/format/";
+ private static final String CONFIG_FILE = RESOURCE_PATH + "greclipse.properties";
+
+ //String is hard-coded in the GrEclipseFormatter
+ private static final String FORMATTER_FILENAME_REPALCEMENT = "Hello.groovy";
+
+ private static Provisioner provisioner() {
+ return TestProvisioner.mavenCentral();
+ }
+
+ @Test
+ public void nominal() throws Throwable {
+ List config = createTestFiles(CONFIG_FILE);
+ StepHarness.forStep(GrEclipseFormatterStep.create(config, provisioner()))
+ .testResource(RESOURCE_PATH + "unformatted.test", RESOURCE_PATH + "formatted.test");
+ }
+
+ @Test
+ public void formatterException() throws Throwable {
+ List config = createTestFiles(CONFIG_FILE);
+ StepHarness.forStep(GrEclipseFormatterStep.create(config, provisioner()))
+ .testException(RESOURCE_PATH + "exception.test", assertion -> {
+ assertion.isInstanceOf(IllegalArgumentException.class);
+ assertion.hasMessageContaining(FORMATTER_FILENAME_REPALCEMENT);
+ });
+ }
+
+ @Test
+ public void configurationException() throws Throwable {
+ String configFileName = "greclipse.exception";
+ List config = createTestFiles(RESOURCE_PATH + configFileName);
+ StepHarness.forStep(GrEclipseFormatterStep.create(config, provisioner()))
+ .testException(RESOURCE_PATH + "unformatted.test", assertion -> {
+ assertion.isInstanceOf(IllegalArgumentException.class);
+ assertion.hasMessageContaining(configFileName);
+ });
+ }
+
+ @Test
+ public void equality() throws IOException {
+ List configFile = createTestFiles(CONFIG_FILE);
+ new SerializableEqualityTester() {
+
+ @Override
+ protected void setupTest(API api) {
+ api.areDifferentThan();
+ }
+
+ @Override
+ protected FormatterStep create() {
+ return GrEclipseFormatterStep.create(configFile, provisioner());
+ }
+ }.testEquals();
+ }
+
+}
diff --git a/lib-extra/src/test/resources/groovy/greclipse/format/exception.test b/lib-extra/src/test/resources/groovy/greclipse/format/exception.test
new file mode 100644
index 000000000..9a298618c
--- /dev/null
+++ b/lib-extra/src/test/resources/groovy/greclipse/format/exception.test
@@ -0,0 +1,18 @@
+/**
+* Class description
+*/
+class Foo{
+String foo
+
+/* Method */
+def callBar() {
+new Bar().bar(foo)
+}
+//Compiler error. Missing close-brace.
+//
+//Note that the error message is additionally logged to system-err
+//within GrEclipse itself. That error message is just a dump of a RAW data report.
+//The whole error handling therefore looks not nicely readable.
+//Since these errors should only occur if the input file is not compile-able,
+//the error format is considered acceptable, since the spotless task runs
+//in general only after a successful compilation.
\ No newline at end of file
diff --git a/lib-extra/src/test/resources/groovy/greclipse/format/formatted.test b/lib-extra/src/test/resources/groovy/greclipse/format/formatted.test
new file mode 100644
index 000000000..9384c375e
--- /dev/null
+++ b/lib-extra/src/test/resources/groovy/greclipse/format/formatted.test
@@ -0,0 +1,22 @@
+/**
+ * Class description
+ */
+class Foo
+{
+ String foo
+
+ /* Method */
+ def callBar()
+ {
+ new Bar().bar(foo) }
+
+ /** Inner class */
+ class Bar
+ {
+
+ def bar(foo)
+ {
+ println "${foo}Bar" }}}
+
+def foo = new Foo(foo: 'Foo')
+foo.callBar()
\ No newline at end of file
diff --git a/lib-extra/src/test/resources/groovy/greclipse/format/greclipse.exception b/lib-extra/src/test/resources/groovy/greclipse/format/greclipse.exception
new file mode 100644
index 000000000..c991f4498
--- /dev/null
+++ b/lib-extra/src/test/resources/groovy/greclipse/format/greclipse.exception
@@ -0,0 +1 @@
+The file name extension 'exception' not supported for GrEclipse configuration files.
\ No newline at end of file
diff --git a/lib-extra/src/test/resources/groovy/greclipse/format/greclipse.properties b/lib-extra/src/test/resources/groovy/greclipse/format/greclipse.properties
new file mode 100644
index 000000000..631310a0e
--- /dev/null
+++ b/lib-extra/src/test/resources/groovy/greclipse/format/greclipse.properties
@@ -0,0 +1,34 @@
+#Whether to use 'space', 'tab' or 'mixed' (both) characters for indentation.
+#The default value is 'tab'.
+org.eclipse.jdt.core.formatter.tabulation.char=space
+
+#Number of spaces used for indentation in case 'space' characters
+#have been selected. The default value is 4.
+org.eclipse.jdt.core.formatter.tabulation.size=2
+
+#Number of spaces used for indentation in case 'mixed' characters
+#have been selected. The default value is 4.
+org.eclipse.jdt.core.formatter.indentation.size=2
+
+#Whether or not indentation characters are inserted into empty lines.
+#The default value is 'true'.
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+
+#Number of spaces used for multiline indentation.
+#The default value is 2.
+groovy.formatter.multiline.indentation=1
+
+#Length after which list are considered too long. These will be wrapped.
+#The default value is 30.
+groovy.formatter.longListLength=30
+
+#Whether opening braces position shall be the next line.
+#The default value is 'same'.
+groovy.formatter.braces.start=next
+
+#Whether closing braces position shall be the next line.
+#The default value is 'next'.
+groovy.formatter.braces.end=same
+
+#Remove unnecessary semicolons. The default value is 'false'.
+groovy.formatter.remove.unnecessary.semicolons=true
diff --git a/lib-extra/src/test/resources/groovy/greclipse/format/unformatted.test b/lib-extra/src/test/resources/groovy/greclipse/format/unformatted.test
new file mode 100644
index 000000000..c05fc936f
--- /dev/null
+++ b/lib-extra/src/test/resources/groovy/greclipse/format/unformatted.test
@@ -0,0 +1,20 @@
+/**
+* Class description
+*/
+class Foo{
+String foo
+
+/* Method */
+def callBar() {
+new Bar().bar(foo)
+}
+
+/** Inner class */
+class Bar {
+
+def bar(foo) {
+println "${foo}Bar"
+}}}
+
+def foo = new Foo(foo: 'Foo');
+foo.callBar()
\ No newline at end of file
diff --git a/lib/build.gradle b/lib/build.gradle
index a58e73560..3493f5a7b 100644
--- a/lib/build.gradle
+++ b/lib/build.gradle
@@ -12,6 +12,4 @@ dependencies {
}
// we'll hold the core lib to a high standard
-findbugs {
- reportLevel = 'low' // low|medium|high (low = sensitive to even minor mistakes)
-}
+findbugs { reportLevel = 'low' } // low|medium|high (low = sensitive to even minor mistakes)
diff --git a/lib/src/main/java/com/diffplug/spotless/FileSignature.java b/lib/src/main/java/com/diffplug/spotless/FileSignature.java
index 8df42cbd7..c0da096d1 100644
--- a/lib/src/main/java/com/diffplug/spotless/FileSignature.java
+++ b/lib/src/main/java/com/diffplug/spotless/FileSignature.java
@@ -69,10 +69,14 @@ public static FileSignature signAsList(Iterable files) throws IOException
return new FileSignature(asNonNullList(files));
}
+ /** Creates file signature whereas order of the files remains unchanged. */
+ public static FileSignature signAsSet(File... files) throws IOException {
+ return signAsSet(Arrays.asList(files));
+ }
+
/** Creates file signature insensitive to the order of the files. */
public static FileSignature signAsSet(Iterable files) throws IOException {
- return new FileSignature(
- toSortedSet(asNonNullList(files)));
+ return new FileSignature(toSortedSet(files));
}
private FileSignature(final List files) throws IOException {
@@ -106,7 +110,8 @@ public File getOnlyFile() {
}
/** Sorts "toBeSorted" and removes duplicates. */
- private static > List toSortedSet(List toBeSorted) {
+ static > List toSortedSet(Iterable raw) {
+ List toBeSorted = asNonNullList(raw);
// sort it
Collections.sort(toBeSorted);
// remove any duplicates (normally there won't be any)
@@ -136,5 +141,4 @@ private static List asNonNullList(Iterable input) {
});
return shallowCopy;
}
-
}
diff --git a/lib/src/main/java/com/diffplug/spotless/SerializableFileFilter.java b/lib/src/main/java/com/diffplug/spotless/SerializableFileFilter.java
index 27561758f..6b5c16df6 100644
--- a/lib/src/main/java/com/diffplug/spotless/SerializableFileFilter.java
+++ b/lib/src/main/java/com/diffplug/spotless/SerializableFileFilter.java
@@ -20,8 +20,8 @@
/** A file filter with full support for serialization. */
public interface SerializableFileFilter extends FileFilter, Serializable, NoLambda {
- /** Creates a FileFilter which will accept all files except files with the given name. */
- public static SerializableFileFilter skipFilesNamed(String name) {
- return new SerializableFileFilterImpl.SkipFilesNamed(name);
+ /** Creates a FileFilter which will accept all files except files with the given name(s). */
+ public static SerializableFileFilter skipFilesNamed(String... names) {
+ return new SerializableFileFilterImpl.SkipFilesNamed(names);
}
}
diff --git a/lib/src/main/java/com/diffplug/spotless/SerializableFileFilterImpl.java b/lib/src/main/java/com/diffplug/spotless/SerializableFileFilterImpl.java
index 82b935839..a0330582b 100644
--- a/lib/src/main/java/com/diffplug/spotless/SerializableFileFilterImpl.java
+++ b/lib/src/main/java/com/diffplug/spotless/SerializableFileFilterImpl.java
@@ -16,21 +16,31 @@
package com.diffplug.spotless;
import java.io.File;
+import java.util.Arrays;
+import java.util.List;
import java.util.Objects;
class SerializableFileFilterImpl {
static class SkipFilesNamed extends NoLambda.EqualityBasedOnSerialization implements SerializableFileFilter {
private static final long serialVersionUID = 1L;
- private final String nameToSkip;
+ private final String[] namesToSkip;
- SkipFilesNamed(String nameToSkip) {
- this.nameToSkip = Objects.requireNonNull(nameToSkip);
+ SkipFilesNamed(String... namesToSkip) {
+ Objects.requireNonNull(namesToSkip);
+ List sorted = FileSignature.toSortedSet(Arrays.asList(namesToSkip));
+ this.namesToSkip = sorted.toArray(new String[sorted.size()]);
}
@Override
public boolean accept(File pathname) {
- return !pathname.getName().equals(nameToSkip);
+ String name = pathname.getName();
+ for (String toSkip : namesToSkip) {
+ if (toSkip.equals(name)) {
+ return false;
+ }
+ }
+ return true;
}
}
}
diff --git a/plugin-gradle/CHANGES.md b/plugin-gradle/CHANGES.md
index 384c1a621..deda0cb2a 100644
--- a/plugin-gradle/CHANGES.md
+++ b/plugin-gradle/CHANGES.md
@@ -2,6 +2,8 @@
### Version 3.3.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 support for groovy formatting (huge thanks to Frank Vennemeyer! [#94](https://github.com/diffplug/spotless/pull/94), [#89](https://github.com/diffplug/spotless/pull/89), [#88](https://github.com/diffplug/spotless/pull/88), [#85](https://github.com/diffplug/spotless/pull/85))
+
### Version 3.2.0 - April 3rd 2017 ([javadoc](https://diffplug.github.io/spotless/javadoc/spotless-plugin-gradle/3.2.0/), [jcenter](https://bintray.com/diffplug/opensource/spotless-plugin-gradle/3.2.0))
* Update default KtLint from 0.3.1 to 0.6.1 (thanks to @kvnxiao [#93](https://github.com/diffplug/spotless/pull/93)).
diff --git a/plugin-gradle/README.md b/plugin-gradle/README.md
index c4b3ac81e..37247f9e8 100644
--- a/plugin-gradle/README.md
+++ b/plugin-gradle/README.md
@@ -79,6 +79,7 @@ Spotless can check and apply formatting to any plain-text file, using simple rul
* Eclipse's java code formatter (including style and import ordering)
* Google's [google-java-format](https://github.com/google/google-java-format)
+* [Groovy Eclipse](https://github.com/groovy/groovy-eclipse/wiki)'s groovy code formatter
* [FreshMark](https://github.com/diffplug/freshmark) (markdown with variables)
* Any user-defined function which takes an unformatted string and outputs a formatted version.
@@ -86,17 +87,19 @@ Contributions are welcome, see [the contributing guide](../CONTRIBUTING.md) for
Spotless requires Gradle to be running on JRE 8+.See [issue #7](https://github.com/diffplug/spotless/issues/7) for details.
+
+
## Applying to Java source
+By default, all Java source sets will be formatted. To change this,
+set the `target` parameter as described in the [Custom rules](#custom) section.
+
```gradle
apply plugin: 'java'
...
spotless {
java {
- // By default, all Java source sets will be formatted. To change
- // this, set the 'target' parameter as described in the next section.
-
licenseHeader '/* Licensed under Apache-2.0 */' // License header
licenseHeaderFile 'spotless.license.java' // License header file
// Obviously, you can't specify both licenseHeader and licenseHeaderFile at the same time
@@ -117,6 +120,8 @@ spotless {
See [ECLIPSE_SCREENSHOTS](../ECLIPSE_SCREENSHOTS.md) for screenshots that demonstrate how to get and install the eclipseFormatFile and importOrderFile mentioned above.
+
+
## Applying to Java source ([google-java-format](https://github.com/google/google-java-format))
```gradle
@@ -129,6 +134,49 @@ spotless {
}
```
+
+
+## Applying to Groovy source
+
+Configuration for Groovy is similar to [Java](#java). Most java steps, like `licenseHeader` and `importOrder`, support Groovy as well as Java.
+
+The groovy formatter's default behavior is to format all `.groovy` and `.java` files found in the Groovy source directories. If you would like to exclude the `.java` files, set the parameter `excludeJava`, or you can set the `target` parameter as described in the [Custom rules](#custom) section.
+
+```gradle
+apply plugin: 'groovy'
+...
+
+spotless {
+ java {
+ licenseHeaderFile 'spotless.license.java'
+ googleJavaFormat() // use a specific formatter for Java files
+ }
+ groovy {
+ licenseHeaderFile 'spotless.license.java'
+ excludeJava() // excludes all Java sources within the Groovy source dirs from formatting
+
+ // the Groovy Eclipse formatter extends the Java Eclipse formatter,
+ // so it formats Java files by default (unless `excludeJava` is used).
+ greclipse().configFile('greclipse.properties')
+ }
+}
+```
+
+The [Groovy-Eclipse](https://github.com/groovy/groovy-eclipse) formatter is based on the Eclipse Java formatter as used by `eclipseFormatFile`. It uses the same configuration parameters plus a few additional ones. These parameters can be configured within a single file, like the Java properties file [greclipse.properties](../lib-extra/src/test/resources/groovy/greclipse/format/greclipse.properties) in the previous example. The formatter step can also load the [exported Eclipse properties](../ECLIPSE_SCREENSHOTS.md) and augment it with the `org.codehaus.groovy.eclipse.ui.prefs` from the Eclipse workspace as shown below.
+
+```gradle
+spotless {
+ groovy {
+ // Use the default version and Groovy-Eclipse default configuration
+ greclipse()
+ // optional: you can specify a specific version or config file(s)
+ greclipse('2.3.0').configFile('spotless.eclipseformat.xml', 'org.codehaus.groovy.eclipse.ui.prefs')
+ }
+}
+```
+
+
+
## Applying [FreshMark](https://github.com/diffplug/freshmark) to markdown files
Freshmark lets you generate markdown in the comments of your markdown. This helps to keep badges and links up-to-date (see the source for this file), and can
@@ -148,6 +196,8 @@ spotless {
}
```
+
+
## Applying [scalafmt](https://olafurpg.github.io/scalafmt/#Scalafmt-codeformatterforScala) to Scala files
```gradle
@@ -160,6 +210,8 @@ spotless {
}
```
+
+
## Applying [ktlint](https://github.com/shyiko/ktlint) to Kotlin files
```gradle
@@ -174,6 +226,7 @@ spotless {
}
}
```
+
## Custom rules
@@ -218,6 +271,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/java/JavaExtension.java?ts=4) 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.
+
+
## Line endings and encodings (invisible stuff)
Spotless uses UTF-8 by default, but you can use [any encoding which Java supports](https://docs.oracle.com/javase/8/docs/technotes/guides/intl/encoding.doc.html). You can set it globally, and you can also set it per-format.
@@ -236,6 +291,8 @@ Line endings can also be set globally or per-format using the `lineEndings` prop
You can easily set the line endings of different files using [a `.gitattributes` file](https://help.github.com/articles/dealing-with-line-endings/). Here's an example `.gitattributes` which sets all files to unix newlines: `* text eol=lf`.
+
+
## Disabling warnings and error messages
The `check` task is Gradle's built-in task for grouping all verification tasks - unit tests, static analysis, etc. By default, `spotlessCheck` is added as a dependency to `check`.
@@ -264,6 +321,8 @@ spotless {
Note that `enforceCheck` is a global property which affects all formats (outside the java block), while `ignoreErrorForStep/Path` are local to a single format (inside the java block).
+
+
## How do I preview what `spotlessApply` will do?
- Save your working tree with `git add -A`, then `git commit -m "Checkpoint before spotless."`
@@ -272,6 +331,8 @@ Note that `enforceCheck` is a global property which affects all formats (outside
- If you don't like what spotless did, `git reset --hard`
- If you'd like to remove the "checkpoint" commit, `git reset --soft head~1` will make the checkpoint commit "disappear" from history, but keeps the changes in your working directory.
+
+
## Example configurations (from real-world projects)
Spotless is hosted on jcenter and at plugins.gradle.org. [Go here](https://plugins.gradle.org/plugin/com.diffplug.gradle.spotless) if you're not sure how to import the plugin.
diff --git a/plugin-gradle/build.gradle b/plugin-gradle/build.gradle
index 21a6c68e0..785e45db4 100644
--- a/plugin-gradle/build.gradle
+++ b/plugin-gradle/build.gradle
@@ -33,9 +33,7 @@ task spotlessApply(type: JavaExec) {
classpath sourceSets.test.runtimeClasspath
main = 'com.diffplug.gradle.spotless.SelfTestApply'
}
-test {
- testLogging.showStandardStreams = true
-}
+test { testLogging.showStandardStreams = true }
//////////////////////////
// GRADLE PLUGIN PORTAL //
@@ -51,7 +49,12 @@ pluginBundle {
spotlessPlugin {
id = 'com.diffplug.gradle.spotless'
displayName = 'Spotless formatting plugin'
- tags = ['format', 'style', 'license', 'header']
+ tags = [
+ 'format',
+ 'style',
+ 'license',
+ 'header'
+ ]
}
}
diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GroovyExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GroovyExtension.java
new file mode 100644
index 000000000..063cb3615
--- /dev/null
+++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GroovyExtension.java
@@ -0,0 +1,135 @@
+/*
+ * 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.util.List;
+import java.util.Objects;
+
+import org.gradle.api.GradleException;
+import org.gradle.api.Project;
+import org.gradle.api.internal.file.UnionFileCollection;
+import org.gradle.api.internal.plugins.DslObject;
+import org.gradle.api.plugins.JavaPluginConvention;
+import org.gradle.api.tasks.GroovySourceSet;
+import org.gradle.api.tasks.SourceSet;
+
+import com.diffplug.spotless.FormatterStep;
+import com.diffplug.spotless.SerializableFileFilter;
+import com.diffplug.spotless.extra.groovy.GrEclipseFormatterStep;
+import com.diffplug.spotless.generic.LicenseHeaderStep;
+import com.diffplug.spotless.java.ImportOrderStep;
+
+public class GroovyExtension extends FormatExtension {
+ static final String NAME = "groovy";
+
+ public GroovyExtension(SpotlessExtension rootExtension) {
+ super(rootExtension);
+ }
+
+ boolean excludeJava = false;
+
+ /** Excludes .java files, to focus on only .groovy files. */
+ public void excludeJava() {
+ excludeJava(true);
+ }
+
+ /** Determines whether to exclude .java files, to focus on only .groovy files. */
+ public void excludeJava(boolean excludeJava) {
+ this.excludeJava = excludeJava;
+ }
+
+ public void licenseHeader(String licenseHeader) {
+ licenseHeader(licenseHeader, JavaExtension.LICENSE_HEADER_DELIMITER);
+ }
+
+ public void licenseHeaderFile(Object licenseHeaderFile) {
+ licenseHeaderFile(licenseHeaderFile, JavaExtension.LICENSE_HEADER_DELIMITER);
+ }
+
+ public void importOrder(List importOrder) {
+ addStep(ImportOrderStep.createFromOrder(importOrder));
+ }
+
+ public void importOrderFile(Object importOrderFile) {
+ addStep(ImportOrderStep.createFromFile(getProject().file(importOrderFile)));
+ }
+
+ public GrEclipseConfig greclipse() {
+ return greclipse(GrEclipseFormatterStep.defaultVersion());
+ }
+
+ public GrEclipseConfig greclipse(String version) {
+ return new GrEclipseConfig(version);
+ }
+
+ public class GrEclipseConfig {
+ final String version;
+ Object[] configFiles;
+
+ GrEclipseConfig(String version) {
+ configFiles = new Object[0];
+ this.version = Objects.requireNonNull(version);
+ addStep(createStep());
+ }
+
+ public void configFile(Object... configFiles) {
+ this.configFiles = configFiles;
+ replaceStep(createStep());
+ }
+
+ private FormatterStep createStep() {
+ Project project = getProject();
+ return GrEclipseFormatterStep.create(version,
+ project.files(configFiles).getFiles(),
+ GradleProvisioner.fromProject(project));
+ }
+ }
+
+ /** If the user hasn't specified the files yet, we'll assume he/she means all of the groovy files. */
+ @Override
+ protected void setupTask(SpotlessTask task) {
+ if (target == null) {
+ JavaPluginConvention convention = getProject().getConvention().getPlugin(JavaPluginConvention.class);
+ if (convention == null) {
+ throw new GradleException("You must apply the groovy plugin before the spotless plugin if you are using the groovy extension.");
+ }
+ //Add all Groovy files (may contain Java files as well)
+
+ UnionFileCollection union = new UnionFileCollection();
+ for (SourceSet sourceSet : convention.getSourceSets()) {
+ GroovySourceSet groovySourceSet = new DslObject(sourceSet).getConvention().getPlugin(GroovySourceSet.class);
+ if (excludeJava) {
+ union.add(groovySourceSet.getAllGroovy());
+ } else {
+ union.add(groovySourceSet.getGroovy());
+ }
+ }
+ target = union;
+ } else if (excludeJava) {
+ throw new IllegalArgumentException("'excludeJava' is not supported in combination with a custom 'target'.");
+ }
+ // LicenseHeaderStep completely blows apart package-info.java/groovy - this common-sense check
+ // ensures that it skips both. See https://github.com/diffplug/spotless/issues/1
+ steps.replaceAll(step -> {
+ if (LicenseHeaderStep.name().equals(step.getName())) {
+ return step.filterByFile(SerializableFileFilter.skipFilesNamed("package-info.java", "package-info.groovy"));
+ } else {
+ return step;
+ }
+ });
+ super.setupTask(task);
+ }
+}
diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JavaExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JavaExtension.java
index c259db8b7..7f90a096d 100644
--- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JavaExtension.java
+++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JavaExtension.java
@@ -39,7 +39,7 @@ public JavaExtension(SpotlessExtension rootExtension) {
// If this constant changes, don't forget to change the similarly-named one in
// testlib/src/test/java/com/diffplug/spotless/generic/LicenseHeaderStepTest.java as well
- private static final String LICENSE_HEADER_DELIMITER = "package ";
+ static final String LICENSE_HEADER_DELIMITER = "package ";
public void licenseHeader(String licenseHeader) {
licenseHeader(licenseHeader, LICENSE_HEADER_DELIMITER);
diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/KotlinExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/KotlinExtension.java
index b9de108e2..410d285f2 100644
--- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/KotlinExtension.java
+++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/KotlinExtension.java
@@ -29,14 +29,12 @@ public KotlinExtension(SpotlessExtension rootExtension) {
super(rootExtension);
}
- private static final String LICENSE_HEADER_DELIMITER = "package ";
-
public void licenseHeader(String licenseHeader) {
- licenseHeader(licenseHeader, LICENSE_HEADER_DELIMITER);
+ licenseHeader(licenseHeader, JavaExtension.LICENSE_HEADER_DELIMITER);
}
public void licenseHeaderFile(Object licenseHeaderFile) {
- licenseHeaderFile(licenseHeaderFile, LICENSE_HEADER_DELIMITER);
+ licenseHeaderFile(licenseHeaderFile, JavaExtension.LICENSE_HEADER_DELIMITER);
}
/** Adds the specified version of [ktlint](https://github.com/shyiko/ktlint). */
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 301b6a7ac..6f2cc4ba1 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
@@ -91,6 +91,11 @@ public void freshmark(Action closure) {
configure(FreshMarkExtension.NAME, FreshMarkExtension.class, closure);
}
+ /** Configures the special groovy-specific extension. */
+ public void groovy(Action closure) {
+ configure(GroovyExtension.NAME, GroovyExtension.class, closure);
+ }
+
/** Configures a custom extension. */
public void format(String name, Action closure) {
configure(name, FormatExtension.class, closure);
diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/GroovyDefaultTargetTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/GroovyDefaultTargetTest.java
new file mode 100644
index 000000000..8673dbe8d
--- /dev/null
+++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/GroovyDefaultTargetTest.java
@@ -0,0 +1,107 @@
+/*
+ * 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.File;
+import java.io.IOException;
+
+import org.assertj.core.api.Assertions;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.diffplug.gradle.spotless.GradleIntegrationTest;
+
+public class GroovyDefaultTargetTest extends GradleIntegrationTest {
+
+ private final String HEADER = "//My tests header";
+
+ @Test
+ public void includeJava() throws IOException {
+ testIncludeExcludeOption(false);
+ }
+
+ @Test
+ public void excludeJava() throws IOException {
+ testIncludeExcludeOption(true);
+ }
+
+ private void testIncludeExcludeOption(boolean excludeJava) throws IOException {
+ String excludeStatement = excludeJava ? "excludeJava()" : "";
+ write("build.gradle",
+ "plugins {",
+ " id 'com.diffplug.gradle.spotless'",
+ "}",
+ "repositories { mavenLocal() }",
+ "",
+ "apply plugin: 'groovy'",
+ "",
+ "spotless {",
+ " groovy {",
+ excludeStatement,
+ " licenseHeader('" + HEADER + "')",
+ " }",
+ "}");
+
+ String original = getTestResource("groovy/licenseheader/JavaCodeWithoutHeader.test");
+
+ File javaSrcJavaFile = write("src/main/java/test.java", original);
+ File groovySrcJavaFile = write("src/main/groovy/test.java", original);
+ File groovySrcGroovyFile = write("src/main/groovy/test.groovy", original);
+
+ // write appends a line ending so re-read to see what the original currently looks like
+ original = read("src/main/java/test.java");
+
+ // Run
+ gradleRunner().withArguments("spotlessApply").build();
+
+ // Common checks
+ assertFileContent(original, javaSrcJavaFile);
+
+ Assertions.assertThat(read(groovySrcGroovyFile.toPath())).contains(HEADER);
+
+ if (excludeJava) {
+ assertFileContent(original, groovySrcJavaFile);
+ } else {
+ Assertions.assertThat(read(groovySrcJavaFile.toPath())).contains(HEADER);
+ }
+ }
+
+ @Test
+ public void excludeJavaWithCustomTarget() throws IOException {
+ write("build.gradle",
+ "plugins {",
+ " id 'com.diffplug.gradle.spotless'",
+ "}",
+ "repositories { mavenLocal() }",
+ "",
+ "apply plugin: 'groovy'",
+ "",
+ "spotless {",
+ " groovy {",
+ " excludeJava()",
+ " target '**/*.java', '**/*.groovy'",
+ " }",
+ "}");
+
+ try {
+ gradleRunner().withArguments("spotlessApply").build();
+ Assert.fail("Exception expected when running 'excludeJava' in combination with 'target'.");
+ } catch (Throwable t) {
+ Assertions.assertThat(t).hasMessageContaining("'excludeJava' is not supported");
+ }
+ }
+
+}
diff --git a/plugin-gradle/src/test/resources/groovy/licenseheader/JavaCodeWithoutHeader.test b/plugin-gradle/src/test/resources/groovy/licenseheader/JavaCodeWithoutHeader.test
new file mode 100644
index 000000000..420b75bb0
--- /dev/null
+++ b/plugin-gradle/src/test/resources/groovy/licenseheader/JavaCodeWithoutHeader.test
@@ -0,0 +1,5 @@
+package my.test
+
+class Clazz {
+
+}
\ No newline at end of file
diff --git a/spotless.groovyformat.prefs b/spotless.groovyformat.prefs
new file mode 100644
index 000000000..da2cb796c
--- /dev/null
+++ b/spotless.groovyformat.prefs
@@ -0,0 +1,2 @@
+groovy.formatter.remove.unnecessary.semicolons=true
+groovy.formatter.longListLength=1
\ No newline at end of file
diff --git a/spotlessSelf.gradle b/spotlessSelf.gradle
index 726c5ead6..a9eab5c40 100644
--- a/spotlessSelf.gradle
+++ b/spotlessSelf.gradle
@@ -4,26 +4,36 @@ plugins {
id 'java'
}
-repositories { mavenCentral() }
+repositories { jcenter() }
spotless {
+ def noInternalDepsClosure = {
+ if (it.contains('import org.gradle.internal.') &&
+ !it.contains('def noInternalDepsClosure')) {
+ throw new AssertionError("Accidental internal import")
+ }
+ }
java {
target fileTree('.') {
include '**/*.java'
exclude '_ext/*/build/**'
}
-
- custom 'noInternalDeps', {
- if (it.contains('import org.gradle.internal.')) {
- throw new AssertionError("Accidental internal import")
- }
- }
+ custom 'noInternalDeps', noInternalDepsClosure
bumpThisNumberIfACustomStepChanges(1)
-
licenseHeaderFile 'spotless.license'
importOrderFile 'spotless.importorder'
eclipseFormatFile 'spotless.eclipseformat.xml'
trimTrailingWhitespace()
}
+ groovy {
+ target fileTree('.') {
+ include '**/*.gradle'
+ exclude '_ext/**'
+ }
+ custom 'noInternalDeps', noInternalDepsClosure
+ custom 'preventFormatPingPong', { return it.replaceAll('}[ \t]+}', '}}') }
+ bumpThisNumberIfACustomStepChanges(1)
+ greclipse().configFile('spotless.eclipseformat.xml', 'spotless.groovyformat.prefs')
+ }
freshmark {
target '**/*.md'
propertiesFile('gradle.properties')
@@ -33,7 +43,7 @@ spotless {
}
}
format 'misc', {
- target '**/*.gradle', '**/*.md', '**/*.gitignore'
+ target '**/*.md', '**/*.gitignore'
indentWithTabs()
trimTrailingWhitespace()
endWithNewline()
diff --git a/testlib/build.gradle b/testlib/build.gradle
index 7903b7a45..953e1b168 100644
--- a/testlib/build.gradle
+++ b/testlib/build.gradle
@@ -13,6 +13,5 @@ dependencies {
}
// we'll hold the testlib to a low standard (prize brevity)
-findbugs {
- reportLevel = 'high' // low|medium|high (low = sensitive to even minor mistakes)
-}
+findbugs { reportLevel = 'high' } // low|medium|high (low = sensitive to even minor mistakes)
+
diff --git a/testlib/src/main/java/com/diffplug/spotless/ResourceHarness.java b/testlib/src/main/java/com/diffplug/spotless/ResourceHarness.java
index d0f740c7e..529461afa 100644
--- a/testlib/src/main/java/com/diffplug/spotless/ResourceHarness.java
+++ b/testlib/src/main/java/com/diffplug/spotless/ResourceHarness.java
@@ -76,6 +76,10 @@ protected File write(String path, LineEnding ending, Charset encoding, String...
return target.toFile();
}
+ protected String read(Path path) throws IOException {
+ return read(path, LineEnding.UNIX);
+ }
+
protected String read(String path) throws IOException {
return read(path, LineEnding.UNIX);
}
@@ -84,9 +88,17 @@ protected String read(String path, LineEnding ending) throws IOException {
return read(path, ending, StandardCharsets.UTF_8);
}
+ protected String read(Path path, LineEnding ending) throws IOException {
+ return read(path, ending, StandardCharsets.UTF_8);
+ }
+
protected String read(String path, LineEnding ending, Charset encoding) throws IOException {
Path target = newFile(path).toPath();
- String content = new String(Files.readAllBytes(target), encoding);
+ return read(target, ending, encoding);
+ }
+
+ protected String read(Path path, LineEnding ending, Charset encoding) throws IOException {
+ String content = new String(Files.readAllBytes(path), encoding);
String allUnixNewline = LineEnding.toUnix(content);
return allUnixNewline.replace("\n", ending.str());
}