Skip to content

Commit 67978ab

Browse files
committed
Update KtLint min version to 0.46.0 and default version to 0.46.1
Closes #1239
1 parent bab36df commit 67978ab

File tree

7 files changed

+37
-143
lines changed

7 files changed

+37
-143
lines changed

CHANGES.md

+3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
1212
## [Unreleased]
1313
### Added
1414
* Support for `MAC_CLASSIC` (`\r`) line ending ([#1243](https://github.com/diffplug/spotless/pull/1243) fixes [#1196](https://github.com/diffplug/spotless/issues/1196))
15+
### Changes
16+
* Bump default `ktlint` version to latest `0.45.2` -> `0.46.1` [#1239](https://github.com/diffplug/spotless/issues/1239)
17+
* Note that we now require `ktlint >= 0.46.0` due to frequent compatibility breakages
1518

1619
## [2.26.2] - 2022-06-11
1720
### Fixed

lib/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ dependencies {
4545
}
4646
}
4747

48-
String VER_KTLINT='0.45.2'
48+
String VER_KTLINT='0.46.1'
4949
ktlintCompileOnly "com.pinterest:ktlint:$VER_KTLINT"
5050
ktlintCompileOnly "com.pinterest.ktlint:ktlint-core:$VER_KTLINT"
5151
ktlintCompileOnly "com.pinterest.ktlint:ktlint-ruleset-experimental:$VER_KTLINT"

lib/src/ktlint/java/com/diffplug/spotless/glue/ktlint/KtlintFormatterFunc.java

+16-28
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import java.util.stream.Collectors;
2525
import java.util.stream.Stream;
2626

27+
import org.jetbrains.annotations.NotNull;
28+
2729
import com.pinterest.ktlint.core.KtLint;
2830
import com.pinterest.ktlint.core.KtLint.ExperimentalParams;
2931
import com.pinterest.ktlint.core.LintError;
@@ -46,6 +48,7 @@ public class KtlintFormatterFunc implements FormatterFunc.NeedsFile {
4648
private final Map<String, String> userData;
4749
private final Function2<? super LintError, ? super Boolean, Unit> formatterCallback;
4850
private final boolean isScript;
51+
@NotNull
4952
private final EditorConfigOverride editorConfigOverride;
5053

5154
/**
@@ -64,7 +67,7 @@ public KtlintFormatterFunc(boolean isScript, boolean useExperimental, Map<String
6467
this.isScript = isScript;
6568

6669
if (editorConfigOverrideMap.isEmpty()) {
67-
this.editorConfigOverride = null;
70+
this.editorConfigOverride = EditorConfigOverride.Companion.getEmptyEditorConfigOverride();
6871
} else {
6972
this.editorConfigOverride = createEditorConfigOverride(editorConfigOverrideMap);
7073
}
@@ -83,7 +86,7 @@ private EditorConfigOverride createEditorConfigOverride(Map<String, Object> edit
8386

8487
// Create a mapping of properties to their names based on rule properties and default properties
8588
Map<String, UsesEditorConfigProperties.EditorConfigProperty<?>> supportedProperties = Stream
86-
.concat(ruleProperties, DefaultEditorConfigProperties.INSTANCE.getDefaultEditorConfigProperties().stream())
89+
.concat(ruleProperties, DefaultEditorConfigProperties.INSTANCE.getEditorConfigProperties().stream())
8790
.distinct()
8891
.collect(Collectors.toMap(property -> property.getType().getName(), property -> property));
8992

@@ -116,31 +119,16 @@ public Unit invoke(LintError lint, Boolean corrected) {
116119

117120
@Override
118121
public String applyWithFile(String unix, File file) throws Exception {
119-
120-
if (editorConfigOverride != null) {
121-
// Use ExperimentalParams with EditorConfigOverride which requires KtLint 0.45.2
122-
return KtLint.INSTANCE.format(new ExperimentalParams(
123-
file.getName(),
124-
unix,
125-
rulesets,
126-
userData,
127-
formatterCallback,
128-
isScript,
129-
null,
130-
false,
131-
editorConfigOverride,
132-
false));
133-
} else {
134-
// Use Params for backward compatibility
135-
return KtLint.INSTANCE.format(new KtLint.Params(
136-
file.getName(),
137-
unix,
138-
rulesets,
139-
userData,
140-
formatterCallback,
141-
isScript,
142-
null,
143-
false));
144-
}
122+
return KtLint.INSTANCE.format(new ExperimentalParams(
123+
file.getName(),
124+
unix,
125+
rulesets,
126+
userData,
127+
formatterCallback,
128+
isScript,
129+
null,
130+
false,
131+
editorConfigOverride,
132+
false));
145133
}
146134
}

lib/src/main/java/com/diffplug/spotless/kotlin/KtLintStep.java

+7-79
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,6 @@
1818
import java.io.IOException;
1919
import java.io.Serializable;
2020
import java.lang.reflect.Constructor;
21-
import java.lang.reflect.InvocationTargetException;
22-
import java.lang.reflect.Method;
23-
import java.lang.reflect.Proxy;
24-
import java.util.ArrayList;
2521
import java.util.Collections;
2622
import java.util.Map;
2723
import java.util.Objects;
@@ -31,18 +27,15 @@
3127
import com.diffplug.spotless.FormatterStep;
3228
import com.diffplug.spotless.JarState;
3329
import com.diffplug.spotless.Provisioner;
34-
import com.diffplug.spotless.ThrowingEx;
3530

3631
/** Wraps up <a href="https://github.com/pinterest/ktlint">ktlint</a> as a FormatterStep. */
3732
public class KtLintStep {
3833
// prevent direct instantiation
3934
private KtLintStep() {}
4035

41-
private static final String DEFAULT_VERSION = "0.45.2";
36+
private static final String DEFAULT_VERSION = "0.46.1";
4237
static final String NAME = "ktlint";
43-
static final String PACKAGE_PRE_0_32 = "com.github.shyiko";
4438
static final String PACKAGE = "com.pinterest";
45-
static final String MAVEN_COORDINATE_PRE_0_32 = PACKAGE_PRE_0_32 + ":ktlint:";
4639
static final String MAVEN_COORDINATE = PACKAGE + ":ktlint:";
4740

4841
public static FormatterStep create(Provisioner provisioner) {
@@ -85,95 +78,30 @@ static final class State implements Serializable {
8578

8679
/** Are the files being linted Kotlin script files. */
8780
private final boolean isScript;
88-
private final String pkg;
8981
/** The jar that contains the formatter. */
9082
final JarState jarState;
9183
private final boolean useExperimental;
9284
private final TreeMap<String, String> userData;
9385
private final TreeMap<String, Object> editorConfigOverride;
94-
private final boolean useParams;
9586

9687
State(String version, Provisioner provisioner, boolean isScript, boolean useExperimental,
9788
Map<String, String> userData, Map<String, Object> editorConfigOverride) throws IOException {
9889

99-
if (!editorConfigOverride.isEmpty() &&
100-
BadSemver.version(version) < BadSemver.version(0, 45, 2)) {
101-
throw new IllegalStateException("KtLint editorConfigOverride supported for version 0.45.2 and later");
90+
if (BadSemver.version(version) < BadSemver.version(0, 46, 0)) {
91+
throw new IllegalStateException("KtLint versions < 0.46.0 not supported!");
10292
}
10393

10494
this.useExperimental = useExperimental;
10595
this.userData = new TreeMap<>(userData);
10696
this.editorConfigOverride = new TreeMap<>(editorConfigOverride);
107-
String coordinate;
108-
if (BadSemver.version(version) < BadSemver.version(0, 32)) {
109-
coordinate = MAVEN_COORDINATE_PRE_0_32;
110-
this.pkg = PACKAGE_PRE_0_32;
111-
} else {
112-
coordinate = MAVEN_COORDINATE;
113-
this.pkg = PACKAGE;
114-
}
115-
this.useParams = BadSemver.version(version) >= BadSemver.version(0, 34);
116-
this.jarState = JarState.from(coordinate + version, provisioner);
97+
this.jarState = JarState.from(MAVEN_COORDINATE + version, provisioner);
11798
this.isScript = isScript;
11899
}
119100

120101
FormatterFunc createFormat() throws Exception {
121-
if (useParams) {
122-
Class<?> formatterFunc = jarState.getClassLoader().loadClass("com.diffplug.spotless.glue.ktlint.KtlintFormatterFunc");
123-
Constructor<?> constructor = formatterFunc.getConstructor(boolean.class, boolean.class, Map.class, Map.class);
124-
return (FormatterFunc.NeedsFile) constructor.newInstance(isScript, useExperimental, userData, editorConfigOverride);
125-
}
126-
127-
ClassLoader classLoader = jarState.getClassLoader();
128-
// String KtLint::format(String input, Iterable<RuleSet> rules, Function2 errorCallback)
129-
130-
ArrayList<Object> ruleSets = new ArrayList<>();
131-
132-
// first, we get the standard rules
133-
Class<?> standardRuleSetProviderClass = classLoader.loadClass(pkg + ".ktlint.ruleset.standard.StandardRuleSetProvider");
134-
Object standardRuleSet = standardRuleSetProviderClass.getMethod("get").invoke(standardRuleSetProviderClass.newInstance());
135-
ruleSets.add(standardRuleSet);
136-
137-
// second, we get the experimental rules if desired
138-
if (useExperimental) {
139-
Class<?> experimentalRuleSetProviderClass = classLoader.loadClass(pkg + ".ktlint.ruleset.experimental.ExperimentalRuleSetProvider");
140-
Object experimentalRuleSet = experimentalRuleSetProviderClass.getMethod("get").invoke(experimentalRuleSetProviderClass.newInstance());
141-
ruleSets.add(experimentalRuleSet);
142-
}
143-
144-
// next, we create an error callback which throws an assertion error when the format is bad
145-
Class<?> function2Interface = classLoader.loadClass("kotlin.jvm.functions.Function2");
146-
Class<?> lintErrorClass = classLoader.loadClass(pkg + ".ktlint.core.LintError");
147-
Method detailGetter = lintErrorClass.getMethod("getDetail");
148-
Method lineGetter = lintErrorClass.getMethod("getLine");
149-
Method colGetter = lintErrorClass.getMethod("getCol");
150-
Object formatterCallback = Proxy.newProxyInstance(classLoader, new Class[]{function2Interface},
151-
(proxy, method, args) -> {
152-
Object lintError = args[0]; //ktlint.core.LintError
153-
boolean corrected = (Boolean) args[1];
154-
if (!corrected) {
155-
String detail = (String) detailGetter.invoke(lintError);
156-
int line = (Integer) lineGetter.invoke(lintError);
157-
int col = (Integer) colGetter.invoke(lintError);
158-
throw new AssertionError("Error on line: " + line + ", column: " + col + "\n" + detail);
159-
}
160-
return null;
161-
});
162-
163-
// grab the KtLint singleton
164-
Class<?> ktlintClass = classLoader.loadClass(pkg + ".ktlint.core.KtLint");
165-
Object ktlint = ktlintClass.getDeclaredField("INSTANCE").get(null);
166-
167-
// and its format method
168-
String formatterMethodName = isScript ? "formatScript" : "format";
169-
Method formatterMethod = ktlintClass.getMethod(formatterMethodName, String.class, Iterable.class, Map.class, function2Interface);
170-
return input -> {
171-
try {
172-
return (String) formatterMethod.invoke(ktlint, input, ruleSets, userData, formatterCallback);
173-
} catch (InvocationTargetException e) {
174-
throw ThrowingEx.unwrapCause(e);
175-
}
176-
};
102+
Class<?> formatterFunc = jarState.getClassLoader().loadClass("com.diffplug.spotless.glue.ktlint.KtlintFormatterFunc");
103+
Constructor<?> constructor = formatterFunc.getConstructor(boolean.class, boolean.class, Map.class, Map.class);
104+
return (FormatterFunc.NeedsFile) constructor.newInstance(isScript, useExperimental, userData, editorConfigOverride);
177105
}
178106
}
179107
}

plugin-gradle/CHANGES.md

+3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
55
## [Unreleased]
66
### Added
77
* Support for `MAC_CLASSIC` (`\r`) line ending ([#1243](https://github.com/diffplug/spotless/pull/1243) fixes [#1196](https://github.com/diffplug/spotless/issues/1196))
8+
### Changes
9+
* Bump default `ktlint` version to latest `0.45.2` -> `0.46.1` [#1239](https://github.com/diffplug/spotless/issues/1239)
10+
* Note that we now require `ktlint >= 0.46.0` due to frequent compatibility breakages
811

912
## [6.7.2] - 2022-06-11
1013
### Fixed

plugin-maven/CHANGES.md

+3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
55
## [Unreleased]
66
### Added
77
* Support for `MAC_CLASSIC` (`\r`) line ending ([#1243](https://github.com/diffplug/spotless/pull/1243) fixes [#1196](https://github.com/diffplug/spotless/issues/1196))
8+
### Changes
9+
* Bump default `ktlint` version to latest `0.45.2` -> `0.46.1` [#1239](https://github.com/diffplug/spotless/issues/1239)
10+
* Note that we now require `ktlint >= 0.46.0` due to frequent compatibility breakages
811

912
## [2.22.8] - 2022-06-11
1013
### Fixed

testlib/src/test/java/com/diffplug/spotless/kotlin/KtLintStepTest.java

+4-35
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ void behavior() throws Exception {
4242
}
4343

4444
@Test
45-
void worksShyiko() throws Exception {
46-
FormatterStep step = KtLintStep.create("0.31.0", TestProvisioner.mavenCentral());
45+
void worksPre0_46_1() throws Exception {
46+
FormatterStep step = KtLintStep.create("0.46.0", TestProvisioner.mavenCentral());
4747
StepHarness.forStep(step)
4848
.testResource("kotlin/ktlint/basic.dirty", "kotlin/ktlint/basic.clean")
4949
.testResourceException("kotlin/ktlint/unsolvable.dirty", assertion -> {
@@ -53,48 +53,17 @@ void worksShyiko() throws Exception {
5353
});
5454
}
5555

56-
// Regression test to ensure it works on the version it switched to Pinterest (version 0.32.0)
57-
// but before 0.34.
58-
// https://github.com/diffplug/spotless/issues/419
59-
@Test
60-
void worksPinterestAndPre034() throws Exception {
61-
FormatterStep step = KtLintStep.create("0.32.0", TestProvisioner.mavenCentral());
62-
StepHarness.forStep(step)
63-
.testResource("kotlin/ktlint/basic.dirty", "kotlin/ktlint/basic.clean")
64-
.testResourceException("kotlin/ktlint/unsolvable.dirty", assertion -> {
65-
assertion.isInstanceOf(AssertionError.class);
66-
assertion.hasMessage("Error on line: 1, column: 1\n" +
67-
"Wildcard import");
68-
});
69-
}
70-
71-
// Regression test to handle alpha and 1.x version numbers
72-
// https://github.com/diffplug/spotless/issues/668
73-
@Test
74-
void worksAlpha1() throws Exception {
75-
FormatterStep step = KtLintStep.create("0.38.0-alpha01", TestProvisioner.mavenCentral());
76-
StepHarness.forStep(step)
77-
.testResource("kotlin/ktlint/basic.dirty", "kotlin/ktlint/basic.clean");
78-
}
79-
80-
@Test
81-
void worksPre0_45_2() throws Exception {
82-
FormatterStep step = KtLintStep.create("0.45.1", TestProvisioner.mavenCentral());
83-
StepHarness.forStep(step)
84-
.testResource("kotlin/ktlint/basic.dirty", "kotlin/ktlint/basic.clean");
85-
}
86-
8756
@Test
8857
void equality() throws Exception {
8958
new SerializableEqualityTester() {
90-
String version = "0.32.0";
59+
String version = "0.46.0";
9160

9261
@Override
9362
protected void setupTest(API api) {
9463
// same version == same
9564
api.areDifferentThan();
9665
// change the version, and it's different
97-
version = "0.38.0-alpha01";
66+
version = "0.46.1";
9867
api.areDifferentThan();
9968
}
10069

0 commit comments

Comments
 (0)