Skip to content
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

Support KtLint 0.34+ #469

Merged
merged 9 commits into from Oct 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGES.md
Expand Up @@ -7,6 +7,8 @@ You might be looking for:

### Version 1.25.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/))

* Add support for ktlint `0.34+`, and bump default version from `0.32.0` to `0.34.2`. ([#469](https://github.com/diffplug/spotless/pull/469))

### Version 1.24.3 - September 23rd 2019 (javadoc [lib](https://diffplug.github.io/spotless/javadoc/spotless-lib/1.24.3/) [lib-extra](https://diffplug.github.io/spotless/javadoc/spotless-lib-extra/1.24.3/), artifact [lib]([jcenter](https://bintray.com/diffplug/opensource/spotless-lib), [lib-extra]([jcenter](https://bintray.com/diffplug/opensource/spotless-lib-extra)))

* Update jgit from `5.3.2.201906051522-r` to `5.5.0.201909110433-r`. ([#445](https://github.com/diffplug/spotless/pull/445))
Expand Down Expand Up @@ -200,7 +202,7 @@ You might be looking for:
### Version 1.1.0 - February 27th 2017 (javadoc [lib](https://diffplug.github.io/spotless/javadoc/spotless-lib/1.1.0/) [lib-extra](https://diffplug.github.io/spotless/javadoc/spotless-lib-extra/1.1.0/), artifact [lib]([jcenter](https://bintray.com/diffplug/opensource/spotless-lib), [lib-extra]([jcenter](https://bintray.com/diffplug/opensource/spotless-lib-extra)))

* Added support for Scala via [scalafmt](https://github.com/olafurpg/scalafmt).
* Added support for Kotlin via [ktlint](https://github.com/shyiko/ktlint).
* Added support for Kotlin via [ktlint](https://github.com/pinterest/ktlint).
* Better error messages for JarState.
* Improved test harnessing.
* Formatter now has pluggable exception policies,
Expand Down
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -108,7 +108,7 @@ Once someone has filled in one square of the formatter/build system matrix, it's
- Thanks to [Oliver Horn](https://github.com/ohorn) for adding AOSP support for Spotless' google-java-format integration.
- 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!
- Thanks to [Zac Sweers](https://github.com/ZacSweers) for multiple build updates and fixing a gradle deprecation warning ([#434](https://github.com/diffplug/spotless/pull/434) and others).
- Thanks to [Zac Sweers](https://github.com/ZacSweers) for fixing the highly requested ktlint 0.34+ support ([#469](https://github.com/diffplug/spotless/pull/469)), multiple build updates and fixing a gradle deprecation warning ([#434](https://github.com/diffplug/spotless/pull/434) and others).
- Thanks to [Nelson Osacky](https://github.com/runningcode) for android doc improvements, versions bump, and a build improvement.
- Thanks to [Stanley Shyiko](https://github.com/shyiko) for his help integrating [ktlint](https://github.com/shyiko/ktlint).
- Thanks to [Jonathan Leitschuh](https://github.com/JLLeitschuh) for adding [ktlint](https://github.com/shyiko/ktlint) support for [Gradle Kotlin DSL](https://github.com/gradle/kotlin-dsl) files.
Expand Down
76 changes: 59 additions & 17 deletions lib/src/main/java/com/diffplug/spotless/kotlin/KtLintStep.java
Expand Up @@ -17,6 +17,7 @@

import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
Expand All @@ -33,13 +34,13 @@
import com.diffplug.spotless.Provisioner;
import com.diffplug.spotless.ThrowingEx;

/** Wraps up [ktlint](https://github.com/shyiko/ktlint) as a FormatterStep. */
/** Wraps up [ktlint](https://github.com/pinterest/ktlint) as a FormatterStep. */
public class KtLintStep {
// prevent direct instantiation
private KtLintStep() {}

private static final Pattern VERSION_PRE_0_32 = Pattern.compile("0\\.(\\d+)\\.\\d+");
private static final String DEFAULT_VERSION = "0.32.0";
private static final Pattern VERSION_MATCHER = Pattern.compile("0\\.(\\d+)\\.\\d+");
private static final String DEFAULT_VERSION = "0.34.2";
static final String NAME = "ktlint";
static final String PACKAGE_PRE_0_32 = "com.github.shyiko";
static final String PACKAGE = "com.pinterest";
Expand Down Expand Up @@ -87,18 +88,21 @@ static final class State implements Serializable {
/** The jar that contains the eclipse formatter. */
final JarState jarState;
private final TreeMap<String, String> userData;
private final boolean useParams;

State(String version, Provisioner provisioner, boolean isScript, Map<String, String> userData) throws IOException {
this.userData = new TreeMap<>(userData);
String coordinate;
Matcher matcher = VERSION_PRE_0_32.matcher(version);
if (matcher.matches() && Integer.parseInt(matcher.group(1)) < 32) {
Matcher matcher = VERSION_MATCHER.matcher(version);
boolean matches = matcher.matches();
if (matches && Integer.parseInt(matcher.group(1)) < 32) {
coordinate = MAVEN_COORDINATE_PRE_0_32;
this.pkg = PACKAGE_PRE_0_32;
} else {
coordinate = MAVEN_COORDINATE;
this.pkg = PACKAGE;
}
this.useParams = matches && Integer.parseInt(matcher.group(1)) >= 34;
this.jarState = JarState.from(coordinate + version, provisioner);
this.isScript = isScript;
}
Expand Down Expand Up @@ -135,18 +139,56 @@ FormatterFunc createFormat() throws Exception {
// grab the KtLint singleton
Class<?> ktlintClass = classLoader.loadClass(pkg + ".ktlint.core.KtLint");
Object ktlint = ktlintClass.getDeclaredField("INSTANCE").get(null);
// and its format method
String formatterMethodName = isScript ? "formatScript" : "format";
Method formatterMethod = ktlintClass.getMethod(formatterMethodName, String.class, Iterable.class, Map.class, function2Interface);

return input -> {
try {
String formatted = (String) formatterMethod.invoke(ktlint, input, ruleSets, userData, formatterCallback);
return formatted;
} catch (InvocationTargetException e) {
throw ThrowingEx.unwrapCause(e);
}
};
FormatterFunc formatterFunc;
if (useParams) {
//
// In KtLint 0.34+ there is a new "format(params: Params)" function. We create an
// instance of the Params class with our configuration and invoke it here.
//

// grab the Params class
Class<?> paramsClass = classLoader.loadClass(pkg + ".ktlint.core.KtLint$Params");
// and its constructor
Constructor<?> constructor = paramsClass.getConstructor(
/* fileName, nullable */ String.class,
/* text */ String.class,
/* ruleSets */ Iterable.class,
/* userData */ Map.class,
/* callback */ function2Interface,
/* script */ boolean.class,
/* editorConfigPath, nullable */ String.class,
/* debug */ boolean.class);
Method formatterMethod = ktlintClass.getMethod("format", paramsClass);
formatterFunc = input -> {
try {
Object params = constructor.newInstance(
/* fileName, nullable */ null,
/* text */ input,
/* ruleSets */ ruleSets,
/* userData */ userData,
/* callback */ formatterCallback,
/* script */ isScript,
/* editorConfigPath, nullable */ null,
/* debug */ false);
return (String) formatterMethod.invoke(ktlint, params);
} catch (InvocationTargetException e) {
throw ThrowingEx.unwrapCause(e);
}
};
} else {
// and its format method
String formatterMethodName = isScript ? "formatScript" : "format";
Method formatterMethod = ktlintClass.getMethod(formatterMethodName, String.class, Iterable.class, Map.class, function2Interface);
formatterFunc = input -> {
try {
return (String) formatterMethod.invoke(ktlint, input, ruleSets, userData, formatterCallback);
} catch (InvocationTargetException e) {
throw ThrowingEx.unwrapCause(e);
}
};
}

return formatterFunc;
}
}
}
3 changes: 2 additions & 1 deletion plugin-gradle/CHANGES.md
Expand Up @@ -4,6 +4,7 @@

* Spotless no longer breaks configuration avoidance for other tasks (specifically the `check` task and all of its dependees) ([#463](https://github.com/diffplug/spotless/pull/463)).
* Important change: **Formerly, Spotless did not create its tasks until the `afterEvaluate` phase. Spotless now creates them as soon as the plugin is applied**, and it creates the format-specific tasks as soon as the formats are defined. There is no performance degradation associated with this change, and it makes configuring Spotless easier.
* Add support for ktlint `0.34+`, and bump default version from `0.32.0` to `0.34.2`. ([#469](https://github.com/diffplug/spotless/pull/469))

### Version 3.24.3 - September 23rd 2019 ([javadoc](https://diffplug.github.io/spotless/javadoc/spotless-plugin-gradle/3.24.3/), [jcenter](https://bintray.com/diffplug/opensource/spotless-plugin-gradle/3.24.3))

Expand Down Expand Up @@ -218,7 +219,7 @@
### Version 3.1.0 - February 27th 2017 ([javadoc](https://diffplug.github.io/spotless/javadoc/spotless-plugin-gradle/3.1.0/), [jcenter](https://bintray.com/diffplug/opensource/spotless-plugin-gradle/3.1.0))

* Added support for Scala via [scalafmt](https://github.com/olafurpg/scalafmt).
* Added support for Kotlin via [ktlint](https://github.com/shyiko/ktlint).
* Added support for Kotlin via [ktlint](https://github.com/pinterest/ktlint).
* Added `FormatExtension::replaceStep`.
* `paddedCell()` is no longer required if a misbehaving rule converges.
* Any errors in a step will now fail the build - previously they were only warned.
Expand Down
4 changes: 2 additions & 2 deletions plugin-gradle/README.md
Expand Up @@ -83,7 +83,7 @@ Spotless can check and apply formatting to any plain-text file, using simple rul
* Google's [google-java-format](https://github.com/google/google-java-format)
* [Groovy Eclipse](#groovy-eclipse)'s groovy code formatter
* [FreshMark](https://github.com/diffplug/freshmark) (markdown with variables)
* [ktlint](https://github.com/shyiko/ktlint)
* [ktlint](https://github.com/pinterest/ktlint)
* [scalafmt](https://github.com/olafurpg/scalafmt)
* [DBeaver sql format](https://dbeaver.jkiss.org/)
* [Prettier: An opinionated code formatter](https://prettier.io)
Expand Down Expand Up @@ -252,7 +252,7 @@ spotless {

<a name="ktlint"></a>

## Applying [ktlint](https://github.com/shyiko/ktlint) to Kotlin files
## Applying [ktlint](https://github.com/pinterest/ktlint) to Kotlin files

```gradle
spotless {
Expand Down
Expand Up @@ -46,7 +46,7 @@ public LicenseHeaderConfig licenseHeaderFile(Object licenseHeaderFile) {
return licenseHeaderFile(licenseHeaderFile, LICENSE_HEADER_DELIMITER);
}

/** Adds the specified version of [ktlint](https://github.com/shyiko/ktlint). */
/** Adds the specified version of [ktlint](https://github.com/pinterest/ktlint). */
public KotlinFormatExtension ktlint(String version) {
Objects.requireNonNull(version);
return new KotlinFormatExtension(version, Collections.emptyMap());
Expand Down
Expand Up @@ -32,7 +32,7 @@ public KotlinGradleExtension(SpotlessExtension rootExtension) {
super(rootExtension);
}

/** Adds the specified version of [ktlint](https://github.com/shyiko/ktlint). */
/** Adds the specified version of [ktlint](https://github.com/pinterest/ktlint). */
public KotlinFormatExtension ktlint(String version) {
Objects.requireNonNull(version, "version");
return new KotlinFormatExtension(version, Collections.emptyMap());
Expand Down
Expand Up @@ -74,7 +74,7 @@ public void integration_default() throws IOException {
}

@Test
public void integration_shyiko() throws IOException {
public void integration_pinterest() throws IOException {
setFile("build.gradle").toLines(
"plugins {",
" id 'nebula.kotlin' version '1.0.6'",
Expand Down
2 changes: 2 additions & 0 deletions plugin-maven/CHANGES.md
Expand Up @@ -2,6 +2,8 @@

### Version 1.25.0-SNAPSHOT - TBD ([javadoc](https://diffplug.github.io/spotless/javadoc/spotless-maven-plugin/snapshot/), [snapshot](https://oss.sonatype.org/content/repositories/snapshots/com/diffplug/spotless/spotless-maven-plugin/))

* Add support for ktlint `0.34+`, and bump default version from `0.32.0` to `0.34.2`. ([#469](https://github.com/diffplug/spotless/pull/469))

### Version 1.24.3 - September 23rd 2019 ([javadoc](https://diffplug.github.io/spotless/javadoc/spotless-maven-plugin/1.24.3/), [jcenter](https://bintray.com/diffplug/opensource/spotless-maven-plugin/1.24.3))

* Update jgit from `5.3.2.201906051522-r` to `5.5.0.201909110433-r`. ([#445](https://github.com/diffplug/spotless/pull/445))
Expand Down
2 changes: 1 addition & 1 deletion plugin-maven/README.md
Expand Up @@ -162,7 +162,7 @@ By default, all files matching `src/main/kotlin/**/*.kt` and `src/test/kotlin/**
<endWithNewLine/>
<trimTrailingWhitespace/>
<ktlint>
<!-- Optional, available versions: https://github.com/shyiko/ktlint/releases -->
<!-- Optional, available versions: https://github.com/pinterest/ktlint/releases -->
<version>0.14.0</version>
</ktlint>
</kotlin>
Expand Down
Expand Up @@ -52,8 +52,11 @@ public void worksShyiko() throws Exception {
});
}

// Regression test to ensure it works on the version it switched to Pinterest (version 0.32.0)
// but before 0.34.
// https://github.com/diffplug/spotless/issues/419
@Test
public void worksPinterest() throws Exception {
public void worksPinterestAndPre034() throws Exception {
// Must use jcenter because `com.andreapivetta.kolor:kolor:0.0.2` isn't available on mavenCentral.
// It is a dependency of ktlint.
FormatterStep step = KtLintStep.create("0.32.0", TestProvisioner.jcenter());
Expand Down