Skip to content

Commit 705e72a

Browse files
committed
Support custom rule sets for Ktlint
1 parent a0936e1 commit 705e72a

File tree

11 files changed

+98
-11
lines changed

11 files changed

+98
-11
lines changed

CHANGES.md

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ This document is intended for Spotless developers.
1010
We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`).
1111

1212
## [Unreleased]
13+
### Added
14+
* Support custom rule sets for Ktlint. ([#1896](https://github.com/diffplug/spotless/pull/1896)
1315
### Fixed
1416
* Fix Eclipse JDT on some settings files. ([#1864](https://github.com/diffplug/spotless/pull/1864) fixes [#1638](https://github.com/diffplug/spotless/issues/1638))
1517
### Changes

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

+13-6
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,11 @@
1919
import java.io.Serializable;
2020
import java.lang.reflect.Constructor;
2121
import java.util.Collections;
22+
import java.util.HashSet;
23+
import java.util.List;
2224
import java.util.Map;
2325
import java.util.Objects;
26+
import java.util.Set;
2427
import java.util.TreeMap;
2528

2629
import javax.annotation.Nullable;
@@ -51,18 +54,19 @@ public static FormatterStep create(String version, Provisioner provisioner) {
5154

5255
public static FormatterStep create(String version, Provisioner provisioner,
5356
Map<String, Object> editorConfigOverride) {
54-
return create(version, provisioner, false, null, editorConfigOverride);
57+
return create(version, provisioner, false, null, editorConfigOverride, Collections.emptyList());
5558
}
5659

5760
public static FormatterStep create(String version,
5861
Provisioner provisioner,
5962
boolean isScript,
6063
@Nullable FileSignature editorConfig,
61-
Map<String, Object> editorConfigOverride) {
64+
Map<String, Object> editorConfigOverride,
65+
List<String> customRuleSets) {
6266
Objects.requireNonNull(version, "version");
6367
Objects.requireNonNull(provisioner, "provisioner");
6468
return FormatterStep.createLazy(NAME,
65-
() -> new State(version, provisioner, isScript, editorConfig, editorConfigOverride),
69+
() -> new State(version, provisioner, isScript, editorConfig, editorConfigOverride, customRuleSets),
6670
State::createFormat);
6771
}
6872

@@ -86,11 +90,14 @@ static final class State implements Serializable {
8690
Provisioner provisioner,
8791
boolean isScript,
8892
@Nullable FileSignature editorConfigPath,
89-
Map<String, Object> editorConfigOverride) throws IOException {
93+
Map<String, Object> editorConfigOverride,
94+
List<String> customRuleSets) throws IOException {
9095
this.version = version;
9196
this.editorConfigOverride = new TreeMap<>(editorConfigOverride);
92-
this.jarState = JarState.from((version.startsWith("0.") ? MAVEN_COORDINATE_0_DOT : MAVEN_COORDINATE_1_DOT) + version,
93-
provisioner);
97+
String ktlintCoordinate = (version.startsWith("0.") ? MAVEN_COORDINATE_0_DOT : MAVEN_COORDINATE_1_DOT) + version;
98+
Set<String> mavenCoordinates = new HashSet<>(customRuleSets);
99+
mavenCoordinates.add(ktlintCoordinate);
100+
this.jarState = JarState.from(mavenCoordinates, provisioner);
94101
this.editorConfigPath = editorConfigPath;
95102
this.isScript = isScript;
96103
}

plugin-gradle/CHANGES.md

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `3.27.0`).
44

55
## [Unreleased]
6+
### Added
7+
* Support custom rule sets for Ktlint. ([#1896](https://github.com/diffplug/spotless/pull/1896)
68
### Fixed
79
* Fix Eclipse JDT on some settings files. ([#1864](https://github.com/diffplug/spotless/pull/1864) fixes [#1638](https://github.com/diffplug/spotless/issues/1638))
810
* Check if EditorConfig file exist for Ktlint in KotlinGradleExtension. ([#1889](https://github.com/diffplug/spotless/pull/1889)

plugin-gradle/README.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -399,14 +399,19 @@ Additionally, `editorConfigOverride` options will override what's supplied in `.
399399
```kotlin
400400
spotless {
401401
kotlin {
402-
// version, editorConfigPath and editorConfigOverride are all optional
402+
// version, editorConfigPath, editorConfigOverride and customRuleSets are all optional
403403
ktlint("1.0.0")
404404
.setEditorConfigPath("$projectDir/config/.editorconfig") // sample unusual placement
405405
.editorConfigOverride(
406406
mapOf(
407407
"indent_size" to 2,
408408
)
409409
)
410+
.customRuleSets(
411+
listOf(
412+
"io.nlopez.compose.rules:ktlint:0.3.3"
413+
)
414+
)
410415
}
411416
}
412417
```

