diff --git a/CHANGES.md b/CHANGES.md index f6671d2191..942dfdc8df 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -13,6 +13,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( ### Fixed * Don't treat `@Value` as a type annotation [#1367](https://github.com/diffplug/spotless/pull/1367) * Support `ktlint_disabled_rules` in `ktlint` 0.47.x [#1378](https://github.com/diffplug/spotless/pull/1378) +* Allow to output multiple errors when using `ktlint` [#1403](https://github.com/diffplug/spotless/pull/1403) ## [2.30.0] - 2022-09-14 ### Added diff --git a/lib/src/compatKtLint0Dot31Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot31Dot0Adapter.java b/lib/src/compatKtLint0Dot31Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot31Dot0Adapter.java index 56b8da2d20..42a9251b42 100644 --- a/lib/src/compatKtLint0Dot31Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot31Dot0Adapter.java +++ b/lib/src/compatKtLint0Dot31Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot31Dot0Adapter.java @@ -29,12 +29,19 @@ import kotlin.jvm.functions.Function2; public class KtLintCompat0Dot31Dot0Adapter implements KtLintCompatAdapter { + private final ArrayList errors = new ArrayList<>(); static class FormatterCallback implements Function2 { + private final ArrayList errors; + + FormatterCallback(final ArrayList errors) { + this.errors = errors; + } + @Override public Unit invoke(LintError lint, Boolean corrected) { if (!corrected) { - KtLintCompatReporting.report(lint.getLine(), lint.getCol(), lint.getRuleId(), lint.getDetail()); + KtLintCompatReporting.addReport(errors, lint.getLine(), lint.getCol(), lint.getRuleId(), lint.getDetail()); } return null; } @@ -45,7 +52,7 @@ public String format(final String text, final String name, final boolean isScrip final boolean useExperimental, final Map userData, final Map editorConfigOverrideMap) { - final FormatterCallback formatterCallback = new FormatterCallback(); + final FormatterCallback formatterCallback = new FormatterCallback(errors); final List rulesets = new ArrayList<>(); rulesets.add(new StandardRuleSetProvider().get()); @@ -54,10 +61,16 @@ public String format(final String text, final String name, final boolean isScrip rulesets.add(new ExperimentalRuleSetProvider().get()); } - return KtLint.INSTANCE.format( + final String result = KtLint.INSTANCE.format( text, rulesets, userData, formatterCallback); + + if (!errors.isEmpty()) { + KtLintCompatReporting.report(errors); + } + + return result; } } diff --git a/lib/src/compatKtLint0Dot32Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot32Dot0Adapter.java b/lib/src/compatKtLint0Dot32Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot32Dot0Adapter.java index 6f69fcc7ce..6fffc34ee4 100644 --- a/lib/src/compatKtLint0Dot32Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot32Dot0Adapter.java +++ b/lib/src/compatKtLint0Dot32Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot32Dot0Adapter.java @@ -29,12 +29,19 @@ import kotlin.jvm.functions.Function2; public class KtLintCompat0Dot32Dot0Adapter implements KtLintCompatAdapter { + private final ArrayList errors = new ArrayList<>(); static class FormatterCallback implements Function2 { + private final ArrayList errors; + + FormatterCallback(final ArrayList errors) { + this.errors = errors; + } + @Override public Unit invoke(LintError lint, Boolean corrected) { if (!corrected) { - KtLintCompatReporting.report(lint.getLine(), lint.getCol(), lint.getRuleId(), lint.getDetail()); + KtLintCompatReporting.addReport(errors, lint.getLine(), lint.getCol(), lint.getRuleId(), lint.getDetail()); } return null; } @@ -45,7 +52,7 @@ public String format(final String text, final String name, final boolean isScrip final boolean useExperimental, final Map userData, final Map editorConfigOverrideMap) { - final FormatterCallback formatterCallback = new FormatterCallback(); + final FormatterCallback formatterCallback = new FormatterCallback(errors); final List rulesets = new ArrayList<>(); rulesets.add(new StandardRuleSetProvider().get()); @@ -54,10 +61,16 @@ public String format(final String text, final String name, final boolean isScrip rulesets.add(new ExperimentalRuleSetProvider().get()); } - return KtLint.INSTANCE.format( + final String result = KtLint.INSTANCE.format( text, rulesets, userData, formatterCallback); + + if (!errors.isEmpty()) { + KtLintCompatReporting.report(errors); + } + + return result; } } diff --git a/lib/src/compatKtLint0Dot34Dot2/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot34Dot2Adapter.java b/lib/src/compatKtLint0Dot34Dot2/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot34Dot2Adapter.java index a3c8c8df3b..5e909cd343 100644 --- a/lib/src/compatKtLint0Dot34Dot2/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot34Dot2Adapter.java +++ b/lib/src/compatKtLint0Dot34Dot2/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot34Dot2Adapter.java @@ -29,12 +29,19 @@ import kotlin.jvm.functions.Function2; public class KtLintCompat0Dot34Dot2Adapter implements KtLintCompatAdapter { + private final ArrayList errors = new ArrayList<>(); static class FormatterCallback implements Function2 { + private final ArrayList errors; + + FormatterCallback(final ArrayList errors) { + this.errors = errors; + } + @Override public Unit invoke(LintError lint, Boolean corrected) { if (!corrected) { - KtLintCompatReporting.report(lint.getLine(), lint.getCol(), lint.getRuleId(), lint.getDetail()); + KtLintCompatReporting.addReport(errors, lint.getLine(), lint.getCol(), lint.getRuleId(), lint.getDetail()); } return null; } @@ -45,7 +52,7 @@ public String format(final String text, final String name, final boolean isScrip final boolean useExperimental, final Map userData, final Map editorConfigOverrideMap) { - final FormatterCallback formatterCallback = new FormatterCallback(); + final FormatterCallback formatterCallback = new FormatterCallback(errors); final List rulesets = new ArrayList<>(); rulesets.add(new StandardRuleSetProvider().get()); @@ -54,7 +61,7 @@ public String format(final String text, final String name, final boolean isScrip rulesets.add(new ExperimentalRuleSetProvider().get()); } - return KtLint.INSTANCE.format(new KtLint.Params( + final String result = KtLint.INSTANCE.format(new KtLint.Params( name, text, rulesets, @@ -63,5 +70,11 @@ public String format(final String text, final String name, final boolean isScrip isScript, null, false)); + + if (!errors.isEmpty()) { + KtLintCompatReporting.report(errors); + } + + return result; } } diff --git a/lib/src/compatKtLint0Dot45Dot2/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot45Dot2Adapter.java b/lib/src/compatKtLint0Dot45Dot2/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot45Dot2Adapter.java index f7eadada3d..b21f59c145 100644 --- a/lib/src/compatKtLint0Dot45Dot2/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot45Dot2Adapter.java +++ b/lib/src/compatKtLint0Dot45Dot2/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot45Dot2Adapter.java @@ -37,12 +37,19 @@ import kotlin.jvm.functions.Function2; public class KtLintCompat0Dot45Dot2Adapter implements KtLintCompatAdapter { + private ArrayList errors = new ArrayList<>(); static class FormatterCallback implements Function2 { + private ArrayList errors; + + FormatterCallback(final ArrayList errors) { + this.errors = errors; + } + @Override public Unit invoke(LintError lint, Boolean corrected) { if (!corrected) { - KtLintCompatReporting.report(lint.getLine(), lint.getCol(), lint.getRuleId(), lint.getDetail()); + KtLintCompatReporting.addReport(errors, lint.getLine(), lint.getCol(), lint.getRuleId(), lint.getDetail()); } return null; } @@ -53,7 +60,7 @@ public String format(final String text, final String name, final boolean isScrip final boolean useExperimental, final Map userData, final Map editorConfigOverrideMap) { - final FormatterCallback formatterCallback = new FormatterCallback(); + final FormatterCallback formatterCallback = new FormatterCallback(errors); final List rulesets = new ArrayList<>(); rulesets.add(new StandardRuleSetProvider().get()); @@ -69,7 +76,7 @@ public String format(final String text, final String name, final boolean isScrip editorConfigOverride = createEditorConfigOverride(rulesets, editorConfigOverrideMap); } - return KtLint.INSTANCE.format(new KtLint.ExperimentalParams( + final String result = KtLint.INSTANCE.format(new KtLint.ExperimentalParams( name, text, rulesets, @@ -80,6 +87,12 @@ public String format(final String text, final String name, final boolean isScrip false, editorConfigOverride, false)); + + if (!errors.isEmpty()) { + KtLintCompatReporting.report(errors); + } + + return result; } /** diff --git a/lib/src/compatKtLint0Dot46Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot46Dot0Adapter.java b/lib/src/compatKtLint0Dot46Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot46Dot0Adapter.java index 873b91af80..9b1351e15f 100644 --- a/lib/src/compatKtLint0Dot46Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot46Dot0Adapter.java +++ b/lib/src/compatKtLint0Dot46Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot46Dot0Adapter.java @@ -37,12 +37,19 @@ import kotlin.jvm.functions.Function2; public class KtLintCompat0Dot46Dot0Adapter implements KtLintCompatAdapter { + private final ArrayList errors = new ArrayList<>(); static class FormatterCallback implements Function2 { + private final ArrayList errors; + + FormatterCallback(ArrayList errors) { + this.errors = errors; + } + @Override public Unit invoke(LintError lint, Boolean corrected) { if (!corrected) { - KtLintCompatReporting.report(lint.getLine(), lint.getCol(), lint.getRuleId(), lint.getDetail()); + KtLintCompatReporting.addReport(errors, lint.getLine(), lint.getCol(), lint.getRuleId(), lint.getDetail()); } return null; } @@ -53,7 +60,7 @@ public String format(final String text, final String name, final boolean isScrip final boolean useExperimental, final Map userData, final Map editorConfigOverrideMap) { - final FormatterCallback formatterCallback = new FormatterCallback(); + final FormatterCallback formatterCallback = new FormatterCallback(errors); final List rulesets = new ArrayList<>(); rulesets.add(new StandardRuleSetProvider().get()); @@ -69,7 +76,8 @@ public String format(final String text, final String name, final boolean isScrip editorConfigOverride = createEditorConfigOverride(rulesets, editorConfigOverrideMap); } - return KtLint.INSTANCE.format(new KtLint.ExperimentalParams( + errors.clear(); + final String result = KtLint.INSTANCE.format(new KtLint.ExperimentalParams( name, text, rulesets, @@ -80,6 +88,12 @@ public String format(final String text, final String name, final boolean isScrip false, editorConfigOverride, false)); + + if (!errors.isEmpty()) { + KtLintCompatReporting.report(errors); + } + + return result; } /** diff --git a/lib/src/compatKtLint0Dot47Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot47Dot0Adapter.java b/lib/src/compatKtLint0Dot47Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot47Dot0Adapter.java index 757ffc922b..d67e11fd14 100644 --- a/lib/src/compatKtLint0Dot47Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot47Dot0Adapter.java +++ b/lib/src/compatKtLint0Dot47Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot47Dot0Adapter.java @@ -42,12 +42,19 @@ import kotlin.jvm.functions.Function2; public class KtLintCompat0Dot47Dot0Adapter implements KtLintCompatAdapter { + private final ArrayList errors = new ArrayList<>(); static class FormatterCallback implements Function2 { + private final ArrayList errors; + + FormatterCallback(ArrayList errors) { + this.errors = errors; + } + @Override public Unit invoke(LintError lint, Boolean corrected) { if (!corrected) { - KtLintCompatReporting.report(lint.getLine(), lint.getCol(), lint.getRuleId(), lint.getDetail()); + KtLintCompatReporting.addReport(errors, lint.getLine(), lint.getCol(), lint.getRuleId(), lint.getDetail()); } return null; } @@ -58,7 +65,7 @@ public String format(final String text, final String name, final boolean isScrip final boolean useExperimental, final Map userData, final Map editorConfigOverrideMap) { - final FormatterCallback formatterCallback = new FormatterCallback(); + final FormatterCallback formatterCallback = new FormatterCallback(errors); Set allRuleProviders = new LinkedHashSet<>( new StandardRuleSetProvider().getRuleProviders()); @@ -76,7 +83,8 @@ public String format(final String text, final String name, final boolean isScrip editorConfigOverrideMap); } - return KtLint.INSTANCE.format(new KtLint.ExperimentalParams( + errors.clear(); + final String result = KtLint.INSTANCE.format(new KtLint.ExperimentalParams( name, text, emptySet(), @@ -89,6 +97,12 @@ public String format(final String text, final String name, final boolean isScrip EditorConfigDefaults.Companion.getEmptyEditorConfigDefaults(), editorConfigOverride, false)); + + if (!errors.isEmpty()) { + KtLintCompatReporting.report(errors); + } + + return result; } /** diff --git a/lib/src/compatKtLintApi/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompatReporting.java b/lib/src/compatKtLintApi/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompatReporting.java index 7c1e0f6dd8..adeda00f84 100644 --- a/lib/src/compatKtLintApi/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompatReporting.java +++ b/lib/src/compatKtLintApi/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompatReporting.java @@ -15,11 +15,24 @@ */ package com.diffplug.spotless.glue.ktlint.compat; +import java.util.ArrayList; + final class KtLintCompatReporting { private KtLintCompatReporting() {} - static void report(int line, int column, String ruleId, String detail) { - throw new AssertionError("Error on line: " + line + ", column: " + column + "\nrule: " + ruleId + "\n" + detail); + static void addReport(ArrayList errors, int line, int column, String ruleId, String detail) { + StringBuilder sb = new StringBuilder("Error on line: "); + sb.append(line).append(", column: ").append(column).append(System.lineSeparator()).append("rule: ").append(ruleId).append(System.lineSeparator()).append(detail); + errors.add(sb.toString()); + } + + static String report(final ArrayList errors) { + StringBuilder output = new StringBuilder(); + output.append("There are ").append(errors.size()).append(" unfixed errors:").append(System.lineSeparator()); + for (final String error : errors) { + output.append(error).append(System.lineSeparator()); + } + throw new AssertionError(output); } } diff --git a/plugin-gradle/CHANGES.md b/plugin-gradle/CHANGES.md index 5acd85ddc8..f7d4396a34 100644 --- a/plugin-gradle/CHANGES.md +++ b/plugin-gradle/CHANGES.md @@ -6,6 +6,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( ### Fixed * Don't treat `@Value` as a type annotation [#1367](https://github.com/diffplug/spotless/pull/1367) * Support `ktlint_disabled_rules` in `ktlint` 0.47.x [#1378](https://github.com/diffplug/spotless/pull/1378) +* Allow to output multiple errors when using `ktlint` [#1403](https://github.com/diffplug/spotless/pull/1403) ## [6.11.0] - 2022-09-14 ### Added diff --git a/plugin-maven/CHANGES.md b/plugin-maven/CHANGES.md index b08a2366fd..51f8b17657 100644 --- a/plugin-maven/CHANGES.md +++ b/plugin-maven/CHANGES.md @@ -6,6 +6,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( ### Fixed * Don't treat `@Value` as a type annotation [#1367](https://github.com/diffplug/spotless/pull/1367) * Support `ktlint_disabled_rules` in `ktlint` 0.47.x [#1378](https://github.com/diffplug/spotless/pull/1378) +* Allow to output multiple errors when using `ktlint` [#1403](https://github.com/diffplug/spotless/pull/1403) ## [2.27.2] - 2022-10-10 ### Fixed diff --git a/testlib/src/test/java/com/diffplug/spotless/kotlin/KtLintStepTest.java b/testlib/src/test/java/com/diffplug/spotless/kotlin/KtLintStepTest.java index 71a0979422..ae2b13ac43 100644 --- a/testlib/src/test/java/com/diffplug/spotless/kotlin/KtLintStepTest.java +++ b/testlib/src/test/java/com/diffplug/spotless/kotlin/KtLintStepTest.java @@ -32,9 +32,14 @@ void behavior() throws Exception { .testResource("kotlin/ktlint/basic.dirty", "kotlin/ktlint/basic.clean") .testResourceException("kotlin/ktlint/unsolvable.dirty", assertion -> { assertion.isInstanceOf(AssertionError.class); - assertion.hasMessage("Error on line: 1, column: 1\n" + - "rule: no-wildcard-imports\n" + - "Wildcard import"); + assertion.hasMessage("There are 2 unfixed errors:" + + System.lineSeparator() + "Error on line: 1, column: 1" + + System.lineSeparator() + "rule: no-wildcard-imports" + + System.lineSeparator() + "Wildcard import" + + System.lineSeparator() + "Error on line: 2, column: 1" + + System.lineSeparator() + "rule: no-wildcard-imports" + + System.lineSeparator() + "Wildcard import" + + System.lineSeparator()); }); } @@ -45,9 +50,14 @@ void worksShyiko() throws Exception { .testResource("kotlin/ktlint/basic.dirty", "kotlin/ktlint/basic.clean") .testResourceException("kotlin/ktlint/unsolvable.dirty", assertion -> { assertion.isInstanceOf(AssertionError.class); - assertion.hasMessage("Error on line: 1, column: 1\n" + - "rule: no-wildcard-imports\n" + - "Wildcard import"); + assertion.hasMessage("There are 2 unfixed errors:" + + System.lineSeparator() + "Error on line: 1, column: 1" + + System.lineSeparator() + "rule: no-wildcard-imports" + + System.lineSeparator() + "Wildcard import" + + System.lineSeparator() + "Error on line: 2, column: 1" + + System.lineSeparator() + "rule: no-wildcard-imports" + + System.lineSeparator() + "Wildcard import" + + System.lineSeparator()); }); } @@ -61,9 +71,14 @@ void worksPinterestAndPre034() throws Exception { .testResource("kotlin/ktlint/basic.dirty", "kotlin/ktlint/basic.clean") .testResourceException("kotlin/ktlint/unsolvable.dirty", assertion -> { assertion.isInstanceOf(AssertionError.class); - assertion.hasMessage("Error on line: 1, column: 1\n" + - "rule: no-wildcard-imports\n" + - "Wildcard import"); + assertion.hasMessage("There are 2 unfixed errors:" + + System.lineSeparator() + "Error on line: 1, column: 1" + + System.lineSeparator() + "rule: no-wildcard-imports" + + System.lineSeparator() + "Wildcard import" + + System.lineSeparator() + "Error on line: 2, column: 1" + + System.lineSeparator() + "rule: no-wildcard-imports" + + System.lineSeparator() + "Wildcard import" + + System.lineSeparator()); }); } @@ -112,9 +127,14 @@ void works0_46_0() throws Exception { .testResource("kotlin/ktlint/basic.dirty", "kotlin/ktlint/basic.clean") .testResourceException("kotlin/ktlint/unsolvable.dirty", assertion -> { assertion.isInstanceOf(AssertionError.class); - assertion.hasMessage("Error on line: 1, column: 1\n" + - "rule: no-wildcard-imports\n" + - "Wildcard import"); + assertion.hasMessage("There are 2 unfixed errors:" + + System.lineSeparator() + "Error on line: 1, column: 1" + + System.lineSeparator() + "rule: no-wildcard-imports" + + System.lineSeparator() + "Wildcard import" + + System.lineSeparator() + "Error on line: 2, column: 1" + + System.lineSeparator() + "rule: no-wildcard-imports" + + System.lineSeparator() + "Wildcard import" + + System.lineSeparator()); }); } @@ -125,9 +145,14 @@ void works0_47_0() throws Exception { .testResource("kotlin/ktlint/basic.dirty", "kotlin/ktlint/basic.clean") .testResourceException("kotlin/ktlint/unsolvable.dirty", assertion -> { assertion.isInstanceOf(AssertionError.class); - assertion.hasMessage("Error on line: 1, column: 1\n" + - "rule: no-wildcard-imports\n" + - "Wildcard import"); + assertion.hasMessage("There are 2 unfixed errors:" + + System.lineSeparator() + "Error on line: 1, column: 1" + + System.lineSeparator() + "rule: no-wildcard-imports" + + System.lineSeparator() + "Wildcard import" + + System.lineSeparator() + "Error on line: 2, column: 1" + + System.lineSeparator() + "rule: no-wildcard-imports" + + System.lineSeparator() + "Wildcard import" + + System.lineSeparator()); }); } @@ -138,9 +163,14 @@ void works0_47_1() throws Exception { .testResource("kotlin/ktlint/basic.dirty", "kotlin/ktlint/basic.clean") .testResourceException("kotlin/ktlint/unsolvable.dirty", assertion -> { assertion.isInstanceOf(AssertionError.class); - assertion.hasMessage("Error on line: 1, column: 1\n" + - "rule: no-wildcard-imports\n" + - "Wildcard import"); + assertion.hasMessage("There are 2 unfixed errors:" + + System.lineSeparator() + "Error on line: 1, column: 1" + + System.lineSeparator() + "rule: no-wildcard-imports" + + System.lineSeparator() + "Wildcard import" + + System.lineSeparator() + "Error on line: 2, column: 1" + + System.lineSeparator() + "rule: no-wildcard-imports" + + System.lineSeparator() + "Wildcard import" + + System.lineSeparator()); }); }