Skip to content

Commit 60367e5

Browse files
authored
removeUnusedImports can use cleanThat backend (#1589)
2 parents 4ca8189 + 561aac8 commit 60367e5

File tree

19 files changed

+510
-45
lines changed

19 files changed

+510
-45
lines changed

lib/build.gradle

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,9 @@ dependencies {
114114

115115
gsonCompileOnly 'com.google.code.gson:gson:2.10.1'
116116

117-
cleanthatCompileOnly 'io.github.solven-eu.cleanthat:java:2.6'
118-
compatCleanthat2Dot1CompileAndTestOnly 'io.github.solven-eu.cleanthat:java:2.6'
117+
String VER_CLEANTHAT="2.8"
118+
cleanthatCompileOnly "io.github.solven-eu.cleanthat:java:$VER_CLEANTHAT"
119+
compatCleanthat2Dot1CompileAndTestOnly "io.github.solven-eu.cleanthat:java:$VER_CLEANTHAT"
119120

120121
gherkinCompileOnly 'io.cucumber:gherkin-utils:8.0.2'
121122
gherkinCompileOnly 'org.slf4j:slf4j-api:2.0.0'

lib/src/cleanthat/java/com/diffplug/spotless/glue/java/JavaCleanthatRefactorerFunc.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,7 @@ private String doApply(String input) throws InterruptedException, IOException {
8888
LOGGER.debug("Processing sourceJdk={} included={} excluded={}", jdkVersion, included, excluded, includeDraft);
8989
LOGGER.debug("Available mutators: {}", JavaRefactorer.getAllIncluded());
9090

91-
// Spotless calls steps always with LF eol.
92-
return refactorer.doFormat(input, LineEnding.LF);
91+
return refactorer.doFormat(input);
9392
}
9493

9594
}

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

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public final class CleanthatJavaStep {
4040
private static final String MAVEN_COORDINATE = "io.github.solven-eu.cleanthat:java";
4141

4242
// CleanThat changelog is available at https://github.com/solven-eu/cleanthat/blob/master/CHANGES.MD
43-
private static final Jvm.Support<String> JVM_SUPPORT = Jvm.<String> support(NAME).add(11, "2.6");
43+
private static final Jvm.Support<String> JVM_SUPPORT = Jvm.<String> support(NAME).add(11, "2.8");
4444

4545
// prevent direct instantiation
4646
private CleanthatJavaStep() {}
@@ -83,8 +83,8 @@ public static boolean defaultIncludeDraft() {
8383
public static FormatterStep create(String groupArtifact,
8484
String version,
8585
String sourceJdkVersion,
86-
List<String> excluded,
8786
List<String> included,
87+
List<String> excluded,
8888
boolean includeDraft,
8989
Provisioner provisioner) {
9090
Objects.requireNonNull(groupArtifact, "groupArtifact");
@@ -94,7 +94,7 @@ public static FormatterStep create(String groupArtifact,
9494
Objects.requireNonNull(version, "version");
9595
Objects.requireNonNull(provisioner, "provisioner");
9696
return FormatterStep.createLazy(NAME,
97-
() -> new JavaRefactorerState(NAME, groupArtifact, version, sourceJdkVersion, excluded, included, includeDraft, provisioner),
97+
() -> new JavaRefactorerState(NAME, groupArtifact, version, sourceJdkVersion, included, excluded, includeDraft, provisioner),
9898
JavaRefactorerState::createFormat);
9999
}
100100

@@ -120,7 +120,7 @@ static final class JavaRefactorerState implements Serializable {
120120
final boolean includeDraft;
121121

122122
JavaRefactorerState(String stepName, String version, Provisioner provisioner) throws IOException {
123-
this(stepName, MAVEN_COORDINATE, version, defaultSourceJdk(), defaultExcludedMutators(), defaultMutators(), defaultIncludeDraft(), provisioner);
123+
this(stepName, MAVEN_COORDINATE, version, defaultSourceJdk(), defaultMutators(), defaultExcludedMutators(), defaultIncludeDraft(), provisioner);
124124
}
125125

126126
JavaRefactorerState(String stepName,
@@ -131,10 +131,7 @@ static final class JavaRefactorerState implements Serializable {
131131
List<String> excluded,
132132
boolean includeDraft,
133133
Provisioner provisioner) throws IOException {
134-
// https://github.com/diffplug/spotless/issues/1583
135-
if (!version.endsWith("-SNAPSHOT")) {
136-
JVM_SUPPORT.assertFormatterSupported(version);
137-
}
134+
JVM_SUPPORT.assertFormatterSupported(version);
138135
ModuleHelper.doOpenInternalPackagesIfRequired();
139136
this.jarState = JarState.from(groupArtifact + ":" + version, provisioner);
140137
this.stepName = stepName;
@@ -162,17 +159,9 @@ FormatterFunc createFormat() {
162159
throw new IllegalStateException("Issue executing the formatter", e);
163160
}
164161

165-
// https://github.com/diffplug/spotless/issues/1583
166-
if (!version.endsWith("-SNAPSHOT")) {
167-
return JVM_SUPPORT.suggestLaterVersionOnError(version, input -> {
168-
return (String) formatterMethod.invoke(formatter, input);
169-
});
170-
} else {
171-
return input -> {
172-
return (String) formatterMethod.invoke(formatter, input);
173-
};
174-
}
162+
return JVM_SUPPORT.suggestLaterVersionOnError(version, input -> {
163+
return (String) formatterMethod.invoke(formatter, input);
164+
});
175165
}
176-
177166
}
178167
}

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

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016 DiffPlug
2+
* Copyright 2016-2023 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.
@@ -15,22 +15,47 @@
1515
*/
1616
package com.diffplug.spotless.java;
1717

18+
import java.util.Arrays;
1819
import java.util.Objects;
1920

2021
import com.diffplug.spotless.FormatterStep;
2122
import com.diffplug.spotless.Provisioner;
2223

23-
/** Uses google-java-format, but only to remove unused imports. */
24+
/** Uses google-java-format or cleanthat.UnnecessaryImport, but only to remove unused imports. */
2425
public class RemoveUnusedImportsStep {
26+
static final String NAME = "removeUnusedImports";
27+
28+
static final String GJF = "google-java-format";
29+
static final String CLEANTHAT = "cleanthat-javaparser-unnecessaryimport";
30+
31+
// https://github.com/solven-eu/cleanthat/blob/master/java/src/main/java/eu/solven/cleanthat/engine/java/refactorer/mutators/UnnecessaryImport.java
32+
private static final String CLEANTHAT_MUTATOR = "UnnecessaryImport";
33+
2534
// prevent direct instantiation
2635
private RemoveUnusedImportsStep() {}
2736

28-
static final String NAME = "removeUnusedImports";
37+
public static final String defaultFormatter() {
38+
return GJF;
39+
}
2940

3041
public static FormatterStep create(Provisioner provisioner) {
42+
// The default importRemover is GJF
43+
return create(GJF, provisioner);
44+
}
45+
46+
public static FormatterStep create(String unusedImportRemover, Provisioner provisioner) {
3147
Objects.requireNonNull(provisioner, "provisioner");
32-
return FormatterStep.createLazy(NAME,
33-
() -> new GoogleJavaFormatStep.State(NAME, GoogleJavaFormatStep.defaultVersion(), provisioner),
34-
GoogleJavaFormatStep.State::createRemoveUnusedImportsOnly);
48+
49+
if (GJF.equals(unusedImportRemover)) {
50+
return FormatterStep.createLazy(NAME,
51+
() -> new GoogleJavaFormatStep.State(NAME, GoogleJavaFormatStep.defaultVersion(), provisioner),
52+
GoogleJavaFormatStep.State::createRemoveUnusedImportsOnly);
53+
} else if (CLEANTHAT.equals(unusedImportRemover)) {
54+
return FormatterStep.createLazy(NAME,
55+
() -> new CleanthatJavaStep.JavaRefactorerState(NAME, CleanthatJavaStep.defaultGroupArtifact(), CleanthatJavaStep.defaultVersion(), "99.9", Arrays.asList(CLEANTHAT_MUTATOR), Arrays.asList(), false, provisioner),
56+
CleanthatJavaStep.JavaRefactorerState::createFormat);
57+
} else {
58+
throw new IllegalArgumentException("Invalid unusedImportRemover: " + unusedImportRemover);
59+
}
3560
}
3661
}

plugin-gradle/CHANGES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
44

55
## [Unreleased]
66
### Added
7+
* `removeUnusedImport` can be configured to rely on `cleanthat-javaparser-unnecessaryimport`. Default remains `google-java-format`. ([#1589](https://github.com/diffplug/spotless/pull/1589))
8+
### Changes
9+
* Bump default `cleanthat` version to latest `2.6` -> `2.8`. ([#1589](https://github.com/diffplug/spotless/pull/1589)
710
* Support configuration of mirrors for P2 repositories ([#1629](https://github.com/diffplug/spotless/issues/1629)):
811
```
912
spotless {

plugin-gradle/README.md

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,17 @@ spotless {
182182
target 'src/*/java/**/*.java'
183183
```
184184

185+
### removeUnusedImports
186+
187+
```
188+
spotless {
189+
java {
190+
removeUnusedImports()
191+
// optional: you may switch for `google-java-format` as underlying engine to `cleanthat-javaparser-unnecessaryimport`
192+
// which enables processing any language level source file with a JDK8+ Runtime
193+
removeUnusedImports().engine('cleanthat-javaparser-unnecessaryimport')
194+
```
195+
185196
### google-java-format
186197

187198
[homepage](https://github.com/google/google-java-format). [changelog](https://github.com/google/google-java-format/releases).
@@ -272,11 +283,13 @@ spotless {
272283
cleanthat()
273284
// optional: you can specify a specific version and/or config file
274285
cleanthat()
275-
.groupArtifact('1.7') // default is 'io.github.solven-eu.cleanthat:java'
276-
.version('2.1') // You may force a past of -SNAPSHOT
277-
.sourceCompatibility('1.7') // default is '1.7'
278-
.addMutator('your.custom.MagicMutator')
279-
.excludeMutator('UseCollectionIsEmpty')
286+
.groupArtifact('io.github.solven-eu.cleanthat:java') // Optional. Default is 'io.github.solven-eu.cleanthat:java'
287+
.version('2.8') // You may force a custom version of Cleanthat
288+
.sourceCompatibility('1.7') // default is '1.7'
289+
.addMutator('SafeAndConsensual') // Default includes the SafeAndConsensual composite mutator
290+
.addMutator('your.custom.MagicMutator') // List of mutators: https://github.com/solven-eu/cleanthat/blob/master/MUTATORS.generated.MD
291+
.excludeMutator('UseCollectionIsEmpty') // You may exclude some mutators (from Composite ones)
292+
.includeDraft(false) // You may exclude draft mutators (from Composite ones)
280293
```
281294

282295

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,11 @@ private FormatterStep createStep() {
109109

110110
/** Removes any unused imports. */
111111
public void removeUnusedImports() {
112-
addStep(RemoveUnusedImportsStep.create(provisioner()));
112+
addStep(RemoveUnusedImportsStep.create(RemoveUnusedImportsStep.defaultFormatter(), provisioner()));
113+
}
114+
115+
public void removeUnusedImports(String formatter) {
116+
addStep(RemoveUnusedImportsStep.create(formatter, provisioner()));
113117
}
114118

115119
/** Uses the <a href="https://github.com/google/google-java-format">google-java-format</a> jar to format source code. */

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,22 @@ void multipleBlocksShouldWork() throws IOException {
6262
gradleRunner().withArguments("spotlessApply").build();
6363
gradleRunner().withArguments("spotlessApply").build();
6464
}
65+
66+
@Test
67+
void removeUnusedImportsWithCleanthat() throws IOException {
68+
setFile("build.gradle").toLines(
69+
"plugins {",
70+
" id 'com.diffplug.spotless'",
71+
" id 'java'",
72+
"}",
73+
"repositories { mavenCentral() }",
74+
"",
75+
"spotless {",
76+
" java { removeUnusedImports('cleanthat-javaparser-unnecessaryimport') }",
77+
"}");
78+
79+
setFile("src/main/java/test.java").toResource("java/removeunusedimports/Jdk17TextBlockUnformatted.test");
80+
gradleRunner().withArguments("spotlessApply").build();
81+
assertFile("src/main/java/test.java").sameAsResource("java/removeunusedimports/Jdk17TextBlockFormatted.test");
82+
}
6583
}

plugin-maven/CHANGES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
44

55
## [Unreleased]
66
### Added
7+
* `removeUnusedImport` can be configured to rely on `cleanthat-javaparser-unnecessaryimport`. Default remains `google-java-format`. ([#1589](https://github.com/diffplug/spotless/pull/1589))
78
* The `style` option in Palantir Java Format ([#1654](https://github.com/diffplug/spotless/pull/1654)).
89
* Added support for Gherkin feature files ([#1649](https://github.com/diffplug/spotless/issues/1649)).
910
### Fixed
1011
* Fix non deterministic computation of cache fingerprint when using multiple formatters. ([#1643](https://github.com/diffplug/spotless/pull/1643) fixes [#1642](https://github.com/diffplug/spotless/pull/1642))
1112
### Changes
13+
* Bump default `cleanthat` version to latest `2.6` -> `2.8`. ([#1589](https://github.com/diffplug/spotless/pull/1589)
1214
* **POTENTIALLY BREAKING** Drop support for `googleJavaFormat` versions &lt; `1.8`. ([#1630](https://github.com/diffplug/spotless/pull/1630))
1315
* Bump default `googleJavaFormat` version `1.15.0` -> `1.16.0`. ([#1630](https://github.com/diffplug/spotless/pull/1630))
1416

plugin-maven/README.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,14 @@ any other maven phase (i.e. compile) then it can be configured as below;
208208
</configuration>
209209
```
210210

211+
### removeUnusedImports
212+
213+
```xml
214+
<removeUnusedImports>
215+
<engine>google-java-format</engine> <!-- optional. Defaults to `google-java-format`. Can be switched to `cleanthat-javaparser-unnecessaryimport` (e.g. to process JDK17 source files with a JDK8+ Runtime) -->
216+
</removeUnusedImports>
217+
```
218+
211219
### google-java-format
212220

213221
[homepage](https://github.com/google/google-java-format). [changelog](https://github.com/google/google-java-format/releases). [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/GoogleJavaFormat.java).
@@ -285,17 +293,18 @@ These mechanisms already exist for the Gradle plugin.
285293

286294
```xml
287295
<cleanthat>
288-
<version>2.0</version> <!-- optional version of Cleanthat -->
296+
<version>2.8</version> <!-- optional version of Cleanthat -->
289297
<sourceJdk>${maven.compiler.source}</sourceJdk> <!-- optional. Default to ${maven.compiler.source} else '1.7' -->
290298
<mutators>
291-
<mutator>*</mutator> <!-- optional. Default to '*' to include all mutators -->
299+
<mutator>SafeAndConsensual</mutator> <!-- optional. Default to 'SafeAndConsensual' to include all mutators -->
292300
</mutators>
293-
<mutators> <!-- List of mutators: https://github.com/solven-eu/cleanthat/tree/master/java/src/main/java/eu/solven/cleanthat/engine/java/refactorer/mutators -->
301+
<mutators> <!-- List of mutators: https://github.com/solven-eu/cleanthat/blob/master/MUTATORS.generated.MD -->
294302
<mutator>LiteralsFirstInComparisons</mutator> <!-- You may alternatively list the requested mutators -->
295303
</mutators>
296304
<excludedMutators>
297305
<excludedMutator>OptionalNotEmpty</excludedMutator> <!-- You can discard specific rules -->
298306
</excludedMutators>
307+
<includeDraft>false</includeDraft> <!-- optional. Default to false, not to include draft mutators from Composite mutators -->
299308
</cleanthat>
300309
```
301310

plugin-maven/src/main/java/com/diffplug/spotless/maven/java/RemoveUnusedImports.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016 DiffPlug
2+
* Copyright 2016-2023 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.
@@ -15,15 +15,20 @@
1515
*/
1616
package com.diffplug.spotless.maven.java;
1717

18+
import org.apache.maven.plugins.annotations.Parameter;
19+
1820
import com.diffplug.spotless.FormatterStep;
1921
import com.diffplug.spotless.java.RemoveUnusedImportsStep;
2022
import com.diffplug.spotless.maven.FormatterStepConfig;
2123
import com.diffplug.spotless.maven.FormatterStepFactory;
2224

2325
public class RemoveUnusedImports implements FormatterStepFactory {
2426

27+
@Parameter
28+
private String engine = RemoveUnusedImportsStep.defaultFormatter();
29+
2530
@Override
2631
public FormatterStep newFormatterStep(FormatterStepConfig config) {
27-
return RemoveUnusedImportsStep.create(config.getProvisioner());
32+
return RemoveUnusedImportsStep.create(engine, config.getProvisioner());
2833
}
2934
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package io.github.shafthq.shaft.tools.tms;
2+
3+
4+
5+
import static io.restassured.RestAssured.*;
6+
7+
public class XrayIntegrationHelper {
8+
private static String getLinkJIRATicketRequestBody() {
9+
return """
10+
{
11+
"update":{
12+
"issuelinks":[
13+
{
14+
"add":{
15+
"type":{
16+
"name":"Relates"
17+
},
18+
"outwardIssue":{
19+
"key":"${TICKET_ID}"
20+
}
21+
}
22+
}
23+
]
24+
}
25+
}
26+
""";
27+
}
28+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package io.github.shafthq.shaft.tools.tms;
2+
3+
import com.google.gson.Gson;
4+
import com.google.gson.GsonBuilder;
5+
import com.google.gson.JsonElement;
6+
import com.google.gson.JsonParser;
7+
import com.shaft.cli.FileActions;
8+
import com.shaft.tools.io.ReportManager;
9+
import io.github.shafthq.shaft.tools.io.helpers.ReportManagerHelper;
10+
import io.restassured.config.RestAssuredConfig;
11+
import io.restassured.config.SSLConfig;
12+
import io.restassured.http.ContentType;
13+
import io.restassured.response.Response;
14+
import io.restassured.specification.RequestSpecification;
15+
16+
import java.io.File;
17+
import java.nio.file.Files;
18+
import java.nio.file.Paths;
19+
import java.text.SimpleDateFormat;
20+
import java.util.Base64;
21+
import java.util.Calendar;
22+
import java.util.List;
23+
24+
import static io.restassured.RestAssured.*;
25+
import static io.restassured.config.EncoderConfig.encoderConfig;
26+
27+
28+
public class XrayIntegrationHelper {
29+
private static String getLinkJIRATicketRequestBody() {
30+
return """
31+
{
32+
"update":{
33+
"issuelinks":[
34+
{
35+
"add":{
36+
"type":{
37+
"name":"Relates"
38+
},
39+
"outwardIssue":{
40+
"key":"${TICKET_ID}"
41+
}
42+
}
43+
}
44+
]
45+
}
46+
}
47+
""";
48+
}
49+
}

0 commit comments

Comments
 (0)