plugin-gradle/src/main/java/com/diffplug/gradle/spotless/BaseKotlinExtension.java

+15-3
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@
1818
import java.io.File;
1919
import java.io.IOException;
2020
import java.util.Collections;
21+
import java.util.List;
2122
import java.util.Map;
2223
import java.util.Objects;
2324
import java.util.function.Consumer;
2425

2526
import javax.annotation.Nullable;
2627

28+
import com.diffplug.common.collect.ImmutableList;
2729
import com.diffplug.common.collect.ImmutableSortedMap;
2830
import com.diffplug.spotless.FileSignature;
2931
import com.diffplug.spotless.FormatterStep;
@@ -51,7 +53,7 @@ public KtlintConfig ktlint() throws IOException {
5153

5254
/** Adds the specified version of <a href="https://github.com/pinterest/ktlint">ktlint</a>. */
5355
public KtlintConfig ktlint(String version) throws IOException {
54-
return new KtlintConfig(version, Collections.emptyMap());
56+
return new KtlintConfig(version, Collections.emptyMap(), Collections.emptyList());
5557
}
5658

5759
/** Uses the <a href="https://github.com/facebookincubator/ktfmt">ktfmt</a> jar to format source code. */
@@ -147,16 +149,19 @@ public class KtlintConfig {
147149
private final String version;
148150
private FileSignature editorConfigPath;
149151
private Map<String, Object> editorConfigOverride;
152+
private List<String> customRuleSets;
150153

151154
private KtlintConfig(
152155
String version,
153-
Map<String, Object> editorConfigOverride) throws IOException {
156+
Map<String, Object> editorConfigOverride,
157+
List<String> customRuleSets) throws IOException {
154158
Objects.requireNonNull(version);
155159
File defaultEditorConfig = getProject().getRootProject().file(".editorconfig");
156160
FileSignature editorConfigPath = defaultEditorConfig.exists() ? FileSignature.signAsList(defaultEditorConfig) : null;
157161
this.version = version;
158162
this.editorConfigPath = editorConfigPath;
159163
this.editorConfigOverride = editorConfigOverride;
164+
this.customRuleSets = customRuleSets;
160165
addStep(createStep());
161166
}
162167

@@ -182,13 +187,20 @@ public KtlintConfig editorConfigOverride(Map<String, Object> editorConfigOverrid
182187
return this;
183188
}
184189

190+
public KtlintConfig customRuleSets(List<String> customRuleSets) {
191+
this.customRuleSets = ImmutableList.copyOf(customRuleSets);
192+
replaceStep(createStep());
193+
return this;
194+
}
195+
185196
private FormatterStep createStep() {
186197
return KtLintStep.create(
187198
version,
188199
provisioner(),
189200
isScript(),
190201
editorConfigPath,
191-
editorConfigOverride);
202+
editorConfigOverride,
203+
customRuleSets);
192204
}
193205
}
194206
}

plugin-gradle/src/test/java/com/diffplug/gradle/spotless/KotlinExtensionTest.java

+24
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,30 @@ void testSetEditorConfigCanOverrideEditorConfigFile() throws IOException {
141141
checkKtlintOfficialStyle();
142142
}
143143

