From a9875a19e097635cefc5350870440eaec4788210 Mon Sep 17 00:00:00 2001 From: Mark Chesney Date: Sat, 30 Mar 2024 19:36:45 -0700 Subject: [PATCH 1/4] Add Gradle support for Maven POM sorting/formatting --- README.md | 2 +- plugin-gradle/CHANGES.md | 1 + plugin-gradle/README.md | 47 ++++++ .../gradle/spotless/PomExtension.java | 159 ++++++++++++++++++ .../gradle/spotless/SpotlessExtension.java | 6 + .../gradle/spotless/SortPomGradleTest.java | 127 ++++++++++++++ plugin-maven/README.md | 4 +- 7 files changed, 344 insertions(+), 2 deletions(-) create mode 100644 plugin-gradle/src/main/java/com/diffplug/gradle/spotless/PomExtension.java create mode 100644 plugin-gradle/src/test/java/com/diffplug/gradle/spotless/SortPomGradleTest.java diff --git a/README.md b/README.md index 3c5d13b179..00864c559a 100644 --- a/README.md +++ b/README.md @@ -154,7 +154,7 @@ lib('yaml.JacksonYamlStep') +'{{yes}} | {{yes}} | [`npm.EslintFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/EslintFormatterStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: | | [`npm.PrettierFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/PrettierFormatterStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: | | [`npm.TsFmtFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/TsFmtFormatterStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: | -| [`pom.SortPomStepStep`](lib/src/main/java/com/diffplug/spotless/pom/SortPomStepStep.java) | :white_large_square: | :+1: | :white_large_square: | :white_large_square: | +| [`pom.SortPomStep`](lib/src/main/java/com/diffplug/spotless/pom/SortPomStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: | | [`protobuf.BufStep`](lib/src/main/java/com/diffplug/spotless/protobuf/BufStep.java) | :+1: | :white_large_square: | :white_large_square: | :white_large_square: | | [`python.BlackStep`](lib/src/main/java/com/diffplug/spotless/python/BlackStep.java) | :+1: | :white_large_square: | :white_large_square: | :white_large_square: | | [`scala.ScalaFmtStep`](lib/src/main/java/com/diffplug/spotless/scala/ScalaFmtStep.java) | :+1: | :+1: | :+1: | :white_large_square: | diff --git a/plugin-gradle/CHANGES.md b/plugin-gradle/CHANGES.md index bac42cee6e..e58fd5cfb6 100644 --- a/plugin-gradle/CHANGES.md +++ b/plugin-gradle/CHANGES.md @@ -11,6 +11,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( * Bump default `shfmt` version to latest `3.7.0` -> `3.8.0`. ([#2050](https://github.com/diffplug/spotless/pull/2050)) ### Added * Respect `.editorconfig` settings for formatting shell via `shfmt` ([#2031](https://github.com/diffplug/spotless/pull/2031)) +* Add support for formatting and sorting Maven POMs ([#2081](https://github.com/diffplug/spotless/issues/2081)) ## [6.25.0] - 2024-01-23 ### Added diff --git a/plugin-gradle/README.md b/plugin-gradle/README.md index db76229450..d5a6aba912 100644 --- a/plugin-gradle/README.md +++ b/plugin-gradle/README.md @@ -65,6 +65,7 @@ Spotless supports all of Gradle's built-in performance features (incremental bui - [Flexmark](#flexmark) aka markdown - [Antlr4](#antlr4) ([antlr4formatter](#antlr4formatter)) - [SQL](#sql) ([dbeaver](#dbeaver), [prettier](#prettier)) + - [Maven POM](#maven-pom) ([sortPom](#sortpom)) - [Typescript](#typescript) ([tsfmt](#tsfmt), [prettier](#prettier), [ESLint](#eslint-typescript), [Biome](#biome)) - [Javascript](#javascript) ([prettier](#prettier), [ESLint](#eslint-javascript), [Biome](#biome)) - [JSON](#json) ([simple](#simple), [gson](#gson), [jackson](#jackson), [Biome](#biome), [jsonPatch](#jsonPatch)) @@ -676,6 +677,52 @@ sql.formatter.indent.type=space sql.formatter.indent.size=4 ``` +## Maven POM + +`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) + +```gradle +spotless { + pom { + target('pom.xml') // default value, you can change if you want + + sortPom() // has its own section below + } +} +``` + +### sortPom + +[homepage](https://github.com/Ekryd/sortpom). + +All configuration settings are optional, they are described in detail [here](https://github.com/Ekryd/sortpom/wiki/Parameters). + +```gradle +spotless { + pom { + sortPom('3.4.0') + .encoding('UTF-8') // The encoding of the pom files + .lineSeparator(System.getProperty('line.separator')) // line separator to use + .expandEmptyElements(true) // Should empty elements be expanded + .spaceBeforeCloseEmptyElement(false) // Should a space be added inside self-closing elements + .keepBlankLines(true) // Keep empty lines + .endWithNewline(true) // Whether sorted pom ends with a newline + .nrOfIndentSpace(2) // Indentation + .indentBlankLines(false) // Should empty lines be indented + .indentSchemaLocation(false) // Should schema locations be indented + .predefinedSortOrder('recommended_2008_06') // Sort order of elements: https://github.com/Ekryd/sortpom/wiki/PredefinedSortOrderProfiles + .sortOrderFile(null) // Custom sort order of elements: https://raw.githubusercontent.com/Ekryd/sortpom/master/sorter/src/main/resources/custom_1.xml + .sortDependencies(null) // Sort dependencies: https://github.com/Ekryd/sortpom/wiki/SortDependencies + .sortDependencyManagement(null) // Sort dependency management: https://github.com/Ekryd/sortpom/wiki/SortDependencies + .sortDependencyExclusions(null) // Sort dependency exclusions: https://github.com/Ekryd/sortpom/wiki/SortDependencies + .sortPlugins(null) // Sort plugins: https://github.com/Ekryd/sortpom/wiki/SortPlugins + .sortProperties(false) // Sort properties + .sortModules(false) // Sort modules + .sortExecutions(false) // Sort plugin executions + } +} +``` + ## Typescript diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/PomExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/PomExtension.java new file mode 100644 index 0000000000..a7f3b0389c --- /dev/null +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/PomExtension.java @@ -0,0 +1,159 @@ +/* + * Copyright 2024 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.gradle.spotless; + +import java.util.Objects; + +import javax.inject.Inject; + +import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.pom.SortPomCfg; +import com.diffplug.spotless.pom.SortPomStep; + +public class PomExtension extends FormatExtension { + private static final String POM_FILE = "pom.xml"; + + static final String NAME = "pom"; + + @Inject + public PomExtension(SpotlessExtension spotless) { + super(spotless); + } + + @Override + protected void setupTask(SpotlessTask task) { + if (target == null) { + target = parseTarget(POM_FILE); + } + super.setupTask(task); + } + + public SortPomGradleConfig sortPom() { + return new SortPomGradleConfig(); + } + + public SortPomGradleConfig sortPom(String version) { + Objects.requireNonNull(version); + return new SortPomGradleConfig(version); + } + + public class SortPomGradleConfig { + final SortPomCfg cfg = new SortPomCfg(); + + SortPomGradleConfig() { + addStep(createStep()); + } + + SortPomGradleConfig(String version) { + this(); + cfg.version = Objects.requireNonNull(version); + } + + public SortPomGradleConfig encoding(String encoding) { + cfg.encoding = encoding; + return this; + } + + public SortPomGradleConfig lineSeparator(String lineSeparator) { + cfg.lineSeparator = lineSeparator; + return this; + } + + public SortPomGradleConfig expandEmptyElements(boolean expandEmptyElements) { + cfg.expandEmptyElements = expandEmptyElements; + return this; + } + + public SortPomGradleConfig spaceBeforeCloseEmptyElement(boolean spaceBeforeCloseEmptyElement) { + cfg.spaceBeforeCloseEmptyElement = spaceBeforeCloseEmptyElement; + return this; + } + + public SortPomGradleConfig keepBlankLines(boolean keepBlankLines) { + cfg.keepBlankLines = keepBlankLines; + return this; + } + + public SortPomGradleConfig endWithNewline(boolean endWithNewline) { + cfg.endWithNewline = endWithNewline; + return this; + } + + public SortPomGradleConfig nrOfIndentSpace(int nrOfIndentSpace) { + cfg.nrOfIndentSpace = nrOfIndentSpace; + return this; + } + + public SortPomGradleConfig indentBlankLines(boolean indentBlankLines) { + cfg.indentBlankLines = indentBlankLines; + return this; + } + + public SortPomGradleConfig indentSchemaLocation(boolean indentSchemaLocation) { + cfg.indentSchemaLocation = indentSchemaLocation; + return this; + } + + public SortPomGradleConfig predefinedSortOrder(String predefinedSortOrder) { + cfg.predefinedSortOrder = predefinedSortOrder; + return this; + } + + public SortPomGradleConfig sortOrderFile(String sortOrderFile) { + cfg.sortOrderFile = sortOrderFile; + return this; + } + + public SortPomGradleConfig sortDependencies(String sortDependencies) { + cfg.sortDependencies = sortDependencies; + return this; + } + + public SortPomGradleConfig sortDependencyManagement(String sortDependencyManagement) { + cfg.sortDependencyManagement = sortDependencyManagement; + return this; + } + + public SortPomGradleConfig sortDependencyExclusions(String sortDependencyExclusions) { + cfg.sortDependencyExclusions = sortDependencyExclusions; + return this; + } + + public SortPomGradleConfig sortPlugins(String sortPlugins) { + cfg.sortPlugins = sortPlugins; + return this; + } + + public SortPomGradleConfig sortProperties(boolean sortProperties) { + cfg.sortProperties = sortProperties; + return this; + } + + public SortPomGradleConfig sortModules(boolean sortModules) { + cfg.sortModules = sortModules; + return this; + } + + public SortPomGradleConfig sortExecutions(boolean sortExecutions) { + cfg.sortExecutions = sortExecutions; + return this; + } + + private FormatterStep createStep() { + return SortPomStep.create(cfg, provisioner()); + } + } +} diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java index f02ac28548..7fee3d950e 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java @@ -228,6 +228,12 @@ public void go(Action closure) { format(GoExtension.NAME, GoExtension.class, closure); } + /** Configures the special POM-specific extension. */ + public void pom(Action closure) { + requireNonNull(closure); + format(PomExtension.NAME, PomExtension.class, closure); + } + /** Configures a custom extension. */ public void format(String name, Action closure) { requireNonNull(name, "name"); diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/SortPomGradleTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/SortPomGradleTest.java new file mode 100644 index 0000000000..1c51d4c2a8 --- /dev/null +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/SortPomGradleTest.java @@ -0,0 +1,127 @@ +/* + * Copyright 2024 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.gradle.spotless; + +import org.junit.jupiter.api.Test; + +class SortPomGradleTest extends GradleIntegrationHarness { + @Test + void sortPom() throws Exception { + // given + setFile("build.gradle").toLines( + "plugins {", + " id 'com.diffplug.spotless'", + "}", + "repositories { mavenCentral() }", + "spotless {", + " pom {", + " sortPom()", + " }", + "}"); + setFile("pom.xml").toResource("pom/pom_dirty.xml"); + + // when + gradleRunner().withArguments("spotlessApply").build(); + + // then + assertFile("pom.xml").sameAsResource("pom/pom_clean_default.xml"); + } + + @Test + void sortPomWithTarget() throws Exception { + // given + setFile("build.gradle").toLines( + "plugins {", + " id 'com.diffplug.spotless'", + "}", + "repositories { mavenCentral() }", + "spotless {", + " pom {", + " target('test.xml')", + " sortPom()", + " }", + "}"); + setFile("test.xml").toResource("pom/pom_dirty.xml"); + + // when + gradleRunner().withArguments("spotlessApply").build(); + + // then + assertFile("test.xml").sameAsResource("pom/pom_clean_default.xml"); + } + + @Test + void sortPomWithVersion() throws Exception { + // given + setFile("build.gradle").toLines( + "plugins {", + " id 'com.diffplug.spotless'", + "}", + "repositories { mavenCentral() }", + "spotless {", + " pom {", + " sortPom '3.4.0'", + " }", + "}"); + setFile("pom.xml").toResource("pom/pom_dirty.xml"); + + // when + gradleRunner().withArguments("spotlessApply").build(); + + // then + assertFile("pom.xml").sameAsResource("pom/pom_clean_default.xml"); + } + + @Test + void sortPomWithParameters() throws Exception { + // given + setFile("build.gradle").toLines( + "plugins {", + " id 'com.diffplug.spotless'", + "}", + "repositories { mavenCentral() }", + "spotless {", + " pom {", + " sortPom()", + " .encoding('UTF-8')", + " .lineSeparator(System.getProperty('line.separator'))", + " .expandEmptyElements(true)", + " .spaceBeforeCloseEmptyElement(false)", + " .keepBlankLines(true)", + " .endWithNewline(true)", + " .nrOfIndentSpace(2)", + " .indentBlankLines(false)", + " .indentSchemaLocation(false)", + " .predefinedSortOrder('recommended_2008_06')", + " .sortOrderFile(null)", + " .sortDependencies(null)", + " .sortDependencyManagement(null)", + " .sortDependencyExclusions(null)", + " .sortPlugins(null)", + " .sortProperties(false)", + " .sortModules(false)", + " .sortExecutions(false)", + " }", + "}"); + setFile("pom.xml").toResource("pom/pom_dirty.xml"); + + // when + gradleRunner().withArguments("spotlessApply").build(); + + // then + assertFile("pom.xml").sameAsResource("pom/pom_clean_default.xml"); + } +} diff --git a/plugin-maven/README.md b/plugin-maven/README.md index 9a17cd2be7..85c364d3ff 100644 --- a/plugin-maven/README.md +++ b/plugin-maven/README.md @@ -665,7 +665,7 @@ All configuration settings are optional, they are described in detail [here](htt false - false + false recommended_2008_06 @@ -673,6 +673,8 @@ All configuration settings are optional, they are described in detail [here](htt + + From 5ca30971cc941564e99896e73535314fabe5123b Mon Sep 17 00:00:00 2001 From: Mark Chesney Date: Mon, 1 Apr 2024 23:22:20 -0700 Subject: [PATCH 2/4] Fix formatting --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 00864c559a..9f295f96cb 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ lib('markdown.FlexmarkStep') +'{{yes}} | {{yes}} lib('npm.EslintFormatterStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |', lib('npm.PrettierFormatterStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |', lib('npm.TsFmtFormatterStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |', -lib('pom.SortPomStepStep') +'{{no}} | {{yes}} | {{no}} | {{no}} |', +lib('pom.SortPomStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |', lib('protobuf.BufStep') +'{{yes}} | {{no}} | {{no}} | {{no}} |', lib('python.BlackStep') +'{{yes}} | {{no}} | {{no}} | {{no}} |', lib('scala.ScalaFmtStep') +'{{yes}} | {{yes}} | {{yes}} | {{no}} |', @@ -154,7 +154,7 @@ lib('yaml.JacksonYamlStep') +'{{yes}} | {{yes}} | [`npm.EslintFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/EslintFormatterStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: | | [`npm.PrettierFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/PrettierFormatterStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: | | [`npm.TsFmtFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/TsFmtFormatterStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: | -| [`pom.SortPomStep`](lib/src/main/java/com/diffplug/spotless/pom/SortPomStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: | +| [`pom.SortPomStep`](lib/src/main/java/com/diffplug/spotless/pom/SortPomStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: | | [`protobuf.BufStep`](lib/src/main/java/com/diffplug/spotless/protobuf/BufStep.java) | :+1: | :white_large_square: | :white_large_square: | :white_large_square: | | [`python.BlackStep`](lib/src/main/java/com/diffplug/spotless/python/BlackStep.java) | :+1: | :white_large_square: | :white_large_square: | :white_large_square: | | [`scala.ScalaFmtStep`](lib/src/main/java/com/diffplug/spotless/scala/ScalaFmtStep.java) | :+1: | :+1: | :+1: | :white_large_square: | From ec7f49fceadce73e35ae0325b200a43d35b0ce35 Mon Sep 17 00:00:00 2001 From: Mark Chesney Date: Tue, 2 Apr 2024 05:56:50 -0700 Subject: [PATCH 3/4] Reduce visibility Co-authored-by: Zongle Wang --- .../main/java/com/diffplug/gradle/spotless/PomExtension.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/PomExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/PomExtension.java index a7f3b0389c..463463d320 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/PomExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/PomExtension.java @@ -51,7 +51,7 @@ public SortPomGradleConfig sortPom(String version) { } public class SortPomGradleConfig { - final SortPomCfg cfg = new SortPomCfg(); + private final SortPomCfg cfg = new SortPomCfg(); SortPomGradleConfig() { addStep(createStep()); From d0f6592dafc3cda1f11de4fe2bcb2d13d4e30188 Mon Sep 17 00:00:00 2001 From: Mark Chesney Date: Tue, 2 Apr 2024 05:57:18 -0700 Subject: [PATCH 4/4] Update changelog Co-authored-by: Zongle Wang --- plugin-gradle/CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin-gradle/CHANGES.md b/plugin-gradle/CHANGES.md index e58fd5cfb6..9629118b0b 100644 --- a/plugin-gradle/CHANGES.md +++ b/plugin-gradle/CHANGES.md @@ -11,7 +11,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( * Bump default `shfmt` version to latest `3.7.0` -> `3.8.0`. ([#2050](https://github.com/diffplug/spotless/pull/2050)) ### Added * Respect `.editorconfig` settings for formatting shell via `shfmt` ([#2031](https://github.com/diffplug/spotless/pull/2031)) -* Add support for formatting and sorting Maven POMs ([#2081](https://github.com/diffplug/spotless/issues/2081)) +* Add support for formatting and sorting Maven POMs ([#2082](https://github.com/diffplug/spotless/issues/2082)) ## [6.25.0] - 2024-01-23 ### Added