From 9ab1154bf3473dbf87016610c7e936b74c20386c Mon Sep 17 00:00:00 2001 From: Ranadeep Polavarapu Date: Mon, 4 May 2020 18:05:18 -0400 Subject: [PATCH 1/3] feat(ktfmt): add `ktfmt` a new Kotlin formatter from Facebook Incubator Signed-off-by: Ranadeep Polavarapu --- CHANGES.md | 1 + README.md | 2 + .../diffplug/spotless/kotlin/KtfmtStep.java | 88 +++++++++++++++ plugin-gradle/CHANGES.md | 1 + plugin-gradle/README.md | 18 ++++ .../gradle/spotless/KotlinExtension.java | 38 ++++++- .../gradle/spotless/KotlinExtensionTest.java | 100 ++++++++++++++++++ plugin-maven/CHANGES.md | 1 + plugin-maven/README.md | 22 ++++ .../spotless/maven/kotlin/Kotlin.java | 4 + .../diffplug/spotless/maven/kotlin/Ktfmt.java | 35 ++++++ .../spotless/maven/kotlin/KtfmtTest.java | 44 ++++++++ .../main/resources/kotlin/ktfmt/basic.clean | 13 +++ .../main/resources/kotlin/ktfmt/basic.dirty | 12 +++ .../KotlinCodeWithoutHeaderKtfmt.test | 5 + .../spotless/kotlin/KtfmtStepTest.java | 56 ++++++++++ 16 files changed, 437 insertions(+), 3 deletions(-) create mode 100644 lib/src/main/java/com/diffplug/spotless/kotlin/KtfmtStep.java create mode 100644 plugin-maven/src/main/java/com/diffplug/spotless/maven/kotlin/Ktfmt.java create mode 100644 plugin-maven/src/test/java/com/diffplug/spotless/maven/kotlin/KtfmtTest.java create mode 100644 testlib/src/main/resources/kotlin/ktfmt/basic.clean create mode 100644 testlib/src/main/resources/kotlin/ktfmt/basic.dirty create mode 100644 testlib/src/main/resources/kotlin/licenseheader/KotlinCodeWithoutHeaderKtfmt.test create mode 100644 testlib/src/test/java/com/diffplug/spotless/kotlin/KtfmtStepTest.java diff --git a/CHANGES.md b/CHANGES.md index 45fd5181fb..865f982128 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -13,6 +13,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( ### Added * Support for google-java-format 1.8 (including test infrastructure for Java 11). ([#562](https://github.com/diffplug/spotless/issues/562)) * Improved PaddedCell such that it is as performant as non-padded cell - no reason not to have it always enabled. Deprecated all of `PaddedCellBulk`. ([#561](https://github.com/diffplug/spotless/pull/561)) +* Support for ktfmt 0.13 ([#569](https://github.com/diffplug/spotless/pull/569)) ### Changed * Updated a bunch of dependencies, most notably: ([#564](https://github.com/diffplug/spotless/pull/564)) * jgit `5.5.0.201909110433-r` -> `5.7.0.202003110725-r` diff --git a/README.md b/README.md index c0af450dbc..15c7f6eb2f 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,7 @@ lib('java.ImportOrderStep') +'{{yes}} | {{yes}} lib('java.RemoveUnusedImportsStep') +'{{yes}} | {{yes}} | {{no}} |', extra('java.EclipseFormatterStep') +'{{yes}} | {{yes}} | {{no}} |', lib('kotlin.KtLintStep') +'{{yes}} | {{yes}} | {{no}} |', +lib('kotlin.KtfmtStep') +'{{yes}} | {{yes}} | {{no}} |', lib('markdown.FreshMarkStep') +'{{yes}} | {{no}} | {{no}} |', lib('npm.PrettierFormatterStep') +'{{yes}} | {{yes}} | {{no}} |', lib('npm.TsFmtFormatterStep') +'{{yes}} | {{yes}} | {{no}} |', @@ -72,6 +73,7 @@ extra('wtp.EclipseWtpFormatterStep') +'{{yes}} | {{yes}} | [`java.RemoveUnusedImportsStep`](lib/src/main/java/com/diffplug/spotless/java/RemoveUnusedImportsStep.java) | :+1: | :+1: | :white_large_square: | | [`java.EclipseFormatterStep`](lib-extra/src/main/java/com/diffplug/spotless/extra/java/EclipseFormatterStep.java) | :+1: | :+1: | :white_large_square: | | [`kotlin.KtLintStep`](lib/src/main/java/com/diffplug/spotless/kotlin/KtLintStep.java) | :+1: | :+1: | :white_large_square: | +| [`kotlin.KtfmtStep`](lib/src/main/java/com/diffplug/spotless/kotlin/KtfmtStep.java) | :+1: | :+1: | :white_large_square: | | [`markdown.FreshMarkStep`](lib/src/main/java/com/diffplug/spotless/markdown/FreshMarkStep.java) | :+1: | :white_large_square: | :white_large_square: | | [`npm.PrettierFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/PrettierFormatterStep.java) | :+1: | :+1: | :white_large_square: | | [`npm.TsFmtFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/TsFmtFormatterStep.java) | :+1: | :+1: | :white_large_square: | diff --git a/lib/src/main/java/com/diffplug/spotless/kotlin/KtfmtStep.java b/lib/src/main/java/com/diffplug/spotless/kotlin/KtfmtStep.java new file mode 100644 index 0000000000..58d6503ee1 --- /dev/null +++ b/lib/src/main/java/com/diffplug/spotless/kotlin/KtfmtStep.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.kotlin; + +import java.io.IOException; +import java.io.Serializable; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Objects; + +import com.diffplug.spotless.*; + +/** Wraps up [ktfmt](https://github.com/facebookincubator/ktfmt) as a FormatterStep. */ +public class KtfmtStep { + // prevent direct instantiation + private KtfmtStep() {} + + private static final String DEFAULT_VERSION = "0.13"; + static final String NAME = "ktfmt"; + static final String PACKAGE = "com.facebook"; + static final String MAVEN_COORDINATE = PACKAGE + ":ktfmt:"; + + /** + * The format method is available in the link below. + * + * @see: + * https://github.com/facebookincubator/ktfmt/blob/master/core/src/main/java/com/facebook/ktfmt/Formatter.kt#L61-L65 + */ + static final String FORMATTER_METHOD = "format"; + + /** Creates a step which formats everything - code, import order, and unused imports. */ + public static FormatterStep create(Provisioner provisioner) { + return create(defaultVersion(), provisioner); + } + + /** Creates a step which formats everything - code, import order, and unused imports. */ + public static FormatterStep create(String version, Provisioner provisioner) { + Objects.requireNonNull(version, "version"); + Objects.requireNonNull(provisioner, "provisioner"); + return FormatterStep.createLazy( + NAME, () -> new State(version, provisioner), State::createFormat); + } + + public static String defaultVersion() { + return DEFAULT_VERSION; + } + + static final class State implements Serializable { + private static final long serialVersionUID = 1L; + + private final String pkg; + /** The jar that contains the eclipse formatter. */ + final JarState jarState; + + State(String version, Provisioner provisioner) throws IOException { + this.pkg = PACKAGE; + this.jarState = JarState.from(MAVEN_COORDINATE + version, provisioner); + } + + FormatterFunc createFormat() throws Exception { + ClassLoader classLoader = jarState.getClassLoader(); + + Class formatterClazz = classLoader.loadClass(pkg + ".ktfmt.FormatterKt"); + Method formatterMethod = formatterClazz.getMethod(FORMATTER_METHOD, String.class); + + return input -> { + try { + return (String) formatterMethod.invoke(formatterClazz, input); + } catch (InvocationTargetException e) { + throw ThrowingEx.unwrapCause(e); + } + }; + } + } +} diff --git a/plugin-gradle/CHANGES.md b/plugin-gradle/CHANGES.md index fb97df88e3..14cb44b0b5 100644 --- a/plugin-gradle/CHANGES.md +++ b/plugin-gradle/CHANGES.md @@ -5,6 +5,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( ## [Unreleased] ### Added * Support for google-java-format 1.8 (requires you to run build on Java 11) ([#562](https://github.com/diffplug/spotless/issues/562)) +* Support for ktfmt 0.13 (requires to be built with Java 11) ([#569](https://github.com/diffplug/spotless/pull/569)) ### Changed * PaddedCell is now always enabled. It is strictly better than non-padded cell, and there is no performance penalty. [See here](https://github.com/diffplug/spotless/pull/560#issuecomment-621752798) for detailed explanation. ([#561](https://github.com/diffplug/spotless/pull/561)) * Updated a bunch of dependencies, most notably jgit `5.5.0.201909110433-r` -> `5.7.0.202003110725-r`. ([#564](https://github.com/diffplug/spotless/pull/564)) diff --git a/plugin-gradle/README.md b/plugin-gradle/README.md index ebe9e958d8..dfa96243b0 100644 --- a/plugin-gradle/README.md +++ b/plugin-gradle/README.md @@ -84,6 +84,7 @@ Spotless can check and apply formatting to any plain-text file, using simple rul * [Groovy Eclipse](#groovy-eclipse)'s groovy code formatter * [FreshMark](https://github.com/diffplug/freshmark) (markdown with variables) * [ktlint](https://github.com/pinterest/ktlint) +* [ktfmt](https://github.com/facebookincubator/ktfmt) * [scalafmt](https://github.com/olafurpg/scalafmt) * [DBeaver sql format](https://dbeaver.jkiss.org/) * [Prettier: An opinionated code formatter](https://prettier.io) @@ -278,6 +279,23 @@ spotless { } ``` + + +## Applying [ktfmt](https://github.com/facebookincubator/ktfmt) to Kotlin files + +```gradle +spotless { + kotlin { + // optionally takes a version + ktfmt() + + // also supports license headers + licenseHeader '/* Licensed under Apache-2.0 */' // License header + licenseHeaderFile 'path-to-license-file' // License header file + } +} +``` + ## Applying [DBeaver](https://dbeaver.jkiss.org/) to SQL scripts 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 38e0dab504..3340291996 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 @@ -28,6 +28,7 @@ import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.kotlin.KtLintStep; +import com.diffplug.spotless.kotlin.KtfmtStep; public class KotlinExtension extends FormatExtension implements HasBuiltinDelimiterForLicense { static final String NAME = "kotlin"; @@ -68,7 +69,8 @@ public class KotlinFormatExtension { } public void userData(Map userData) { - // Copy the map to a sorted map because up-to-date checking is based on binary-equals of the serialized + // Copy the map to a sorted map because up-to-date checking is based on binary-equals of the + // serialized // representation. this.userData = userData; replaceStep(createStep()); @@ -79,13 +81,43 @@ private FormatterStep createStep() { } } - /** If the user hasn't specified the files yet, we'll assume he/she means all of the kotlin files. */ + /** Uses the [ktfmt](https://github.com/facebookincubator/ktfmt) jar to format source code. */ + public KtfmtConfig ktfmt() { + return ktfmt(KtfmtStep.defaultVersion()); + } + + /** + * Uses the given version of [ktfmt](https://github.com/facebookincubator/ktfmt) to format source + * code. + */ + public KtfmtConfig ktfmt(String version) { + Objects.requireNonNull(version); + return new KtfmtConfig(version); + } + + public class KtfmtConfig { + final String version; + + KtfmtConfig(String version) { + this.version = Objects.requireNonNull(version); + addStep(createStep()); + } + + private FormatterStep createStep() { + return KtfmtStep.create(version, GradleProvisioner.fromProject(getProject())); + } + } + + /** + * If the user hasn't specified the files yet, we'll assume he/she means all of the kotlin files. + */ @Override protected void setupTask(SpotlessTask task) { if (target == null) { JavaPluginConvention javaPlugin = getProject().getConvention().findPlugin(JavaPluginConvention.class); if (javaPlugin == null) { - throw new GradleException("You must either specify 'target' manually or apply a kotlin plugin."); + throw new GradleException( + "You must either specify 'target' manually or apply a kotlin plugin."); } FileCollection union = getProject().files(); for (SourceSet sourceSet : javaPlugin.getSourceSets()) { diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/KotlinExtensionTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/KotlinExtensionTest.java index 82a3ef1f96..e1661e1ee2 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/KotlinExtensionTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/KotlinExtensionTest.java @@ -23,6 +23,8 @@ import org.gradle.testkit.runner.BuildResult; import org.junit.Test; +import com.diffplug.spotless.JreVersion; + public class KotlinExtensionTest extends GradleIntegrationTest { private static final String HEADER = "// License Header"; private static final String HEADER_WITH_YEAR = "// License Header $YEAR"; @@ -45,6 +47,28 @@ public void integration() throws IOException { assertFile("src/main/kotlin/basic.kt").sameAsResource("kotlin/ktlint/basic.clean"); } + @Test + public void integrationKtfmt() throws IOException { + if (JreVersion.thisVm() == JreVersion._8) { + // ktfmt's dependency, google-java-format 1.8 requires a minimum of JRE 11+. + return; + } + setFile("build.gradle").toLines( + "plugins {", + " id 'nebula.kotlin' version '1.0.6'", + " id 'com.diffplug.gradle.spotless'", + "}", + "repositories { mavenCentral() }", + "spotless {", + " kotlin {", + " ktfmt()", + " }", + "}"); + setFile("src/main/kotlin/basic.kt").toResource("kotlin/ktfmt/basic.dirty"); + gradleRunner().withArguments("spotlessApply").build(); + assertFile("src/main/kotlin/basic.kt").sameAsResource("kotlin/ktfmt/basic.clean"); + } + @Test public void testWithIndentation() throws IOException { setFile("build.gradle").toLines( @@ -82,6 +106,29 @@ public void testWithHeader() throws IOException { assertFile("src/main/kotlin/test.kt").hasContent(HEADER + "\n" + getTestResource("kotlin/licenseheader/KotlinCodeWithoutHeader.test")); } + @Test + public void testWithHeaderKtfmt() throws IOException { + if (JreVersion.thisVm() == JreVersion._8) { + // ktfmt's dependency, google-java-format 1.8 requires a minimum of JRE 11+. + return; + } + setFile("build.gradle").toLines( + "plugins {", + " id 'nebula.kotlin' version '1.0.6'", + " id 'com.diffplug.gradle.spotless'", + "}", + "repositories { mavenCentral() }", + "spotless {", + " kotlin {", + " licenseHeader('" + HEADER + "')", + " ktfmt()", + " }", + "}"); + setFile("src/main/kotlin/test.kt").toResource("kotlin/licenseheader/KotlinCodeWithoutHeader.test"); + gradleRunner().withArguments("spotlessApply").build(); + assertFile("src/main/kotlin/test.kt").hasContent(HEADER + "\n" + getTestResource("kotlin/licenseheader/KotlinCodeWithoutHeaderKtfmt.test")); + } + @Test public void testWithCustomHeaderSeparator() throws IOException { setFile("build.gradle").toLines( @@ -101,6 +148,29 @@ public void testWithCustomHeaderSeparator() throws IOException { assertFile("src/main/kotlin/test.kt").hasContent(HEADER + "\n" + getTestResource("kotlin/licenseheader/KotlinCodeWithoutHeader.test")); } + @Test + public void testWithCustomHeaderSeparatorKtfmt() throws IOException { + if (JreVersion.thisVm() == JreVersion._8) { + // ktfmt's dependency, google-java-format 1.8 requires a minimum of JRE 11+. + return; + } + setFile("build.gradle").toLines( + "plugins {", + " id 'nebula.kotlin' version '1.0.6'", + " id 'com.diffplug.gradle.spotless'", + "}", + "repositories { mavenCentral() }", + "spotless {", + " kotlin {", + " licenseHeader ('" + HEADER + "', '@file')", + " ktfmt()", + " }", + "}"); + setFile("src/main/kotlin/test.kt").toResource("kotlin/licenseheader/KotlinCodeWithoutHeader.test"); + gradleRunner().withArguments("spotlessApply").build(); + assertFile("src/main/kotlin/test.kt").hasContent(HEADER + "\n" + getTestResource("kotlin/licenseheader/KotlinCodeWithoutHeaderKtfmt.test")); + } + @Test public void testWithNonStandardYearSeparator() throws IOException { setFile("build.gradle").toLines( @@ -126,4 +196,34 @@ public void testWithNonStandardYearSeparator() throws IOException { matcher.startsWith(HEADER_WITH_YEAR.replace("$YEAR", String.valueOf(YearMonth.now().getYear()))); }); } + + @Test + public void testWithNonStandardYearSeparatorKtfmt() throws IOException { + if (JreVersion.thisVm() == JreVersion._8) { + // ktfmt's dependency, google-java-format 1.8 requires a minimum of JRE 11+. + return; + } + setFile("build.gradle").toLines( + "plugins {", + " id 'nebula.kotlin' version '1.0.6'", + " id 'com.diffplug.gradle.spotless'", + "}", + "repositories { mavenCentral() }", + "spotless {", + " kotlin {", + " licenseHeader('" + HEADER_WITH_YEAR + "').yearSeparator(', ')", + " ktfmt()", + " }", + "}"); + + setFile("src/main/kotlin/test.kt").toResource("kotlin/licenseheader/KotlinCodeWithMultiYearHeader.test"); + setFile("src/main/kotlin/test2.kt").toResource("kotlin/licenseheader/KotlinCodeWithMultiYearHeader2.test"); + gradleRunner().withArguments("spotlessApply").build(); + assertFile("src/main/kotlin/test.kt").matches(matcher -> { + matcher.startsWith("// License Header 2012, 2014"); + }); + assertFile("src/main/kotlin/test2.kt").matches(matcher -> { + matcher.startsWith(HEADER_WITH_YEAR.replace("$YEAR", String.valueOf(YearMonth.now().getYear()))); + }); + } } diff --git a/plugin-maven/CHANGES.md b/plugin-maven/CHANGES.md index 502f16d7c8..2c08bfd651 100644 --- a/plugin-maven/CHANGES.md +++ b/plugin-maven/CHANGES.md @@ -7,6 +7,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( * Support for google-java-format 1.8 (requires you to run build on Java 11) ([#562](https://github.com/diffplug/spotless/issues/562)) * `mvn spotless:apply` is now guaranteed to be idempotent, even if some of the formatters are not. See [`PADDEDCELL.md` for details](https://github.com/diffplug/spotless/blob/master/PADDEDCELL.md) if you're curious. ([#565](https://github.com/diffplug/spotless/pull/565)) * Updated a bunch of dependencies, most notably jgit `5.5.0.201909110433-r` -> `5.7.0.202003110725-r`. ([#564](https://github.com/diffplug/spotless/pull/564)) +* Support for ktfmt 0.13 (requires to be built with Java 11) ([#569](https://github.com/diffplug/spotless/pull/569)) ## [1.30.0] - 2020-04-10 ### Added diff --git a/plugin-maven/README.md b/plugin-maven/README.md index 34610ea2bd..517f51e527 100644 --- a/plugin-maven/README.md +++ b/plugin-maven/README.md @@ -153,6 +153,8 @@ By default, all files matching `src/main/scala/**/*.scala`, `src/test/scala/**/* By default, all files matching `src/main/kotlin/**/*.kt` and `src/test/kotlin/**/*.kt` Ant style pattern will be formatted. Each element under `` is a step, and they will be applied in the order specified. Every step is optional. +### Applying [ktlint](https://github.com/pinterest/ktlint) to Kotlin files + ```xml @@ -171,6 +173,26 @@ By default, all files matching `src/main/kotlin/**/*.kt` and `src/test/kotlin/** ``` +### Applying [ktfmt](https://github.com/facebookincubator/ktfmt) to Kotlin files + +```xml + + + + + /* Licensed under Apache-2.0 */ + ${basedir}/license-header + + + + + + 0.11 + + + +``` + ## Applying to C/C++ source diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/kotlin/Kotlin.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/kotlin/Kotlin.java index 51618613a4..dcfce10fc4 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/kotlin/Kotlin.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/kotlin/Kotlin.java @@ -39,4 +39,8 @@ public String licenseHeaderDelimiter() { public void addKtlint(Ktlint ktlint) { addStepFactory(ktlint); } + + public void addKtfmt(Ktfmt ktfmt) { + addStepFactory(ktfmt); + } } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/kotlin/Ktfmt.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/kotlin/Ktfmt.java new file mode 100644 index 0000000000..a5d99f81f4 --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/kotlin/Ktfmt.java @@ -0,0 +1,35 @@ +/* + * 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.maven.kotlin; + +import org.apache.maven.plugins.annotations.Parameter; + +import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.kotlin.KtfmtStep; +import com.diffplug.spotless.maven.FormatterStepConfig; +import com.diffplug.spotless.maven.FormatterStepFactory; + +public class Ktfmt implements FormatterStepFactory { + + @Parameter + private String version; + + @Override + public FormatterStep newFormatterStep(FormatterStepConfig config) { + String version = this.version != null ? this.version : KtfmtStep.defaultVersion(); + return KtfmtStep.create(version, config.getProvisioner()); + } +} diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/kotlin/KtfmtTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/kotlin/KtfmtTest.java new file mode 100644 index 0000000000..d87c15a503 --- /dev/null +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/kotlin/KtfmtTest.java @@ -0,0 +1,44 @@ +/* + * 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.maven.kotlin; + +import org.junit.Test; + +import com.diffplug.spotless.JreVersion; +import com.diffplug.spotless.maven.MavenIntegrationTest; + +public class KtfmtTest extends MavenIntegrationTest { + @Test + public void testKtfmt() throws Exception { + if (JreVersion.thisVm() == JreVersion._8) { + // ktfmt's dependency, google-java-format 1.8 requires a minimum of JRE 11+. + return; + } + + writePomWithKotlinSteps(""); + + String path1 = "src/main/kotlin/main1.kt"; + String path2 = "src/main/kotlin/main2.kt"; + + setFile(path1).toResource("kotlin/ktfmt/basic.dirty"); + setFile(path2).toResource("kotlin/ktfmt/basic.dirty"); + + mavenRunner().withArguments("spotless:apply").runNoError(); + + assertFile(path1).sameAsResource("kotlin/ktfmt/basic.clean"); + assertFile(path2).sameAsResource("kotlin/ktfmt/basic.clean"); + } +} diff --git a/testlib/src/main/resources/kotlin/ktfmt/basic.clean b/testlib/src/main/resources/kotlin/ktfmt/basic.clean new file mode 100644 index 0000000000..668c9bd20d --- /dev/null +++ b/testlib/src/main/resources/kotlin/ktfmt/basic.clean @@ -0,0 +1,13 @@ +import a.* +import a.b +import a.b.c.* +import kotlinx.android.synthetic.main.layout_name.* + +fun main() { + fun name() { + a(); + return b + } + println(";") + println(); +} diff --git a/testlib/src/main/resources/kotlin/ktfmt/basic.dirty b/testlib/src/main/resources/kotlin/ktfmt/basic.dirty new file mode 100644 index 0000000000..1a76f25fcc --- /dev/null +++ b/testlib/src/main/resources/kotlin/ktfmt/basic.dirty @@ -0,0 +1,12 @@ +import a.* + +import kotlinx.android.synthetic.main.layout_name.* + +import a.b.c.* +import a.b + +fun main() { + fun name() { a(); return b } + println(";") + println(); +} diff --git a/testlib/src/main/resources/kotlin/licenseheader/KotlinCodeWithoutHeaderKtfmt.test b/testlib/src/main/resources/kotlin/licenseheader/KotlinCodeWithoutHeaderKtfmt.test new file mode 100644 index 0000000000..16ba57b2d4 --- /dev/null +++ b/testlib/src/main/resources/kotlin/licenseheader/KotlinCodeWithoutHeaderKtfmt.test @@ -0,0 +1,5 @@ +@file:JvmName("SomeFileName") + +package my.test + +object AnObject diff --git a/testlib/src/test/java/com/diffplug/spotless/kotlin/KtfmtStepTest.java b/testlib/src/test/java/com/diffplug/spotless/kotlin/KtfmtStepTest.java new file mode 100644 index 0000000000..602ddc5dae --- /dev/null +++ b/testlib/src/test/java/com/diffplug/spotless/kotlin/KtfmtStepTest.java @@ -0,0 +1,56 @@ +/* + * 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.kotlin; + +import org.junit.Ignore; +import org.junit.Test; + +import com.diffplug.spotless.*; + +@Ignore +public class KtfmtStepTest extends ResourceHarness { + @Test + public void behavior() throws Exception { + if (JreVersion.thisVm() == JreVersion._8) { + // ktfmt's dependency, google-java-format 1.8 requires a minimum of JRE 11+. + return; + } + FormatterStep step = KtfmtStep.create(TestProvisioner.mavenCentral()); + StepHarness.forStep(step).testResource("kotlin/ktfmt/basic.dirty", "kotlin/ktfmt/basic.clean"); + } + + @Test + public void equality() throws Exception { + new SerializableEqualityTester() { + String version = "0.13"; + + @Override + protected void setupTest(API api) { + // same version == same + api.areDifferentThan(); + // change the version, and it's different + version = "0.12"; + api.areDifferentThan(); + } + + @Override + protected FormatterStep create() { + String finalVersion = this.version; + return KtfmtStep.create(finalVersion, TestProvisioner.mavenCentral()); + } + }.testEquals(); + } +} From 686775aa7e5cf6a96b25789bfaa7dc4ea1e946a9 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Mon, 4 May 2020 17:33:12 -0700 Subject: [PATCH 2/3] Remove unrelated formatting changes. --- .../com/diffplug/gradle/spotless/KotlinExtension.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) 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 3340291996..0feacb8575 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 @@ -69,8 +69,7 @@ public class KotlinFormatExtension { } public void userData(Map userData) { - // Copy the map to a sorted map because up-to-date checking is based on binary-equals of the - // serialized + // Copy the map to a sorted map because up-to-date checking is based on binary-equals of the serialized // representation. this.userData = userData; replaceStep(createStep()); @@ -108,16 +107,13 @@ private FormatterStep createStep() { } } - /** - * If the user hasn't specified the files yet, we'll assume he/she means all of the kotlin files. - */ + /** If the user hasn't specified the files yet, we'll assume he/she means all of the kotlin files. */ @Override protected void setupTask(SpotlessTask task) { if (target == null) { JavaPluginConvention javaPlugin = getProject().getConvention().findPlugin(JavaPluginConvention.class); if (javaPlugin == null) { - throw new GradleException( - "You must either specify 'target' manually or apply a kotlin plugin."); + throw new GradleException("You must either specify 'target' manually or apply a kotlin plugin."); } FileCollection union = getProject().files(); for (SourceSet sourceSet : javaPlugin.getSourceSets()) { From d549f8fd8da70437eb38566bd353d6ad413b8f40 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Mon, 4 May 2020 17:37:06 -0700 Subject: [PATCH 3/3] Use consistent language for "requires build to run on Java 11+" across different formatters and changelogs. --- plugin-gradle/CHANGES.md | 4 ++-- plugin-maven/CHANGES.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugin-gradle/CHANGES.md b/plugin-gradle/CHANGES.md index 14cb44b0b5..be097cc0ac 100644 --- a/plugin-gradle/CHANGES.md +++ b/plugin-gradle/CHANGES.md @@ -4,8 +4,8 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( ## [Unreleased] ### Added -* Support for google-java-format 1.8 (requires you to run build on Java 11) ([#562](https://github.com/diffplug/spotless/issues/562)) -* Support for ktfmt 0.13 (requires to be built with Java 11) ([#569](https://github.com/diffplug/spotless/pull/569)) +* Support for google-java-format 1.8 (requires build to run on Java 11+) ([#562](https://github.com/diffplug/spotless/issues/562)) +* Support for ktfmt 0.13 (requires build to run on Java 11+) ([#569](https://github.com/diffplug/spotless/pull/569)) ### Changed * PaddedCell is now always enabled. It is strictly better than non-padded cell, and there is no performance penalty. [See here](https://github.com/diffplug/spotless/pull/560#issuecomment-621752798) for detailed explanation. ([#561](https://github.com/diffplug/spotless/pull/561)) * Updated a bunch of dependencies, most notably jgit `5.5.0.201909110433-r` -> `5.7.0.202003110725-r`. ([#564](https://github.com/diffplug/spotless/pull/564)) diff --git a/plugin-maven/CHANGES.md b/plugin-maven/CHANGES.md index 2c08bfd651..744cec81e1 100644 --- a/plugin-maven/CHANGES.md +++ b/plugin-maven/CHANGES.md @@ -4,10 +4,10 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( ## [Unreleased] ### Added -* Support for google-java-format 1.8 (requires you to run build on Java 11) ([#562](https://github.com/diffplug/spotless/issues/562)) +* Support for google-java-format 1.8 (requires build to run on Java 11+) ([#562](https://github.com/diffplug/spotless/issues/562)) +* Support for ktfmt 0.13 (requires build to run on Java 11+) ([#569](https://github.com/diffplug/spotless/pull/569)) * `mvn spotless:apply` is now guaranteed to be idempotent, even if some of the formatters are not. See [`PADDEDCELL.md` for details](https://github.com/diffplug/spotless/blob/master/PADDEDCELL.md) if you're curious. ([#565](https://github.com/diffplug/spotless/pull/565)) * Updated a bunch of dependencies, most notably jgit `5.5.0.201909110433-r` -> `5.7.0.202003110725-r`. ([#564](https://github.com/diffplug/spotless/pull/564)) -* Support for ktfmt 0.13 (requires to be built with Java 11) ([#569](https://github.com/diffplug/spotless/pull/569)) ## [1.30.0] - 2020-04-10 ### Added