Skip to content

Commit 2b05af1

Browse files
authored
Add a step to remove semicolons in Groovy files (#1900)
2 parents 0570045 + ad2f3ca commit 2b05af1

File tree

13 files changed

+223
-6
lines changed

13 files changed

+223
-6
lines changed

CHANGES.md

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
1616
* Fix Eclipse JDT on some settings files. ([#1864](https://github.com/diffplug/spotless/pull/1864) fixes [#1638](https://github.com/diffplug/spotless/issues/1638))
1717
### Changes
1818
* Bump default `ktlint` version to latest `1.0.0` -> `1.0.1`. ([#1855](https://github.com/diffplug/spotless/pull/1855))
19+
* Add a Step to remove semicolons from Groovy files. ([#1881](https://github.com/diffplug/spotless/pull/1881))
1920

2021
## [2.42.0] - 2023-09-28
2122
### Added
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* Copyright 2023 DiffPlug
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.diffplug.spotless.groovy;
17+
18+
import java.io.BufferedReader;
19+
import java.io.Serializable;
20+
import java.io.StringReader;
21+
22+
import com.diffplug.spotless.FormatterFunc;
23+
import com.diffplug.spotless.FormatterStep;
24+
25+
/**
26+
* Removes all semicolons from the end of lines.
27+
*
28+
* @author Jose Luis Badano
29+
*/
30+
public final class RemoveSemicolonsStep {
31+
private static final String NAME = "Remove unnecessary semicolons";
32+
33+
private RemoveSemicolonsStep() {
34+
// do not instantiate
35+
}
36+
37+
public static FormatterStep create() {
38+
return FormatterStep.createLazy(NAME,
39+
State::new,
40+
RemoveSemicolonsStep.State::toFormatter);
41+
}
42+
43+
private static final class State implements Serializable {
44+
private static final long serialVersionUID = 1L;
45+
46+
FormatterFunc toFormatter() {
47+
return raw -> {
48+
try (BufferedReader reader = new BufferedReader(new StringReader(raw))) {
49+
StringBuilder result = new StringBuilder();
50+
String line;
51+
while ((line = reader.readLine()) != null) {
52+
result.append(removeSemicolon(line));
53+
result.append(System.lineSeparator());
54+
}
55+
return result.toString();
56+
}
57+
};
58+
}
59+
60+
/**
61+
* Removes the last semicolon in a line if it exists.
62+
*
63+
* @param line the line to remove the semicolon from
64+
* @return the line without the last semicolon
65+
*/
66+
private String removeSemicolon(String line) {
67+
// find last semicolon in a string a remove it
68+
int lastSemicolon = line.lastIndexOf(";");
69+
if (lastSemicolon != -1 && lastSemicolon == line.length() - 1) {
70+
return line.substring(0, lastSemicolon);
71+
} else {
72+
return line;
73+
}
74+
}
75+
}
76+
}

plugin-gradle/CHANGES.md

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
1010
* Check if EditorConfig file exist for Ktlint in KotlinGradleExtension. ([#1889](https://github.com/diffplug/spotless/pull/1889))
1111
### Changes
1212
* Bump default `ktlint` version to latest `1.0.0` -> `1.0.1`. ([#1855](https://github.com/diffplug/spotless/pull/1855))
13+
* Add a Step to remove semicolons from Groovy files. ([#1881](https://github.com/diffplug/spotless/pull/1881))
1314
### Fixed
1415
* Fix `GoogleJavaFormatConfig.reorderImports` not working. ([#1872](https://github.com/diffplug/spotless/issues/1872))
1516

plugin-gradle/README.md

+8-3
Original file line numberDiff line numberDiff line change
@@ -320,13 +320,18 @@ spotless {
320320
// optional: instead of specifying import groups directly you can specify a config file
321321
// export config file: https://github.com/diffplug/spotless/blob/main/ECLIPSE_SCREENSHOTS.md#creating-spotlessimportorder
322322
importOrderFile('eclipse-import-order.txt') // import order file as exported from eclipse
323-
324-
excludeJava() // excludes all Java sources within the Groovy source dirs from formatting
323+
// removes semicolons at the end of lines
324+
removeSemicolons()
325325
// the Groovy Eclipse formatter extends the Java Eclipse formatter,
326326
// so it formats Java files by default (unless `excludeJava` is used).
327327
greclipse() // has its own section below
328+
329+
licenseHeader('/* (C) $YEAR */') // or licenseHeaderFile
328330
329-
licenseHeader '/* (C) $YEAR */' // or licenseHeaderFile
331+
//---- Below is for `groovy` only ----
332+
333+
// excludes all Java sources within the Groovy source dirs from formatting
334+
excludeJava()
330335
}
331336
groovyGradle {
332337
target '*.gradle' // default target of groovyGradle

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

+5
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
import com.diffplug.spotless.extra.EquoBasedStepBuilder;
2626
import com.diffplug.spotless.extra.groovy.GrEclipseFormatterStep;
27+
import com.diffplug.spotless.groovy.RemoveSemicolonsStep;
2728
import com.diffplug.spotless.java.ImportOrderStep;
2829

2930
abstract class BaseGroovyExtension extends FormatExtension {
@@ -40,6 +41,10 @@ public void importOrderFile(Object importOrderFile) {
4041
addStep(ImportOrderStep.forGroovy().createFrom(getProject().file(importOrderFile)));
4142
}
4243

44+
public void removeSemicolons() {
45+
addStep(RemoveSemicolonsStep.create());
46+
}
47+
4348
public GrEclipseConfig greclipse() {
4449
return greclipse(GrEclipseFormatterStep.defaultVersion());
4550
}

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

+21
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,27 @@ void excludeJavaWithCustomTarget() throws IOException {
8888
assertThat(error).hasMessageContaining("'excludeJava' is not supported");
8989
}
9090

91+
@Test
92+
void removeSemicolons() throws IOException {
93+
setFile("build.gradle").toLines(
94+
"plugins {",
95+
" id 'com.diffplug.spotless'",
96+
"}",
97+
"apply plugin: 'groovy'",
98+
"",
99+
"spotless {",
100+
" groovy {",
101+
" removeSemicolons()",
102+
" }",
103+
"}");
104+
105+
String withSemicolons = getTestResource("groovy/removeSemicolons/GroovyCodeWithSemicolons.test");
106+
String withoutSemicolons = getTestResource("groovy/removeSemicolons/GroovyCodeWithSemicolonsFormatted.test");
107+
setFile("src/main/groovy/test.groovy").toContent(withSemicolons);
108+
gradleRunner().withArguments("spotlessApply").build();
109+
assertFile("src/main/groovy/test.groovy").hasContent(withoutSemicolons);
110+
}
111+
91112
@Test
92113
void groovyPluginMissingCheck() throws IOException {
93114
setFile("build.gradle").toLines(

plugin-maven/CHANGES.md

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
1111
* Fix Eclipse JDT on some settings files. ([#1864](https://github.com/diffplug/spotless/pull/1864) fixes [#1638](https://github.com/diffplug/spotless/issues/1638))
1212
### Changes
1313
* Bump default `ktlint` version to latest `1.0.0` -> `1.0.1`. ([#1855](https://github.com/diffplug/spotless/pull/1855))
14+
* Add a Step to remove semicolons from Groovy files. ([#1881](https://github.com/diffplug/spotless/pull/1881))
1415

1516
## [2.40.0] - 2023-09-28
1617
### Added

plugin-maven/README.md

+5-3
Original file line numberDiff line numberDiff line change
@@ -331,14 +331,16 @@ These mechanisms already exist for the Gradle plugin.
331331
<include>src/test/groovy/**/*.groovy</include>
332332
</includes>
333333

334-
<importOrder /> <!-- standard import order -->
334+
<importOrder/> <!-- standard import order -->
335335
<importOrder> <!-- or a custom ordering -->
336336
<order>java|javax,org,com,com.diffplug,,\#com.diffplug,\#</order> <!-- or use <file>${project.basedir}/eclipse.importorder</file> -->
337337
<!-- 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. -->
338338
</importOrder>
339+
340+
<removeSemicolons/> <!-- removes semicolons at the end of lines -->
341+
<greclipse/> <!-- has its own section below -->
339342

340-
<greclipse /> <!-- has its own section below -->
341-
343+
<excludeJava/>
342344
<licenseHeader>
343345
<content>/* (C)$YEAR */</content> <!-- or <file>${project.basedir}/license-header</file> -->
344346
</licenseHeader>

plugin-maven/src/main/java/com/diffplug/spotless/maven/groovy/Groovy.java

+4
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,8 @@ public void addGreclipse(GrEclipse greclipse) {
5252
public void addImportOrder(ImportOrder importOrder) {
5353
addStepFactory(importOrder);
5454
}
55+
56+
public void addRemoveSemicolons(RemoveSemicolons removeSemicolons) {
57+
addStepFactory(removeSemicolons);
58+
}
5559
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright 2016-2023 DiffPlug
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.diffplug.spotless.maven.groovy;
17+
18+
import com.diffplug.spotless.FormatterStep;
19+
import com.diffplug.spotless.groovy.RemoveSemicolonsStep;
20+
import com.diffplug.spotless.maven.FormatterStepConfig;
21+
import com.diffplug.spotless.maven.FormatterStepFactory;
22+
23+
public class RemoveSemicolons implements FormatterStepFactory {
24+
25+
@Override
26+
public FormatterStep newFormatterStep(FormatterStepConfig config) {
27+
return RemoveSemicolonsStep.create();
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright 2023 DiffPlug
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.diffplug.spotless.maven.groovy;
17+
18+
import org.junit.jupiter.api.Test;
19+
20+
import com.diffplug.spotless.maven.MavenIntegrationHarness;
21+
22+
class RemoveSemicolonsTest extends MavenIntegrationHarness {
23+
24+
@Test
25+
void testRemoveSemicolonsString() throws Exception {
26+
writePomWithGroovySteps("<removeSemicolons/>");
27+
runTest("Hello World;", "Hello World");
28+
}
29+
30+
@Test
31+
void testNotRemoveSemicolonsString() throws Exception {
32+
writePomWithGroovySteps("<removeSemicolons/>");
33+
runTest("Hello;World", "Hello;World");
34+
}
35+
36+
@Test
37+
void testRemoveSemicolons() throws Exception {
38+
writePomWithGroovySteps("<removeSemicolons/>");
39+
40+
String path = "src/main/groovy/test.groovy";
41+
setFile(path).toResource("groovy/removeSemicolons/GroovyCodeWithSemicolons.test");
42+
mavenRunner().withArguments("spotless:apply").runNoError();
43+
assertFile(path).sameAsResource("groovy/removeSemicolons/GroovyCodeWithSemicolonsFormatted.test");
44+
}
45+
46+
private void runTest(String sourceContent, String targetContent) throws Exception {
47+
String path = "src/main/groovy/test.groovy";
48+
setFile(path).toContent(sourceContent);
49+
mavenRunner().withArguments("spotless:apply").runNoError();
50+
assertFile(path).hasContent(targetContent);
51+
}
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import mylib.Unused;
2+
import mylib.UsedB;
3+
import mylib.UsedA;
4+
5+
public class SomeClass {
6+
System.out.println("hello");
7+
UsedB.someMethod();
8+
UsedA.someMethod();
9+
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import mylib.Unused
2+
import mylib.UsedB
3+
import mylib.UsedA
4+
5+
public class SomeClass {
6+
System.out.println("hello")
7+
UsedB.someMethod()
8+
UsedA.someMethod()
9+
}
10+
}

0 commit comments

Comments
 (0)