144+
@Test
145+
void withCustomRuleSetApply() throws IOException {
146+
setFile("build.gradle").toLines(
147+
"plugins {",
148+
" id 'org.jetbrains.kotlin.jvm' version '1.5.31'",
149+
" id 'com.diffplug.spotless'",
150+
"}",
151+
"repositories { mavenCentral() }",
152+
"spotless {",
153+
" kotlin {",
154+
" ktlint(\"1.0.1\")",
155+
" .customRuleSets([",
156+
" \"io.nlopez.compose.rules:ktlint:0.3.3\"",
157+
" ])",
158+
" .editorConfigOverride([",
159+
" ktlint_function_naming_ignore_when_annotated_with: \"Composable\",",
160+
" ])",
161+
" }",
162+
"}");
163+
setFile("src/main/kotlin/Main.kt").toResource("kotlin/ktlint/listScreen.dirty");
164+
String buildOutput = gradleRunner().withArguments("spotlessCheck").buildAndFail().getOutput();
165+
assertThat(buildOutput).contains("Composable functions that return Unit should start with an uppercase letter.");
166+
}
167+
144168
@Test
145169
void testWithHeader() throws IOException {
146170
setFile("build.gradle").toLines(

plugin-maven/CHANGES.md

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
55
## [Unreleased]
66
### Added
77
* CompileSourceRoots and TestCompileSourceRoots are now respected as default includes. These properties are commonly set when adding extra source directories. ([#1846](https://github.com/diffplug/spotless/issues/1846))
8+
* Support custom rule sets for Ktlint. ([#1896](https://github.com/diffplug/spotless/pull/1896)
89
### Fixed
910
* Fix crash when build dir is a softlink to another directory. ([#1859](https://github.com/diffplug/spotless/pull/1859))
1011
* Fix Eclipse JDT on some settings files. ([#1864](https://github.com/diffplug/spotless/pull/1864) fixes [#1638](https://github.com/diffplug/spotless/issues/1638))

plugin-maven/README.md

+3
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,9 @@ Additionally, `editorConfigOverride` options will override what's supplied in `.
416416
<ij_kotlin_allow_trailing_comma>true</ij_kotlin_allow_trailing_comma>
417417
<ij_kotlin_allow_trailing_comma_on_call_site>true</ij_kotlin_allow_trailing_comma_on_call_site>
418418
</editorConfigOverride>
419+
<customRuleSets> <!-- optional -->
420+
<value>io.nlopez.compose.rules:ktlint:0.3.3</value>
421+
</customRuleSets>
419422
</ktlint>
420423
```
421424

plugin-maven/src/main/java/com/diffplug/spotless/maven/kotlin/Ktlint.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
*/
1616
package com.diffplug.spotless.maven.kotlin;
1717

18+
import java.util.Collections;
1819
import java.util.HashMap;
20+
import java.util.List;
1921
import java.util.Map;
2022

2123
import org.apache.maven.plugins.annotations.Parameter;
@@ -35,6 +37,8 @@ public class Ktlint implements FormatterStepFactory {
3537
private String editorConfigPath;
3638
@Parameter
3739
private Map<String, Object> editorConfigOverride;
40+
@Parameter
41+
private List<String> customRuleSets;
3842

3943
@Override
4044
public FormatterStep newFormatterStep(final FormatterStepConfig stepConfig) {
@@ -46,7 +50,10 @@ public FormatterStep newFormatterStep(final FormatterStepConfig stepConfig) {
4650
if (editorConfigOverride == null) {
4751
editorConfigOverride = new HashMap<>();
4852
}
53+
if (customRuleSets == null) {
54+
customRuleSets = Collections.emptyList();
55+
}
4956

50-
return KtLintStep.create(ktlintVersion, stepConfig.getProvisioner(), false, configPath, editorConfigOverride);
57+
return KtLintStep.create(ktlintVersion, stepConfig.getProvisioner(), false, configPath, editorConfigOverride, customRuleSets);
5158
}
5259
}

plugin-maven/src/test/java/com/diffplug/spotless/maven/kotlin/KtlintTest.java

+18
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@
1515
*/
1616
package com.diffplug.spotless.maven.kotlin;
1717

18+
import static org.junit.jupiter.api.Assertions.assertTrue;
19+
1820
import org.junit.jupiter.api.Test;
1921

22+
import com.diffplug.spotless.ProcessRunner;
2023
import com.diffplug.spotless.maven.MavenIntegrationHarness;
2124

2225
class KtlintTest extends MavenIntegrationHarness {
@@ -63,6 +66,21 @@ void testSetEditorConfigCanOverrideEditorConfigFile() throws Exception {
6366
checkKtlintOfficialStyle();
6467
}
6568

69+
@Test
70+
void testWithCustomRuleSetApply() throws Exception {
71+
writePomWithKotlinSteps("<ktlint>\n" +
72+
" <customRuleSets>\n" +
73+
" <value>io.nlopez.compose.rules:ktlint:0.3.3</value>\n" +
74+
" </customRuleSets>\n" +
75+
" <editorConfigOverride>\n" +
76+
" <ktlint_function_naming_ignore_when_annotated_with>Composable</ktlint_function_naming_ignore_when_annotated_with>\n" +
77+
" </editorConfigOverride>\n" +
78+
"</ktlint>");
79+
setFile("src/main/kotlin/Main.kt").toResource("kotlin/ktlint/listScreen.dirty");
80+
ProcessRunner.Result result = mavenRunner().withArguments("spotless:check").runHasError();
81+
assertTrue(result.toString().contains("Composable functions that return Unit should start with an uppercase letter."));
82+
}
83+
6684
private void checkKtlintOfficialStyle() throws Exception {
6785
String path = "src/main/kotlin/Main.kt";
6886
setFile(path).toResource("kotlin/ktlint/experimentalEditorConfigOverride.dirty");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import androidx.compose.runtime.Composable
2+
3+
@Composable
4+
fun listScreen() {
5+
val list: List<String> = mutableListOf<String>()
6+
}

0 commit comments

Comments
 (0)