Skip to content

Commit a9875a1

Browse files
committed
Add Gradle support for Maven POM sorting/formatting
1 parent aa113ff commit a9875a1

File tree

7 files changed

+344
-2
lines changed

7 files changed

+344
-2
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ lib('yaml.JacksonYamlStep') +'{{yes}} | {{yes}}
154154
| [`npm.EslintFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/EslintFormatterStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: |
155155
| [`npm.PrettierFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/PrettierFormatterStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: |
156156
| [`npm.TsFmtFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/TsFmtFormatterStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: |
157-
| [`pom.SortPomStepStep`](lib/src/main/java/com/diffplug/spotless/pom/SortPomStepStep.java) | :white_large_square: | :+1: | :white_large_square: | :white_large_square: |
157+
| [`pom.SortPomStep`](lib/src/main/java/com/diffplug/spotless/pom/SortPomStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: |
158158
| [`protobuf.BufStep`](lib/src/main/java/com/diffplug/spotless/protobuf/BufStep.java) | :+1: | :white_large_square: | :white_large_square: | :white_large_square: |
159159
| [`python.BlackStep`](lib/src/main/java/com/diffplug/spotless/python/BlackStep.java) | :+1: | :white_large_square: | :white_large_square: | :white_large_square: |
160160
| [`scala.ScalaFmtStep`](lib/src/main/java/com/diffplug/spotless/scala/ScalaFmtStep.java) | :+1: | :+1: | :+1: | :white_large_square: |

plugin-gradle/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
* Bump default `shfmt` version to latest `3.7.0` -> `3.8.0`. ([#2050](https://github.com/diffplug/spotless/pull/2050))
1212
### Added
1313
* Respect `.editorconfig` settings for formatting shell via `shfmt` ([#2031](https://github.com/diffplug/spotless/pull/2031))
14+
* Add support for formatting and sorting Maven POMs ([#2081](https://github.com/diffplug/spotless/issues/2081))
1415

1516
## [6.25.0] - 2024-01-23
1617
### Added

plugin-gradle/README.md

+47
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ Spotless supports all of Gradle's built-in performance features (incremental bui
6565
- [Flexmark](#flexmark) aka markdown
6666
- [Antlr4](#antlr4) ([antlr4formatter](#antlr4formatter))
6767
- [SQL](#sql) ([dbeaver](#dbeaver), [prettier](#prettier))
68+
- [Maven POM](#maven-pom) ([sortPom](#sortpom))
6869
- [Typescript](#typescript) ([tsfmt](#tsfmt), [prettier](#prettier), [ESLint](#eslint-typescript), [Biome](#biome))
6970
- [Javascript](#javascript) ([prettier](#prettier), [ESLint](#eslint-javascript), [Biome](#biome))
7071
- [JSON](#json) ([simple](#simple), [gson](#gson), [jackson](#jackson), [Biome](#biome), [jsonPatch](#jsonPatch))
@@ -676,6 +677,52 @@ sql.formatter.indent.type=space
676677
sql.formatter.indent.size=4
677678
```
678679
680+
## Maven POM
681+
682+
`com.diffplug.gradle.spotless.PomExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/6.25.0/com/diffplug/gradle/spotless/PomExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/PomExtension.java)
683+
684+
```gradle
685+
spotless {
686+
pom {
687+
target('pom.xml') // default value, you can change if you want
688+
689+
sortPom() // has its own section below
690+
}
691+
}
692+
```
693+
694+
### sortPom
695+
696+
[homepage](https://github.com/Ekryd/sortpom).
697+
698+
All configuration settings are optional, they are described in detail [here](https://github.com/Ekryd/sortpom/wiki/Parameters).
699+
700+
```gradle
701+
spotless {
702+
pom {
703+
sortPom('3.4.0')
704+
.encoding('UTF-8') // The encoding of the pom files
705+
.lineSeparator(System.getProperty('line.separator')) // line separator to use
706+
.expandEmptyElements(true) // Should empty elements be expanded
707+
.spaceBeforeCloseEmptyElement(false) // Should a space be added inside self-closing elements
708+
.keepBlankLines(true) // Keep empty lines
709+
.endWithNewline(true) // Whether sorted pom ends with a newline
710+
.nrOfIndentSpace(2) // Indentation
711+
.indentBlankLines(false) // Should empty lines be indented
712+
.indentSchemaLocation(false) // Should schema locations be indented
713+
.predefinedSortOrder('recommended_2008_06') // Sort order of elements: https://github.com/Ekryd/sortpom/wiki/PredefinedSortOrderProfiles
714+
.sortOrderFile(null) // Custom sort order of elements: https://raw.githubusercontent.com/Ekryd/sortpom/master/sorter/src/main/resources/custom_1.xml
715+
.sortDependencies(null) // Sort dependencies: https://github.com/Ekryd/sortpom/wiki/SortDependencies
716+
.sortDependencyManagement(null) // Sort dependency management: https://github.com/Ekryd/sortpom/wiki/SortDependencies
717+
.sortDependencyExclusions(null) // Sort dependency exclusions: https://github.com/Ekryd/sortpom/wiki/SortDependencies
718+
.sortPlugins(null) // Sort plugins: https://github.com/Ekryd/sortpom/wiki/SortPlugins
719+
.sortProperties(false) // Sort properties
720+
.sortModules(false) // Sort modules
721+
.sortExecutions(false) // Sort plugin executions
722+
}
723+
}
724+
```
725+
679726
<a name="applying-to-typescript-source"></a>
680727
681728
## Typescript
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
/*
2+
* Copyright 2024 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.gradle.spotless;
17+
18+
import java.util.Objects;
19+
20+
import javax.inject.Inject;
21+
22+
import com.diffplug.spotless.FormatterStep;
23+
import com.diffplug.spotless.pom.SortPomCfg;
24+
import com.diffplug.spotless.pom.SortPomStep;
25+
26+
public class PomExtension extends FormatExtension {
27+
private static final String POM_FILE = "pom.xml";
28+
29+
static final String NAME = "pom";
30+
31+
@Inject
32+
public PomExtension(SpotlessExtension spotless) {
33+
super(spotless);
34+
}
35+
36+
@Override
37+
protected void setupTask(SpotlessTask task) {
38+
if (target == null) {
39+
target = parseTarget(POM_FILE);
40+
}
41+
super.setupTask(task);
42+
}
43+
44+
public SortPomGradleConfig sortPom() {
45+
return new SortPomGradleConfig();
46+
}
47+
48+
public SortPomGradleConfig sortPom(String version) {
49+
Objects.requireNonNull(version);
50+
return new SortPomGradleConfig(version);
51+
}
52+
53+
public class SortPomGradleConfig {
54+
final SortPomCfg cfg = new SortPomCfg();
55+
56+
SortPomGradleConfig() {
57+
addStep(createStep());
58+
}
59+
60+
SortPomGradleConfig(String version) {
61+
this();
62+
cfg.version = Objects.requireNonNull(version);
63+
}
64+
65+
public SortPomGradleConfig encoding(String encoding) {
66+
cfg.encoding = encoding;
67+
return this;
68+
}
69+
70+
public SortPomGradleConfig lineSeparator(String lineSeparator) {
71+
cfg.lineSeparator = lineSeparator;
72+
return this;
73+
}
74+
75+
public SortPomGradleConfig expandEmptyElements(boolean expandEmptyElements) {
76+
cfg.expandEmptyElements = expandEmptyElements;
77+
return this;
78+
}
79+
80+
public SortPomGradleConfig spaceBeforeCloseEmptyElement(boolean spaceBeforeCloseEmptyElement) {
81+
cfg.spaceBeforeCloseEmptyElement = spaceBeforeCloseEmptyElement;
82+
return this;
83+
}
84+
85+
public SortPomGradleConfig keepBlankLines(boolean keepBlankLines) {
86+
cfg.keepBlankLines = keepBlankLines;
87+
return this;
88+
}
89+
90+
public SortPomGradleConfig endWithNewline(boolean endWithNewline) {
91+
cfg.endWithNewline = endWithNewline;
92+
return this;
93+
}
94+
95+
public SortPomGradleConfig nrOfIndentSpace(int nrOfIndentSpace) {
96+
cfg.nrOfIndentSpace = nrOfIndentSpace;
97+
return this;
98+
}
99+
100+
public SortPomGradleConfig indentBlankLines(boolean indentBlankLines) {
101+
cfg.indentBlankLines = indentBlankLines;
102+
return this;
103+
}
104+
105+
public SortPomGradleConfig indentSchemaLocation(boolean indentSchemaLocation) {
106+
cfg.indentSchemaLocation = indentSchemaLocation;
107+
return this;
108+
}
109+
110+
public SortPomGradleConfig predefinedSortOrder(String predefinedSortOrder) {
111+
cfg.predefinedSortOrder = predefinedSortOrder;
112+
return this;
113+
}
114+
115+
public SortPomGradleConfig sortOrderFile(String sortOrderFile) {
116+
cfg.sortOrderFile = sortOrderFile;
117+
return this;
118+
}
119+
120+
public SortPomGradleConfig sortDependencies(String sortDependencies) {
121+
cfg.sortDependencies = sortDependencies;
122+
return this;
123+
}
124+
125+
public SortPomGradleConfig sortDependencyManagement(String sortDependencyManagement) {
126+
cfg.sortDependencyManagement = sortDependencyManagement;
127+
return this;
128+
}
129+
130+
public SortPomGradleConfig sortDependencyExclusions(String sortDependencyExclusions) {
131+
cfg.sortDependencyExclusions = sortDependencyExclusions;
132+
return this;
133+
}
134+
135+
public SortPomGradleConfig sortPlugins(String sortPlugins) {
136+
cfg.sortPlugins = sortPlugins;
137+
return this;
138+
}
139+
140+
public SortPomGradleConfig sortProperties(boolean sortProperties) {
141+
cfg.sortProperties = sortProperties;
142+
return this;
143+
}
144+
145+
public SortPomGradleConfig sortModules(boolean sortModules) {
146+
cfg.sortModules = sortModules;
147+
return this;
148+
}
149+
150+
public SortPomGradleConfig sortExecutions(boolean sortExecutions) {
151+
cfg.sortExecutions = sortExecutions;
152+
return this;
153+
}
154+
155+
private FormatterStep createStep() {
156+
return SortPomStep.create(cfg, provisioner());
157+
}
158+
}
159+
}

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

+6
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,12 @@ public void go(Action<GoExtension> closure) {
228228
format(GoExtension.NAME, GoExtension.class, closure);
229229
}
230230

231+
/** Configures the special POM-specific extension. */
232+
public void pom(Action<PomExtension> closure) {
233+
requireNonNull(closure);
234+
format(PomExtension.NAME, PomExtension.class, closure);
235+
}
236+
231237
/** Configures a custom extension. */
232238
public void format(String name, Action<FormatExtension> closure) {
233239
requireNonNull(name, "name");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/*
2+
* Copyright 2024 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.gradle.spotless;
17+
18+
import org.junit.jupiter.api.Test;
19+
20+
class SortPomGradleTest extends GradleIntegrationHarness {
21+
@Test
22+
void sortPom() throws Exception {
23+
// given
24+
setFile("build.gradle").toLines(
25+
"plugins {",
26+
" id 'com.diffplug.spotless'",
27+
"}",
28+
"repositories { mavenCentral() }",
29+
"spotless {",
30+
" pom {",
31+
" sortPom()",
32+
" }",
33+
"}");
34+
setFile("pom.xml").toResource("pom/pom_dirty.xml");
35+
36+
// when
37+
gradleRunner().withArguments("spotlessApply").build();
38+
39+
// then
40+
assertFile("pom.xml").sameAsResource("pom/pom_clean_default.xml");
41+
}
42+
43+
@Test
44+
void sortPomWithTarget() throws Exception {
45+
// given
46+
setFile("build.gradle").toLines(
47+
"plugins {",
48+
" id 'com.diffplug.spotless'",
49+
"}",
50+
"repositories { mavenCentral() }",
51+
"spotless {",
52+
" pom {",
53+
" target('test.xml')",
54+
" sortPom()",
55+
" }",
56+
"}");
57+
setFile("test.xml").toResource("pom/pom_dirty.xml");
58+
59+
// when
60+
gradleRunner().withArguments("spotlessApply").build();
61+
62+
// then
63+
assertFile("test.xml").sameAsResource("pom/pom_clean_default.xml");
64+
}
65+
66+
@Test
67+
void sortPomWithVersion() throws Exception {
68+
// given
69+
setFile("build.gradle").toLines(
70+
"plugins {",
71+
" id 'com.diffplug.spotless'",
72+
"}",
73+
"repositories { mavenCentral() }",
74+
"spotless {",
75+
" pom {",
76+
" sortPom '3.4.0'",
77+
" }",
78+
"}");
79+
setFile("pom.xml").toResource("pom/pom_dirty.xml");
80+
81+
// when
82+
gradleRunner().withArguments("spotlessApply").build();
83+
84+
// then
85+
assertFile("pom.xml").sameAsResource("pom/pom_clean_default.xml");
86+
}
87+
88+
@Test
89+
void sortPomWithParameters() throws Exception {
90+
// given
91+
setFile("build.gradle").toLines(
92+
"plugins {",
93+
" id 'com.diffplug.spotless'",
94+
"}",
95+
"repositories { mavenCentral() }",
96+
"spotless {",
97+
" pom {",
98+
" sortPom()",
99+
" .encoding('UTF-8')",
100+
" .lineSeparator(System.getProperty('line.separator'))",
101+
" .expandEmptyElements(true)",
102+
" .spaceBeforeCloseEmptyElement(false)",
103+
" .keepBlankLines(true)",
104+
" .endWithNewline(true)",
105+
" .nrOfIndentSpace(2)",
106+
" .indentBlankLines(false)",
107+
" .indentSchemaLocation(false)",
108+
" .predefinedSortOrder('recommended_2008_06')",
109+
" .sortOrderFile(null)",
110+
" .sortDependencies(null)",
111+
" .sortDependencyManagement(null)",
112+
" .sortDependencyExclusions(null)",
113+
" .sortPlugins(null)",
114+
" .sortProperties(false)",
115+
" .sortModules(false)",
116+
" .sortExecutions(false)",
117+
" }",
118+
"}");
119+
setFile("pom.xml").toResource("pom/pom_dirty.xml");
120+
121+
// when
122+
gradleRunner().withArguments("spotlessApply").build();
123+
124+
// then
125+
assertFile("pom.xml").sameAsResource("pom/pom_clean_default.xml");
126+
}
127+
}

plugin-maven/README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -665,14 +665,16 @@ All configuration settings are optional, they are described in detail [here](htt
665665

666666
<indentBlankLines>false</indentBlankLines> <!-- Should empty lines be indented -->
667667

668-
<indentSchemaLocation>false</indentSchemaLocation> <!-- Should schema locations be indended -->
668+
<indentSchemaLocation>false</indentSchemaLocation> <!-- Should schema locations be indented -->
669669

670670
<predefinedSortOrder>recommended_2008_06</predefinedSortOrder> <!-- Sort order of elements: https://github.com/Ekryd/sortpom/wiki/PredefinedSortOrderProfiles-->
671671

672672
<sortOrderFile></sortOrderFile> <!-- Custom sort order of elements: https://raw.githubusercontent.com/Ekryd/sortpom/master/sorter/src/main/resources/custom_1.xml -->
673673

674674
<sortDependencies></sortDependencies> <!-- Sort dependencies: https://github.com/Ekryd/sortpom/wiki/SortDependencies-->
675675

676+
<sortDependencyManagement></sortDependencyManagement> <!-- Sort dependency management: https://github.com/Ekryd/sortpom/wiki/SortDependencies-->
677+
676678
<sortDependencyExclusions></sortDependencyExclusions> <!-- Sort dependency exclusions: https://github.com/Ekryd/sortpom/wiki/SortDependencies-->
677679

678680
<sortPlugins></sortPlugins> <!-- Sort plugins: https://github.com/Ekryd/sortpom/wiki/SortPlugins -->

0 commit comments

Comments
 (0)