Skip to content

Commit 1de1741

Browse files
committed
Merge branch 'main' into renovate/ver_ktfmt
2 parents c280c40 + c173aa7 commit 1de1741

File tree

25 files changed

+331
-134
lines changed

25 files changed

+331
-134
lines changed

CHANGES.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ 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+
* `importOrder` now support groups of imports without blank lines ([#1401](https://github.com/diffplug/spotless/pull/1401))
15+
### Fixed
16+
* Don't treat `@Value` as a type annotation [#1367](https://github.com/diffplug/spotless/pull/1367)
17+
* Support `ktlint_disabled_rules` in `ktlint` 0.47.x [#1378](https://github.com/diffplug/spotless/pull/1378)
1318

1419
## [2.30.0] - 2022-09-14
1520
### Added

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ lib('markdown.FreshMarkStep') +'{{yes}} | {{no}}
7171
lib('markdown.FlexmarkStep') +'{{no}} | {{yes}} | {{no}} | {{no}} |',
7272
lib('npm.PrettierFormatterStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |',
7373
lib('npm.TsFmtFormatterStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |',
74-
lib('pom.SortPomStepStep') +'{{no}} | {{yes}} | {{no}} | {{no}} |',
74+
lib('pom.SortPomStep') +'{{no}} | {{yes}} | {{no}} | {{no}} |',
7575
lib('python.BlackStep') +'{{yes}} | {{no}} | {{no}} | {{no}} |',
7676
lib('scala.ScalaFmtStep') +'{{yes}} | {{yes}} | {{yes}} | {{no}} |',
7777
lib('sql.DBeaverSQLFormatterStep') +'{{yes}} | {{yes}} | {{yes}} | {{no}} |',
@@ -115,7 +115,7 @@ extra('wtp.EclipseWtpFormatterStep') +'{{yes}} | {{yes}}
115115
| [`markdown.FlexmarkStep`](lib/src/main/java/com/diffplug/spotless/markdown/FlexmarkStep.java) | :white_large_square: | :+1: | :white_large_square: | :white_large_square: |
116116
| [`npm.PrettierFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/PrettierFormatterStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: |
117117
| [`npm.TsFmtFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/TsFmtFormatterStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: |
118-
| [`pom.SortPomStepStep`](lib/src/main/java/com/diffplug/spotless/pom/SortPomStepStep.java) | :white_large_square: | :+1: | :white_large_square: | :white_large_square: |
118+
| [`pom.SortPomStep`](lib/src/main/java/com/diffplug/spotless/pom/SortPomStep.java) | :white_large_square: | :+1: | :white_large_square: | :white_large_square: |
119119
| [`python.BlackStep`](lib/src/main/java/com/diffplug/spotless/python/BlackStep.java) | :+1: | :white_large_square: | :white_large_square: | :white_large_square: |
120120
| [`scala.ScalaFmtStep`](lib/src/main/java/com/diffplug/spotless/scala/ScalaFmtStep.java) | :+1: | :+1: | :+1: | :white_large_square: |
121121
| [`sql.DBeaverSQLFormatterStep`](lib/src/main/java/com/diffplug/spotless/sql/DBeaverSQLFormatterStep.java) | :+1: | :+1: | :+1: | :white_large_square: |

build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1+
repositories {
2+
mavenCentral()
3+
}
14
apply from: rootProject.file('gradle/java-publish.gradle')
25
apply from: rootProject.file('gradle/changelog.gradle')
36
allprojects {
47
apply from: rootProject.file('gradle/spotless.gradle')
58
}
69
apply from: rootProject.file('gradle/spotless-freshmark.gradle')
710

8-
repositories {
9-
mavenCentral()
10-
}
1111
spotless {
1212
groovyGradle {
1313
target '*.gradle', 'gradle/*.gradle'

gradle.properties

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ artifactIdGradle=spotless-plugin-gradle
1717

1818
# Build requirements
1919
VER_JAVA=1.8
20-
VER_SPOTBUGS=4.7.2
20+
VER_SPOTBUGS=4.7.3
2121
VER_JSR_305=3.0.2
2222

2323
# Dependencies provided by Spotless plugin
@@ -26,9 +26,9 @@ VER_SLF4J=[1.6,2.0[
2626
# Used in multiple places
2727
VER_DURIAN=1.2.0
2828
VER_JGIT=5.13.1.202206130422-r
29-
VER_JUNIT=5.9.0
29+
VER_JUNIT=5.9.1
3030
VER_ASSERTJ=3.23.1
31-
VER_MOCKITO=4.8.0
31+
VER_MOCKITO=4.9.0
3232

3333
# Used for Maven Plugin
3434
VER_MAVEN_API=3.0

lib/src/compatKtLint0Dot47Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot47Dot0Adapter.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import static java.util.Collections.emptySet;
1919

20+
import java.util.ArrayList;
2021
import java.util.LinkedHashSet;
2122
import java.util.List;
2223
import java.util.Map;
@@ -100,9 +101,13 @@ private static EditorConfigOverride createEditorConfigOverride(final List<Rule>
100101
.filter(rule -> rule instanceof UsesEditorConfigProperties)
101102
.flatMap(rule -> ((UsesEditorConfigProperties) rule).getEditorConfigProperties().stream());
102103

104+
// get complete list of supported properties in DefaultEditorConfigProperties.INSTANCE
105+
List<UsesEditorConfigProperties.EditorConfigProperty<?>> editorConfigProperties = new ArrayList<>(DefaultEditorConfigProperties.INSTANCE.getEditorConfigProperties());
106+
editorConfigProperties.add(DefaultEditorConfigProperties.INSTANCE.getKtlintDisabledRulesProperty());
107+
103108
// Create a mapping of properties to their names based on rule properties and default properties
104109
Map<String, UsesEditorConfigProperties.EditorConfigProperty<?>> supportedProperties = Stream
105-
.concat(ruleProperties, DefaultEditorConfigProperties.INSTANCE.getEditorConfigProperties().stream())
110+
.concat(ruleProperties, editorConfigProperties.stream())
106111
.distinct()
107112
.collect(Collectors.toMap(property -> property.getType().getName(), property -> property));
108113

lib/src/main/java/com/diffplug/spotless/java/FormatAnnotationsStep.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ public final class FormatAnnotationsStep {
371371
"UpperBoundBottom",
372372
"UpperBoundLiteral",
373373
"UpperBoundUnknown",
374-
"Value",
374+
"ValueTypeAnno",
375375
"VariableNameDefaultBottom",
376376
"VariableNameDefaultMiddle",
377377
"VariableNameDefaultTop",

lib/src/main/java/com/diffplug/spotless/java/ImportSorterImpl.java

Lines changed: 76 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016-2021 DiffPlug
2+
* Copyright 2016-2022 DiffPlug
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,6 +17,8 @@
1717

1818
import java.io.Serializable;
1919
import java.util.*;
20+
import java.util.stream.Collectors;
21+
import java.util.stream.Stream;
2022

2123
import javax.annotation.Nullable;
2224

@@ -25,12 +27,41 @@
2527
// which itself is licensed under the Apache 2.0 license.
2628
final class ImportSorterImpl {
2729

28-
private final List<String> template = new ArrayList<>();
30+
private static final String CATCH_ALL_SUBGROUP = "";
31+
private static final String STATIC_KEYWORD = "static ";
32+
private static final String STATIC_SYMBOL = "\\#";
33+
private static final String SUBGROUP_SEPARATOR = "|";
34+
35+
private final List<ImportsGroup> importsGroups;
2936
private final Map<String, List<String>> matchingImports = new HashMap<>();
3037
private final List<String> notMatching = new ArrayList<>();
3138
private final Set<String> allImportOrderItems = new HashSet<>();
3239
private final Comparator<String> ordering;
3340

41+
// An ImportsGroup is a group of imports ; each group is separated by blank lines.
42+
// A group is composed of subgroups : imports are sorted by subgroup.
43+
private static class ImportsGroup {
44+
45+
private final List<String> subGroups;
46+
47+
public ImportsGroup(String importOrder) {
48+
this.subGroups = Stream.of(importOrder.split("\\" + SUBGROUP_SEPARATOR))
49+
.map(this::normalizeStatic)
50+
.collect(Collectors.toList());
51+
}
52+
53+
private String normalizeStatic(String subgroup) {
54+
if (subgroup.startsWith(STATIC_SYMBOL)) {
55+
return subgroup.replace(STATIC_SYMBOL, STATIC_KEYWORD);
56+
}
57+
return subgroup;
58+
}
59+
60+
public List<String> getSubGroups() {
61+
return subGroups;
62+
}
63+
}
64+
3465
static List<String> sort(List<String> imports, List<String> importsOrder, boolean wildcardsLast, String lineFormat) {
3566
ImportSorterImpl importsSorter = new ImportSorterImpl(importsOrder, wildcardsLast);
3667
return importsSorter.sort(imports, lineFormat);
@@ -40,43 +71,42 @@ private List<String> sort(List<String> imports, String lineFormat) {
4071
filterMatchingImports(imports);
4172
mergeNotMatchingItems(false);
4273
mergeNotMatchingItems(true);
43-
mergeMatchingItems();
74+
List<String> sortedImported = mergeMatchingItems();
4475

45-
return getResult(lineFormat);
76+
return getResult(sortedImported, lineFormat);
4677
}
4778

4879
private ImportSorterImpl(List<String> importOrder, boolean wildcardsLast) {
49-
List<String> importOrderCopy = new ArrayList<>(importOrder);
50-
normalizeStaticOrderItems(importOrderCopy);
51-
putStaticItemIfNotExists(importOrderCopy);
52-
template.addAll(importOrderCopy);
80+
importsGroups = importOrder.stream().filter(Objects::nonNull).map(ImportsGroup::new).collect(Collectors.toList());
81+
putStaticItemIfNotExists(importsGroups);
82+
putCatchAllGroupIfNotExists(importsGroups);
83+
5384
ordering = new OrderingComparator(wildcardsLast);
54-
this.allImportOrderItems.addAll(importOrderCopy);
85+
86+
List<String> subgroups = importsGroups.stream().map(ImportsGroup::getSubGroups).flatMap(Collection::stream).collect(Collectors.toList());
87+
this.allImportOrderItems.addAll(subgroups);
5588
}
5689

57-
private static void putStaticItemIfNotExists(List<String> allImportOrderItems) {
58-
boolean contains = false;
90+
private void putStaticItemIfNotExists(List<ImportsGroup> importsGroups) {
91+
boolean catchAllSubGroupExist = importsGroups.stream().anyMatch(group -> group.getSubGroups().contains(STATIC_KEYWORD));
92+
if (catchAllSubGroupExist) {
93+
return;
94+
}
95+
5996
int indexOfFirstStatic = 0;
60-
for (int i = 0; i < allImportOrderItems.size(); i++) {
61-
String allImportOrderItem = allImportOrderItems.get(i);
62-
if (allImportOrderItem.equals("static ")) {
63-
contains = true;
64-
}
65-
if (allImportOrderItem.startsWith("static ")) {
97+
for (int i = 0; i < importsGroups.size(); i++) {
98+
boolean subgroupMatch = importsGroups.get(i).getSubGroups().stream().anyMatch(subgroup -> subgroup.startsWith(STATIC_KEYWORD));
99+
if (subgroupMatch) {
66100
indexOfFirstStatic = i;
67101
}
68102
}
69-
if (!contains) {
70-
allImportOrderItems.add(indexOfFirstStatic, "static ");
71-
}
103+
importsGroups.add(indexOfFirstStatic, new ImportsGroup(STATIC_KEYWORD));
72104
}
73105

74-
private static void normalizeStaticOrderItems(List<String> allImportOrderItems) {
75-
for (int i = 0; i < allImportOrderItems.size(); i++) {
76-
String s = allImportOrderItems.get(i);
77-
if (s.startsWith("\\#")) {
78-
allImportOrderItems.set(i, s.replace("\\#", "static "));
79-
}
106+
private void putCatchAllGroupIfNotExists(List<ImportsGroup> importsGroups) {
107+
boolean catchAllSubGroupExist = importsGroups.stream().anyMatch(group -> group.getSubGroups().contains(CATCH_ALL_SUBGROUP));
108+
if (!catchAllSubGroupExist) {
109+
importsGroups.add(new ImportsGroup(CATCH_ALL_SUBGROUP));
80110
}
81111
}
82112

@@ -87,9 +117,7 @@ private void filterMatchingImports(List<String> imports) {
87117
for (String anImport : imports) {
88118
String orderItem = getBestMatchingImportOrderItem(anImport);
89119
if (orderItem != null) {
90-
if (!matchingImports.containsKey(orderItem)) {
91-
matchingImports.put(orderItem, new ArrayList<>());
92-
}
120+
matchingImports.computeIfAbsent(orderItem, key -> new ArrayList<>());
93121
matchingImports.get(orderItem).add(anImport);
94122
} else {
95123
notMatching.add(anImport);
@@ -116,34 +144,14 @@ private void filterMatchingImports(List<String> imports) {
116144
* not matching means it does not match any order item, so it will be appended before or after order items
117145
*/
118146
private void mergeNotMatchingItems(boolean staticItems) {
119-
sort(notMatching);
120-
121-
int firstIndexOfOrderItem = getFirstIndexOfOrderItem(notMatching, staticItems);
122-
int indexOfOrderItem = 0;
123147
for (String notMatchingItem : notMatching) {
124148
if (!matchesStatic(staticItems, notMatchingItem)) {
125149
continue;
126150
}
127151
boolean isOrderItem = isOrderItem(notMatchingItem, staticItems);
128-
if (isOrderItem) {
129-
indexOfOrderItem = template.indexOf(notMatchingItem);
130-
} else {
131-
if (indexOfOrderItem == 0 && firstIndexOfOrderItem != 0) {
132-
// insert before alphabetically first order item
133-
template.add(firstIndexOfOrderItem, notMatchingItem);
134-
firstIndexOfOrderItem++;
135-
} else if (firstIndexOfOrderItem == 0) {
136-
// no order is specified
137-
if (template.size() > 0 && (template.get(template.size() - 1).startsWith("static"))) {
138-
// insert N after last static import
139-
template.add(ImportSorter.N);
140-
}
141-
template.add(notMatchingItem);
142-
} else {
143-
// insert after the previous order item
144-
template.add(indexOfOrderItem + 1, notMatchingItem);
145-
indexOfOrderItem++;
146-
}
152+
if (!isOrderItem) {
153+
matchingImports.computeIfAbsent(CATCH_ALL_SUBGROUP, key -> new ArrayList<>());
154+
matchingImports.get(CATCH_ALL_SUBGROUP).add(notMatchingItem);
147155
}
148156
}
149157
}
@@ -153,76 +161,44 @@ private boolean isOrderItem(String notMatchingItem, boolean staticItems) {
153161
return contains && matchesStatic(staticItems, notMatchingItem);
154162
}
155163

156-
/**
157-
* gets first order item from sorted input list, and finds out it's index in template.
158-
*/
159-
private int getFirstIndexOfOrderItem(List<String> notMatching, boolean staticItems) {
160-
int firstIndexOfOrderItem = 0;
161-
for (String notMatchingItem : notMatching) {
162-
if (!matchesStatic(staticItems, notMatchingItem)) {
163-
continue;
164-
}
165-
boolean isOrderItem = isOrderItem(notMatchingItem, staticItems);
166-
if (isOrderItem) {
167-
firstIndexOfOrderItem = template.indexOf(notMatchingItem);
168-
break;
169-
}
170-
}
171-
return firstIndexOfOrderItem;
172-
}
173-
174164
private static boolean matchesStatic(boolean staticItems, String notMatchingItem) {
175-
boolean isStatic = notMatchingItem.startsWith("static ");
165+
boolean isStatic = notMatchingItem.startsWith(STATIC_KEYWORD);
176166
return (isStatic && staticItems) || (!isStatic && !staticItems);
177167
}
178168

179-
private void mergeMatchingItems() {
180-
for (int i = 0; i < template.size(); i++) {
181-
String item = template.get(i);
182-
if (allImportOrderItems.contains(item)) {
183-
// find matching items for order item
184-
List<String> strings = matchingImports.get(item);
169+
private List<String> mergeMatchingItems() {
170+
List<String> template = new ArrayList<>();
171+
for (ImportsGroup group : importsGroups) {
172+
boolean groupIsNotEmpty = false;
173+
for (String subgroup : group.getSubGroups()) {
174+
List<String> strings = matchingImports.get(subgroup);
185175
if (strings == null || strings.isEmpty()) {
186-
// if there is none, just remove order item
187-
template.remove(i);
188-
i--;
189176
continue;
190177
}
178+
groupIsNotEmpty = true;
191179
List<String> matchingItems = new ArrayList<>(strings);
192180
sort(matchingItems);
193-
194-
// replace order item by matching import statements
195-
// this is a mess and it is only a luck that it works :-]
196-
template.remove(i);
197-
if (i != 0 && !template.get(i - 1).equals(ImportSorter.N)) {
198-
template.add(i, ImportSorter.N);
199-
i++;
200-
}
201-
if (i + 1 < template.size() && !template.get(i + 1).equals(ImportSorter.N)
202-
&& !template.get(i).equals(ImportSorter.N)) {
203-
template.add(i, ImportSorter.N);
204-
}
205-
template.addAll(i, matchingItems);
206-
if (i != 0 && !template.get(i - 1).equals(ImportSorter.N)) {
207-
template.add(i, ImportSorter.N);
208-
}
209-
181+
template.addAll(matchingItems);
182+
}
183+
if (groupIsNotEmpty) {
184+
template.add(ImportSorter.N);
210185
}
211186
}
212187
// if there is \n on the end, remove it
213-
if (template.size() > 0 && template.get(template.size() - 1).equals(ImportSorter.N)) {
188+
if (!template.isEmpty() && template.get(template.size() - 1).equals(ImportSorter.N)) {
214189
template.remove(template.size() - 1);
215190
}
191+
return template;
216192
}
217193

218194
private void sort(List<String> items) {
219195
items.sort(ordering);
220196
}
221197

222-
private List<String> getResult(String lineFormat) {
198+
private List<String> getResult(List<String> sortedImported, String lineFormat) {
223199
List<String> strings = new ArrayList<>();
224200

225-
for (String s : template) {
201+
for (String s : sortedImported) {
226202
if (s.equals(ImportSorter.N)) {
227203
strings.add(s);
228204
} else {

plugin-gradle/CHANGES.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
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+
* `importOrder` now support groups of imports without blank lines ([#1401](https://github.com/diffplug/spotless/pull/1401))
8+
### Fixed
9+
* Don't treat `@Value` as a type annotation [#1367](https://github.com/diffplug/spotless/pull/1367)
10+
* Support `ktlint_disabled_rules` in `ktlint` 0.47.x [#1378](https://github.com/diffplug/spotless/pull/1378)
611

712
## [6.11.0] - 2022-09-14
813
### Added

plugin-gradle/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,8 @@ spotless {
151151
// Use the default importOrder configuration
152152
importOrder()
153153
// optional: you can specify import groups directly
154-
// note: you can use an empty string for all the imports you didn't specify explicitly, and '\\#` prefix for static imports
155-
importOrder('java', 'javax', 'com.acme', '', '\\#com.acme', '\\#')
154+
// note: you can use an empty string for all the imports you didn't specify explicitly, '|' to join group without blank line, and '\\#` prefix for static imports
155+
importOrder('java|javax', 'com.acme', '', '\\#com.acme', '\\#')
156156
// optional: instead of specifying import groups directly you can specify a config file
157157
// export config file: https://github.com/diffplug/spotless/blob/main/ECLIPSE_SCREENSHOTS.md#creating-spotlessimportorder
158158
importOrderFile('eclipse-import-order.txt') // import order file as exported from eclipse
@@ -303,7 +303,7 @@ spotless {
303303

304304
### eclipse groovy
305305

306-
[homepage](https://github.com/groovy/groovy-eclipse/wiki). [changelog](https://github.com/groovy/groovy-eclipse/releases). [compatible versions](https://github.com/diffplug/spotless/tree/main/lib-extra/src/main/resources/com/diffplug/spotless/extra/groovy_eclipse_formatter). The Groovy formatter uses some of the [eclipse jdt](#eclipse-jdt) configuration parameters in addition to groovy-specific ones. All parameters can be configured within a single file, like the Java properties file [greclipse.properties](../testlib/src/main/resources/groovy/greclipse/format/greclipse.properties) in the previous example. The formatter step can also load the [exported Eclipse properties](../ECLIPSE_SCREENSHOTS.md) and augment it with the `.metadata/.plugins/org.eclipse.core.runtime/.settings/org.codehaus.groovy.eclipse.ui.prefs` from your Eclipse workspace as shown below.
306+
[homepage](https://github.com/groovy/groovy-eclipse/wiki). [changelog](https://github.com/groovy/groovy-eclipse/releases). [compatible versions](https://github.com/diffplug/spotless/tree/main/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_groovy_formatter). The Groovy formatter uses some of the [eclipse jdt](#eclipse-jdt) configuration parameters in addition to groovy-specific ones. All parameters can be configured within a single file, like the Java properties file [greclipse.properties](../testlib/src/main/resources/groovy/greclipse/format/greclipse.properties) in the previous example. The formatter step can also load the [exported Eclipse properties](../ECLIPSE_SCREENSHOTS.md) and augment it with the `.metadata/.plugins/org.eclipse.core.runtime/.settings/org.codehaus.groovy.eclipse.ui.prefs` from your Eclipse workspace as shown below.
307307

308308
```gradle
309309
spotless {

0 commit comments

Comments
 (0)