# Technical Documentation: diffplug/spotless

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/diffplug/spotless)

### Overview (`README.md`)

# <img align="left" src="_images/spotless_logo.png"> Spotless: Keep your code spotless

[](plugin-gradle)
[](plugin-maven)
[](https://github.com/moznion/sbt-spotless)

Spotless can format &lt;antlr | c | c# | c++ | css | flow | graphql | groovy | html | java | javascript | json | jsx | kotlin | less | license headers | markdown | objective-c | protobuf | python | scala | scss | shell | sql | typeScript | vue | yaml | anything> using &lt;gradle | maven | sbt | anything>.

You probably want one of the links below:

## [❇️ Spotless for Gradle](plugin-gradle) (with integrations for [VS Code](https://marketplace.visualstudio.com/items?itemName=richardwillis.vscode-spotless-gradle) and IntelliJ with [Spotless Daemon](https://plugins.jetbrains.com/plugin/29287-spotless-daemon) or [Spotless Gradle](https://plugins.jetbrains.com/plugin/18321-spotless-gradle))

```console
user@machine repo % ./gradlew build
:spotlessJavaCheck FAILED
  The following files had format violations:
  src\main\java\com\diffplug\gradle\spotless\FormatExtension.java
    -\t\t····if·(targets.length·==·0)·{
    +\t\tif·(targets.length·==·0)·{
  Run './gradlew spotlessApply' to fix these violations.
user@machine repo % ./gradlew spotlessApply
:spotlessApply
BUILD SUCCESSFUL
user@machine repo % ./gradlew build
BUILD SUCCESSFUL
```

## [❇️ Spotless for Maven](plugin-maven)

```console
user@machine repo % mvn spotless:check
[ERROR]  > The following files had format violations:
[ERROR]  src\main\java\com\diffplug\gradle\spotless\FormatExtension.java
[ERROR]    -\t\t····if·(targets.length·==·0)·{
[ERROR]    +\t\tif·(targets.length·==·0)·{
[ERROR]  Run 'mvn spotless:apply' to fix these violations.
user@machine repo % mvn spotless:apply
[INFO] BUILD SUCCESS
user@machine repo % mvn spotless:check
[INFO] BUILD SUCCESS
```

## [❇️ Spotless for SBT (external for now)](https://github.com/moznion/sbt-spotless)
## [Other build systems](CONTRIBUTING.md#how-to-add-a-new-plugin-for-a-build-system)

## How it works (for potential contributors)

Ideally, a code formatter can do more than just find formatting errors - it should fix them as well. Such a formatter is just a `Function<String, String>`, which returns a formatted version of its potentially unformatted input.

It's easy to build such a function, but there are some gotchas and lots of integration work ([newlines](https://github.com/diffplug/spotless/tree/main/plugin-gradle#line-endings-and-encodings-invisible-stuff), character [encodings](https://github.com/diffplug/spotless/blob/08340a11566cdf56ecf50dbd4d557ed84a70a502/testlib/src/test/java/com/diffplug/spotless/EncodingErrorMsgTest.java#L34-L38), [idempotency](https://github.com/diffplug/spotless/blob/main/PADDEDCELL.md), git [ratcheting](https://github.com/diffplug/spotless/tree/main/plugin-gradle#ratchet), and build-system integration). Spotless tackles those for you **so you can focus on just a simple `Function<String, String>` which can compose with any of the other formatters and build tools in Spotless' arsenal**.

## Current feature matrix


| Feature / FormatterStep                       | [gradle](plugin-gradle/README.md) | [maven](plugin-maven/README.md) | [sbt](https://github.com/moznion/sbt-spotless) | [(Your build tool here)](CONTRIBUTING.md#how-to-add-a-new-plugin-for-a-build-system) |
| --------------------------------------------- | ------------- | ------------ | ------------ | --------|
| Automatic [idempotency safeguard](PADDEDCELL.md) | :+1:    | :+1:      | :+1:      | :white_large_square:  |
| Misconfigured [encoding safeguard](https://github.com/diffplug/spotless/blob/08340a11566cdf56ecf50dbd4d557ed84a70a502/testlib/src/test/java/com/diffplug/spotless/EncodingErrorMsgTest.java#L34-L38) | :+1:    | :+1:      | :+1:       | :white_large_square:  |
| Toggle with [`spotless:off` and `spotless:on`](plugin-gradle/#spotlessoff-and-spotlesson) | :+1:    | :+1:      | :white_large_square:       | :white_large_square:  |
| [Ratchet from](https://github.com/diffplug/spotless/tree/main/plugin-gradle#ratchet) `origin/main` or other git ref | :+1:    | :+1:      | :white_large_square:       | :white_large_square:  |
| Define [line endings using git](https://github.com/diffplug/spotless/tree/main/plugin-gradle#line-endings-and-encodings-invisible-stuff) | :+1:    | :+1:      | :+1:       | :white_large_square:  |
| Fast incremental format and up-to-date check   | :+1:      | :+1:      | :white_large_square:       | :white_large_square:  |
| Fast format on fresh checkout using buildcache | :+1:      | :white_large_square:       | :white_large_square:       | :white_large_square:  |
| [`generic.EndWithNewlineStep`](lib/src/main/java/com/diffplug/spotless/generic/EndWithNewlineStep.java) | :+1:       | :+1:      | :white_large_square:       | :white_large_square:  |
| [`generic.IndentStep`](lib/src/main/java/com/diffplug/spotless/generic/IndentStep.java) | :+1:       | :+1:      | :white_large_square:       | :white_large_square:  |
| [`generic.Jsr223Step`](lib/src/main/java/com/diffplug/spotless/generic/Jsr223Step.java) | :white_large_square:        | :+1:      | :white_large_square:       | :white_large_square:  |
| [`generic.LicenseHeaderStep`](lib/src/main/java/com/diffplug/spotless/generic/LicenseHeaderStep.java) | :+1:       | :+1:      | :+1:      | :white_large_square:  |
| [`generic.NativeCmdStep`](lib/src/main/java/com/diffplug/spotless/generic/NativeCmdStep.java) | :+1:       | :+1:      | :white_large_square:       | :white_large_square:  |
| [`generic.ReplaceRegexStep`](lib/src/main/java/com/diffplug/spotless/generic/ReplaceRegexStep.java) | :+1:       | :+1:      | :white_large_square:       | :white_large_square:  |
| [`generic.ReplaceStep`](lib/src/main/java/com/diffplug/spotless/generic/ReplaceStep.java) | :+1:       | :+1:      | :white_large_square:       | :white_large_square:  |
| [`generic.TrimTrailingWhitespaceStep`](lib/src/main/java/com/diffplug/spotless/generic/TrimTrailingWhitespaceStep.java) | :+1:       | :+1:      | :white_large_square:       | :white_large_square:  |
| [`antlr4.Antlr4FormatterStep`](lib/src/main/java/com/diffplug/spotless/antlr4/Antlr4FormatterStep.java) | :+1:       | :+1:      | :white_large_square:       | :white_large_square:  |
| [`biome.BiomeStep`](lib/src/main/java/com/diffplug/spotless/biome/BiomeStep.java) | :+1:       | :+1:      | :white_large_square:       | :white_large_square:  |
| [`cpp.ClangFormatStep`](lib/src/main/java/com/diffplug/spotless/cpp/ClangFormatStep.java) | :+1:       | :white_large_square:       | :white_large_square:       | :white_large_square:  |
| [`cpp.EclipseFormatterStep`](lib-extra/src/main/java/com/diffplug/spotless/extra/cpp/EclipseFormatterStep.java) | :+1:       | :+1:      | :+1:      | :white_large_square:  |
| [`go.GofmtFormatStep`](lib/src/main/java/com/diffplug/spotless/go/GofmtFormatStep.java) | :+1:       | :white_large_square:       | :white_large_square:       | :white_large_square:  |
| [`gherkin.GherkinUtilsStep`](lib/src/main/java/com/diffplug/spotless/gherkin/GherkinUtilsStep.java) | :+1:       | :+1:      | :white_large_square:       | :white_large_square:  |
| [`groovy.GrEclipseFormatterStep`](lib-extra/src/main/java/com/diffplug/spotless/extra/groovy/GrEclipseFormatterStep.java) | :+1:       | :+1:      | :+1:      | :white_large_square:  |
| [`java.GoogleJavaFormatStep`](lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java) | :+1:       | :+1:      | :+1:      | :white_large_square:  |
| [`java.ImportOrderStep`](lib/src/main/java/com/diffplug/spotless/java/ImportOrderStep.java) | :+1:       | :+1:      | :+1:      | :white_large_square:  |
| [`java.PalantirJavaFormatStep`](lib/src/main/java/com/diffplug/spotless/java/PalantirJavaFormatStep.java) | :+1:       | :+1:      | :white_large_square:       | :white_large_square:  |
| [`java.PrinceOfSpaceStep`](lib/src/main/java/com/diffplug/spotless/java/PrinceOfSpaceStep.java) | :+1:       | :+1:      | :white_large_square:       | :white_large_square:  |
| [`java.RemoveUnusedImportsStep`](lib/src/main/java/com/diffplug/spotless/java/RemoveUnusedImportsStep.java) | :+1:       | :+1:      | :+1:      | :white_large_square:  |
| [`java.ExpandWildcardImportsStep`](lib/src/main/java/com/diffplug/spotless/java/ExpandWildcardImportsStep.java) | :+1:       | :white_large_square:       | :white_large_square:       | :white_large_square:  |
| [`java.ForbidWildcardImportsStep`](lib/src/main/java/com/diffplug/spotless/java/ForbidWildcardImportsStep.java) | :+1:       | :+1:      | :+1:      | :white_large_square:  |
| [`java.ForbidModuleImportsStep`](lib/src/main/java/com/diffplug/spotless/java/ForbidModuleImportsStep.java) | :+1:       | :+1:      | :white_large_square:       | :white_large_square:  |
| [`java.ShortenFullyQualifiedTypesStep`](lib/src/main/java/com/diffplug/spotless/java/ShortenFullyQualifiedTypesStep.java) | :+1:       | :+1:      | :white_large_square:       | :white_large_square:  |
| [`java.EclipseJdtFormatterStep`](lib-extra/src/main/java/com/diffplug/spotless/extra/java/EclipseJdtFormatterStep.java) | :+1:       | :+1:      | :+1:      | :white_large_square:  |
| [`java.FormatAnnotationsStep`](lib/src/main/java/com/diffplug/spotless/java/FormatAnnotationsStep.java) | :+1:       | :+1:      | :white_large_square:       | :white_large_square:  |
| [`java.CleanthatJavaStep`](lib/src/main/java/com/diffplug/spotless/java/CleanthatJavaStep.java) | :+1:       | :+1:      | :white_large_square:       | :white_large_square:  |
| [`java.TableTestFormatterStep`](lib/src/main/java/com/diffplug/spotless/java/TableTestFormatterStep.java) | :+1:       | :+1:      | :white_large_square:       | :white_large_square:  |
| [`json.gson.GsonStep`](lib/src/main/java/com/diffplug/spotless/json/gson/GsonStep.java) | :+1:       | :+1:      | :white_large_square:       | :white_large_square:  |
| [`json.JacksonJsonStep`](lib/src/main/java/com/diffplug/spotless/json/JacksonJsonStep.java) | :+1:       | :+1:      | :white_large_square:       | :white_large_square:  |
| [`json.JsonSimpleStep`](lib/src/main/java/com/diffplug/spotless/json/JsonSimpleStep.java) | :+1:       | :+1:      | :white_large_square:       | :white_large_square:  |
| [`json.JsonPatchStep`](lib/src/main/java/com/diffplug/spotless/json/JsonPatchStep.java) | :+1:       | :+1:      | :white_large_square:       | :white_large_square:  |
| [`kotlin.KtLintStep`](lib/src/main/java/com/diffplug/spotless/kotlin/KtLintStep.java) | :+1:       | :+1:      | :+1:      | :white_large_square:  |
| [`kotlin.KtfmtStep`](lib/src/main/java/com/diffplug/spotless/kotlin/KtfmtStep.java) | :+1:       | :+1:      | :white_large_square:       | :white_large_square:  |
| [`kotlin.DiktatStep`](lib/src/main/java/com/diffplug/spotless/kotlin/DiktatStep.java) | :+1:       | :+1:      | :white_large_square:       | :white_large_square:  |
| [`markdown.FreshMarkStep`](lib/src/main/java/com/diffplug/spotless/markdown/FreshMarkStep.java) | :+1:       | :white_large_square:       | :white_large_square:       | :white_large_square:  |
| [`markdown.FlexmarkStep`](lib/src/main/java/com/diffplug/spotless/markdown/FlexmarkStep.java) | :+1:       | :+1:      | :white_large_square:       | :white_large_square:  |
| [`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:  |
| [`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:  |
| [`rdf.RdfFormatterStep`](lib/src/main/java/com/diffplug/spotless/rdf/RdfFormatterStep.java) | :white_large_square:        | :+1:      | :white_large_square:       | :white_large_square:  |
| [`scala.ScalaFmtStep`](lib/src/main/java/com/diffplug/spotless/scala/ScalaFmtStep.java) | :+1:       | :+1:      | :+1:      | :white_large_square:  |
| [`shell.ShfmtStep`](lib/src/main/java/com/diffplug/spotless/shell/ShfmtStep.java) | :+1:       | :+1:      | :white_large_square:       | :white_large_square:  |
| [`sql.DBeaverSQLFormatterStep`](lib/src/main/java/com/diffplug/spotless/sql/DBeaverSQLFormatterStep.java) | :+1:       | :+1:      | :+1:      | :white_large_square:  |
| [`wtp.EclipseWtpFormatterStep`](lib-extra/src/main/java/com/diffplug/spotless/extra/wtp/EclipseWtpFormatterStep.java) | :+1:       | :+1:      | :white_large_square:       | :white_large_square:  |
| [`yaml.JacksonYamlStep`](lib/src/main/java/com/diffplug/spotless/yaml/JacksonYamlStep.java) | :+1:       | :+1:      | :white_large_square:       | :white_large_square:  |
| [(Your FormatterStep here)](CONTRIBUTING.md#how-to-add-a-new-formatterstep) | :white_large_square: | :white_large_square: | :white_large_square: | :white_large_square: |


### Why are there empty squares?

Many projects get harder to work on as they get bigger. Spotless is easier to work on than ever, and one of the reasons why is that we don't require contributors to "fill the matrix". If you want to [add Bazel support](https://github.com/diffplug/spotless/issues/76), we'd happily accept the PR even if it only supports the one formatter you use. And if you want to add FooFormatter support, we'll happily accept the PR even if it only supports the one build system you use.

Once someone has filled in one square of the formatter/build system matrix, it's easy for interested parties to fill in any empty squares, since you'll now have a working example for every piece needed.

## Acknowledgements

- Thanks to [over 200 contributors with merged PRs](https://github.com/diffplug/spotless/graphs/contributors), and also to everyone who helped with code review, file reproducible bugs, etc. A few contributions stand out as especially significant to the history of the project, though regrettably there are certain to be some important omissions!
- Thanks to [Zongle Wang](https://github.com/Goooler) for an [enormous mound of contributions](https://github.com/diffplug/spotless/issues?q=is%3Apr%20is%3Aclosed%20author%3AGoooler), but especially for [his near-rewrite](https://github.com/diffplug/spotless/issues/1274#issuecomment-2146972303) so that Spotless could support Gradle's configuration cache natively.
- Thanks to [Simon Gamma](https://github.com/simschla) for [adding support for npm-based formatters](https://github.com/diffplug/spotless/pull/283), [twice](https://github.com/diffplug/spotless/pull/606) including `prettier` and `tsfmt`.
- Thanks to [Konstantin Lutovich](https://github.com/lutovich) for [implementing and maintaining the Maven plugin](https://github.com/diffplug/spotless/pull/188), as well as fixing [remote-build cache support for Gradle](https://github.com/diffplug/spotless/pull/571).
- Thanks to [Frank Vennemeyer](https://github.com/fvgh) for [Groovy support via greclipse](https://github.com/diffplug/spotless/issues/13), [C++ support via CDT](https://github.com/diffplug/spotless/issues/232), [XML support via WTP](https://github.com/diffplug/spotless/pull/241) and a huge body of work with other eclipse-based formatters.
- Thanks to [Jonathan Bluett-Duncan](https://github.com/jbduncan) for
  - implementing up-to-date checking [#31](https://github.com/diffplug/spotless/issues/31)
  - breaking spotless into libraries [#56](https://github.com/diffplug/spotless/issues/56)
  - lots of other things, but especially the diff support in `spotlessCheck`
  - constant improvements on a variety of topics with high-quality code reviews
- Thanks to [Daz DeBoer](https://github.com/bigdaz) for the reworking the guts of our Gradle plugin to support [buildcache](https://github.com/diffplug/spotless/pull/576), [InputChanges](https://github.com/diffplug/spotless/pull/607), and [lazy configuration](https://github.com/diffplug/spotless/pull/617).
- Thanks to [Richard Willis](https://github.com/badsyntax) for creating the [VS Code extension for Spotless Gradle](https://marketplace.visualstudio.com/items?itemName=richardwillis.vscode-spotless-gradle).
- Thanks to [Ryan Gurney](https://github.com/ragurney) for creating the [IntelliJ plugin for Spotless Gradle](https://plugins.jetbrains.com/plugin/18321-spotless-gradle).
- Thanks to [Alex Danylenko](https://github.com/lazer-dev) for creating the [git pre-push hook](https://github.com/diffplug/spotless/pull/2553).
- Thanks to [Markus Heberling](https://github.com/tisoft) for adding [generic native formatters](https://github.com/diffplug/spotless/pull/949), [jsr-223 formatters](https://github.com/diffplug/spotless/pull/945), and [maven pom sorting](https://github.com/diffplug/spotless/pull/946).
- Thanks to [Matthias Balke](https://github.com/matthiasbalke) for [adding support for Antlr](https://github.com/diffplug/spotless/pull/328).
- Thanks to [Matthias Andreas Benkard](https://github.com/benkard) for adding support for google-java-format 1.8+ ([#563](https://github.com/diffplug/spotless/pull/563))
- Thanks to [Thomas Broyer](https://github.com/tbroyer) for adding support for google-java-format's [skip-reflowing-long-strings option](https://github.com/diffplug/spotless/pull/929).
- Thanks to [Hakanai](https://github.com/hakanai) for adding [wildcards last support to the import sorter](https://github.com/diffplug/spotless/pull/956).
- Thanks to [Kevin Brooks](https://github.com/k-brooks) for [updating all eclipse-based formatters to 4.13](https://github.com/diffplug/spotless/pull/482) and [fixing Groovy for multiproject](https://github.com/diffplug/spotless/issues/877).
- Thanks to [Dylan Baroody](https://github.com/dylanbaroody) for fixing [sql formatting support for JDBI bind list params](https://github.com/diffplug/spotless/pull/955).
- Thanks to [figroc](https://github.com/figroc) for adding [custom mavenCoordinate support to google-java-format](https://github.com/diffplug/spotless/pull/944#issuecomment-927565149).
- Thanks to [Thomas Glaeser](https://github.com/tglaeser) for [finding](https://github.com/diffplug/spotless/issues/654) and [fixing](https://github.com/diffplug/spotless/pull/656) a file-permissions-clobbering bug.
- Thanks to [Joan Goyeau](https://github.com/joan38) for [fixing scalafmt integration](https://github.com/diffplug/spotless/pull/260).
- Thanks to [Nick Sutcliffe](https://github.com/nsutcliffe) for [fixing scalafmt post-2.0](https://github.com/diffplug/spotless/pull/416).
- Thanks to [Baptiste Mesta](https://github.com/baptistemesta) for
  - porting the DBeaver formatter to Spotless, and thanks to [DBeaver](https://dbeaver.jkiss.org/) and [its authors](https://github.com/serge-rider/dbeaver/graphs/contributors) for their excellent SQL formatter.
  - making license headers date-aware [#179](https://github.com/diffplug/spotless/pull/179)
- Thanks to [vmdominguez](https://github.com/vmdominguez) and [Luis Fors](https://github.com/luis-fors-cb) for adding the ability to limit formatting to specific files in Gradle ([#322](https://github.com/diffplug/spotless/pull/322)) and Maven ([#392](https://github.com/diffplug/spotless/pull/392)), respectively.
- Thanks to [bender316](https://github.com/bender316) for fixing classloading on Java 9 ([#426](https://github.com/diffplug/spotless/pull/426)).
- Thanks to [Stefan Oehme](https://github.com/oehme) for tons of help on the internal mechanics of Gradle.
- Thanks to [eyalkaspi](https://github.com/eyalkaspi) for adding configurable date ranges to the date-aware license headers.
- Thanks to [Andrew Parmet](https://github.com/andrewparmet) for adding [ktfmt support for kotlin gradle](https://github.com/diffplug/spotless/pull/583).
- Thanks to [Oliver Horn](https://github.com/ohorn) for adding AOSP support for Spotless' google-java-format integration.
- Formatting by Eclipse
  - Special thanks to [Mateusz Matela](https://waynebeaton.wordpress.com/2015/03/15/great-fixes-for-mars-winners-part-i/) for huge improvements to the eclipse code formatter!
- Thanks to [Zac Sweers](https://github.com/ZacSweers) for fixing the highly requested ktlint 0.34+ support ([#469](https://github.com/diffplug/spotless/pull/469)), multiple build updates and fixing a Gradle deprecation warning ([#434](https://github.com/diffplug/spotless/pull/434) and others).
- Thanks to [Stephen Panaro](https://github.com/smpanaro) for adding support for ktlint FilenameRule ([#974](https://github.com/diffplug/spotless/pull/974)).
- Thanks to [Nelson Osacky](https://github.com/runningcode) for android doc improvements, versions bump, and a build improvement.
- Thanks to [Stanley Shyiko](https://github.com/shyiko) for his help integrating [ktlint](https://github.com/shyiko/ktlint).
- Thanks to [Jonathan Leitschuh](https://github.com/JLLeitschuh) for adding [ktlint](https://github.com/shyiko/ktlint) support for [Gradle Kotlin DSL](https://github.com/gradle/kotlin-dsl) files.
- Originally forked from [gradle-format-plugin](https://github.com/youribonnaffe/gradle-format-plugin) by Youri Bonnaffé.
- Thanks to Ismaël Mejía for bumping eclipse-jdt deps to 4.11. [PR #60](https://github.com/diffplug/spotless/issues/381).
- Thanks to Gábor Bernát for improvements to logging and multi-project support.
- Thanks to [Oliver Szymanski](https://github.com/source-knights) for porting [tsfmt](https://github.com/diffplug/spotless/pull/553) and [prettier](https://github.com/diffplug/spotless/pull/555) to maven.
- Thanks to Andrew Oberstar for improvements to formatting java source in non-java source sets. [PR #60](https://github.com/diffplug/spotless/pull/60).
- Thanks to [Sameer Balasubrahmanyam](https://github.com/sameer-b) for [adding support for IntelliJ-style year placeholders](https://github.com/diffplug/spotless/pull/542).
- Thanks to [Jamie Tanna](https://github.com/jamietanna) for [adding a simple JSON formatter](https://github.com/diffplug/spotless/pull/853).
- Thanks to [Adib Saikali](https://github.com/asaikali) and [Paul Merlin](https://github.com/eskatos) for tracking down the tricky cause of [#506](https://github.com/diffplug/spotless/issues/506).
- Import ordering from [EclipseCodeFormatter](https://github.com/krasa/EclipseCodeFormatter).
- Built by [gradle](https://gradle.org/).
- Tested by [junit](https://junit.org/).
- Maintained by [DiffPlug](https://www.diffplug.com/).

---

### Overview (`plugin-gradle/README.md`)

# <img align="left" src="../_images/spotless_logo.png"> Spotless plugin for Gradle
*Keep your code Spotless with Gradle*


[](https://plugins.gradle.org/plugin/com.diffplug.spotless)
[](CHANGES.md)
[](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.diffplug.spotless%22%20AND%20a%3A%22spotless-plugin-gradle%22)
[](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/index.html)

[](https://marketplace.visualstudio.com/items?itemName=richardwillis.vscode-spotless-gradle)
[](https://plugins.jetbrains.com/plugin/18321-spotless-gradle)
[](https://plugins.jetbrains.com/plugin/29287-spotless-daemon)
[](IDE_HOOK.md)


Two IntelliJ plugins are available, with different trade-offs:

**[Spotless Daemon](https://plugins.jetbrains.com/plugin/29287-spotless-daemon)**

|    |                                                                                                          |
|:---|:---------------------------------------------------------------------------------------------------------|
| ✅ | Fast response — the Gradle daemon stays resident, so each format skips Gradle's startup and task execution |
| ✅ | Replaces the IDE's built-in formatter, so the formatting UX is identical to native reformat |
| ✅ | Includes targeted optimizations, e.g. import optimization is preprocessed on the IDE side |
| ❌ | The resident daemon holds some resources while running |
| ❌ | Implementation depends on some internal Gradle plugin structures rather than public integration APIs |

**[Spotless Gradle](https://plugins.jetbrains.com/plugin/18321-spotless-gradle)**

|    |                                                                                                          |
|:---|:---------------------------------------------------------------------------------------------------------|
| ✅ | Stable and battle-tested over years of use |
| ✅ | Works through the standard `spotlessApply` Gradle task integration |
| ❌ | Slow cold start — every invocation pays Gradle's startup cost |
| ❌ | Runs as a separate action, disconnected from the IDE's built-in format UX |



Spotless is a general-purpose formatting plugin used by [15,000 projects on GitHub (Jan 2023)](https://github.com/search?l=gradle&q=spotless&type=Code).  It is completely à la carte, but also includes powerful "batteries-included" if you opt-in.

To people who use your build, it looks like this ([IDE support also available](IDE_HOOK.md)):

```console
user@machine repo % ./gradlew build
:spotlessJavaCheck FAILED
  The following files had format violations:
  src\main\java\com\diffplug\gradle\spotless\FormatExtension.java
    -\t\t····if·(targets.length·==·0)·{
    +\t\tif·(targets.length·==·0)·{
  Run './gradlew spotlessApply' to fix these violations.
user@machine repo % ./gradlew spotlessApply
:spotlessApply
BUILD SUCCESSFUL
user@machine repo % ./gradlew build
BUILD SUCCESSFUL
```

Spotless supports all of Gradle's built-in performance features (incremental build, remote and local buildcache, lazy configuration, etc), and also automatically fixes [idempotence issues](https://github.com/diffplug/spotless/blob/main/PADDEDCELL.md), infers [line-endings from git](#line-endings-and-encodings-invisible-stuff), is cautious about [misconfigured encoding](https://github.com/diffplug/spotless/blob/08340a11566cdf56ecf50dbd4d557ed84a70a502/testlib/src/test/java/com/diffplug/spotless/EncodingErrorMsgTest.java#L34-L38) bugs, and can use git to [ratchet formatting](#ratchet) without "format-everything" commits.


### Table of Contents

- [**Quickstart**](#quickstart)
  - [Requirements](#requirements)
  - [Git hook (optional)](#git-hook)
  - [Linting](#linting)
- **Languages**
  - [Java](#java) ([removeUnusedImports](#removeunusedimports), [forbidWildcardImports](#forbidwildcardimports), [expandWildcardImports](#expandwildcardimports), [forbidModuleImports](#forbidmoduleimports), [shortenFullyQualifiedTypes](#shortenfullyqualifiedtypes), [google-java-format](#google-java-format), [eclipse jdt](#eclipse-jdt), [clang-format](#clang-format), [prettier](#prettier), [palantir-java-format](#palantir-java-format), [prince-of-space](#prince-of-space), [formatAnnotations](#formatAnnotations), [cleanthat](#cleanthat), [tabletest-formatter](#tabletest-formatter), [IntelliJ IDEA](#intellij-idea))
  - [Groovy](#groovy) ([eclipse groovy](#eclipse-groovy))
  - [Kotlin](#kotlin) ([ktfmt](#ktfmt), [ktlint](#ktlint), [diktat](#diktat), [tabletest-formatter](#tabletest-formatter-1), [prettier](#prettier))
  - [Scala](#scala) ([scalafmt](#scalafmt))
  - [Asciidoc](#asciidoc) ([adocfmt](#adocfmt))
  - [C/C++](#cc) ([clang-format](#clang-format), [eclipse cdt](#eclipse-cdt))
  - [Protobuf](#protobuf) ([buf](#buf), [clang-format](#clang-format))
  - [Python](#python) ([black](#black))
  - [FreshMark](#freshmark) aka markdown
  - [Flexmark](#flexmark) aka markdown
  - [Antlr4](#antlr4) ([antlr4formatter](#antlr4formatter))
  - [SQL](#sql) ([dbeaver](#dbeaver), [prettier](#prettier), [IntelliJ IDEA](#intellij-idea))
  - [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))
  - [YAML](#yaml)
  - [Shell](#shell)
  - [Gherkin](#gherkin)
  - Multiple languages
    - [Prettier](#prettier) ([plugins](#prettier-plugins), [npm detection](#npm-detection), [`.npmrc` detection](#npmrc-detection), [caching `npm install` results](#caching-results-of-npm-install))
    - [clang-format](#clang-format)
    - [eclipse web tools platform](#eclipse-web-tools-platform)
    - [Biome](#biome) ([binary detection](#biome-binary), [config file](#biome-configuration-file), [input language](#biome-input-language))
    - [IntelliJ IDEA](#intellij-idea)
- **Language independent**
  - [Generic steps](#generic-steps)
  - [License header](#license-header) ([slurp year from git](#retroactively-slurp-years-from-git-history))
  - [How can I enforce formatting gradually? (aka "ratchet")](#ratchet)
  - [`spotless:off` and `spotless:on`](#spotlessoff-and-spotlesson)
  - [Line endings and encodings (invisible stuff)](#line-endings-and-encodings-invisible-stuff)
  - [Custom steps](#custom-steps)
  - [Multiple (or custom) language-specific blocks](#multiple-or-custom-language-specific-blocks)
  - [Inception (languages within languages within...)](#inception-languages-within-languages-within)
  - [Disabling warnings and error messages](#disabling-warnings-and-error-messages)
  - [Dependency resolution modes](#dependency-resolution-modes)
  - [How do I preview what `spotlessApply` will do?](#how-do-i-preview-what-spotlessapply-will-do)
  - [Can I apply Spotless to specific files?](#can-i-apply-spotless-to-specific-files)
  - [How to centralize Spotless configuration](#central-configuration)
  - [Example configurations (from real-world projects)](#example-configurations-from-real-world-projects)

***Contributions are welcome, see [the contributing guide](../CONTRIBUTING.md) for development info.***

## Quickstart

To use it in your buildscript, just [add the Spotless dependency](https://plugins.gradle.org/plugin/com.diffplug.spotless), and configure it like so:

```gradle
spotless {
  // optional: limit format enforcement to just the files changed by this feature branch
  ratchetFrom 'origin/main'

  format 'misc', {
    // define the files to apply `misc` to
    target '*.gradle', '.gitattributes', '.gitignore'

    // define the steps to apply to those files
    trimTrailingWhitespace()
    leadingSpacesToTabs() // or leadingTabsToSpaces. Takes an integer argument if you don't like 4
    endWithNewline()
  }
  java {
    // don't need to set target, it is inferred from java

    // apply a specific flavor of google-java-format
    googleJavaFormat('1.8').aosp().reflowLongStrings().skipJavadocFormatting()
    // fix formatting of type annotations
    formatAnnotations()
    // make sure every file has the following copyright header.
    // optionally, Spotless can set copyright years by digging
    // through git history (see "license" section below)
    licenseHeader '/* (C)$YEAR */'
  }
}
```

Spotless consists of a list of formats (in the example above, `misc` and `java`), and each format has:
- a `target` (the files to format), which you set with [`target`](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/FormatExtension.html#target-java.lang.Object...-) and [`targetExclude`](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/FormatExtension.html#targetExclude-java.lang.Object...-)
- a list of `FormatterStep`, which are just `String -> String` functions, such as [`replace`](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/FormatExtension.html#replace-java.lang.String-java.lang.CharSequence-java.lang.CharSequence-), [`replaceRegex`](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/FormatExtension.html#replaceRegex-java.lang.String-java.lang.String-java.lang.String-), [`trimTrailingWhitespace`](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/FormatExtension.html#replace-java.lang.String-java.lang.CharSequence-java.lang.CharSequence-), [`custom`](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/FormatExtension.html#custom-java.lang.String-groovy.lang.Closure-), [`prettier`](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/FormatExtension.html#prettier--), [`eclipseWtp`](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/FormatExtension.html#eclipseWtp-com.diffplug.spotless.extra.wtp.EclipseWtpFormatterStep-), [`licenseHeader`](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/FormatExtension.html#licenseHeader-java.lang.String-java.lang.String-) etc.

All the generic steps live in [`FormatExtension`](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/FormatExtension.html), and there are many language-specific steps which live in its language-specific subclasses, which are described below.

### Requirements

Spotless requires JRE 17+ and Gradle 7.3 or newer.

- If you're stuck on JRE 11, use [`id 'com.diffplug.spotless' version '7.2.1'` or older](https://github.com/diffplug/spotless/blob/main/plugin-gradle/CHANGES.md#721---2025-07-21).
- If you're stuck on JRE 8, use [`id 'com.diffplug.spotless' version '6.13.0'` or older](https://github.com/diffplug/spotless/blob/main/plugin-gradle/CHANGES.md#6130---2023-01-14).
- If you're stuck on a very old version of Gradle, [`id 'com.diffplug.gradle.spotless' version '4.5.1'` supports all the way back to Gradle 2.x](https://github.com/diffplug/spotless/blob/main/plugin-gradle/CHANGES.md#451---2020-07-04).

### Git hook

If you want, you can run `./gradlew spotlessInstallGitPrePushHook` and it will install a hook such that

1. When you push, it runs `spotlessCheck`
2. If formatting issues are found:
   - It automatically runs `spotlessApply` to fix them
   - Aborts the push with a message
   - You can then commit the changes and push again

This ensures your code is always clean before it leaves your machine.

If you prefer instead to have a "pre-commit" hook so that every single commit is clean, see [#623](https://github.com/diffplug/spotless/issues/623) for a workaround or to contribute a permanent fix.

### Linting

Starting in version `7.0.0`, Spotless now supports linting in addition to formatting. To Spotless, all lints are errors which must be either fixed or suppressed. Lints show up like this:

```console
user@machine repo % ./gradlew build
:spotlessKotlinCheck FAILED
  There were 2 lint error(s), they must be fixed or suppressed.
    src/main/kotlin/com/diffplug/Foo.kt:L7 ktlint(standard:no-wildcard-imports) Wildcard import
    src/main/kotlin/com/diffplug/Bar.kt:L9 ktlint(standard:no-wildcard-imports) Wildcard import 
  Resolve these lints or suppress with `suppressLintsFor`
```

To suppress lints, you can do this:

```gradle
spotless {
  kotlin {
    ktlint()
    suppressLintsFor {
      step = 'ktlint'
      shortCode = 'standard:no-wildcard-imports'
    }
  }
}
```

Spotless is primarily a formatter, _not_ a linter. In our opinion, a linter is just a broken formatter. But formatters do break sometimes, and representing these failures as lints that can be suppressed is more useful than just giving up.

<a name="applying-to-java-source"></a>

## Java

`com.diffplug.gradle.spotless.JavaExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/JavaExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JavaExtension.java)

```
/* Detailed source-code truncated for AI context efficiency. */
```

<a name="applying-to-android-java-source"></a>

> [!WARNING]
> The target is usually inferred automatically from the java source sets. However, Spotless cannot automatically detect [android](https://github.com/diffplug/spotless/issues/111) or [java-gradle-plugin](https://github.com/diffplug/spotless/issues/437) sources, but you can fix this easily:
>
> ```gradle
> spotless {
>   java {
>     target 'src/*/java/**/*.java'
> ```

### removeUnusedImports

```
spotless {
  java {
  removeUnusedImports()
  // optional: you may switch for `google-java-format` as underlying engine to `cleanthat-javaparser-unnecessaryimport`
  // which enables processing any language level source file with a JDK8+ Runtime
  removeUnusedImports('cleanthat-javaparser-unnecessaryimport')
```

### forbidWildcardImports

```
spotless {
  java {
    forbidWildcardImports()
  }
}
```

### expandWildcardImports

This step expands all wildcard imports to single class imports.
To do this, [JavaParser](https://javaparser.org/) is used to parse the complete sourcecode and resolve the full qualified name of all used classes and static methods from the full classpath.
This operation can be resource intensive when formatting many source files, so you may want to change to `forbidWildcardImports` when your codebase is cleaned and stable.

```
spotless {
  java {
    expandWildcardImports()
  }
}
```

### forbidModuleImports

```
spotless {
  java {
    forbidModuleImports()
  }
}
```

### shortenFullyQualifiedTypes

Replaces fully-qualified type names with their simple names, adding the imports they need. Useful for cleaning up generated code, or code where inline fully-qualified names have crept in.

[JavaParser](https://javaparser.org/) parses the source and only type positions in the AST are rewritten, so fully-qualified names appearing in strings, text blocks, and comments are left alone. Unlike [`expandWildcardImports`](#expandwildcardimports), it works from the source file alone and does not need your compile classpath.

New imports are appended after the existing ones, so run this before `importOrder()`:

```gradle
spotless {
  java {
    shortenFullyQualifiedTypes()
    importOrder()
    removeUnusedImports()
  }
}
```

Before:

```java
package com.acme;

public class UserService {
  private final java.util.Map<String, java.util.List<String>> cache = new java.util.HashMap<>();

  public java.util.List<String> getUsers(java.util.function.Predicate<String> filter) throws java.io.IOException {
    return new java.util.ArrayList<>();
  }
}
```

After:

```java
package com.acme;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;

public class UserService {
  private final Map<String, List<String>> cache = new HashMap<>();

  public List<String> getUsers(Predicate<String> filter) throws IOException {
    return new ArrayList<>();
  }
}
```

A name is left fully-qualified whenever shortening it could change what the code means:

- two different fully-qualified names in the file would collapse to the same simple name (e.g. `java.util.List` and `java.awt.List`)
- an existing import already binds that simple name to a different type
- the file does not parse

Types in `java.lang` and in the file's own package are shortened without adding an import.

### google-java-format

[homepage](https://github.com/google/google-java-format). [changelog](https://github.com/google/google-java-format/releases).
```gradle
spotless {
  java {
    googleJavaFormat()
    // optional: you can specify a specific version (>= 1.8) and/or switch to AOSP style
    //   and/or reflow long strings
    //   and/or use custom group artifact (you probably don't need this)
    googleJavaFormat('1.8').aosp().reflowLongStrings().formatJavadoc(false).reorderImports(false).groupArtifact('com.google.googlejavaformat:google-java-format')
```

### palantir-java-format

[homepage](https://github.com/palantir/palantir-java-format). [changelog](https://github.com/palantir/palantir-java-format/releases).
```gradle
spotless {
  java {
    palantirJavaFormat()
    // optional: you can specify a specific version and/or switch to AOSP/GOOGLE style
    palantirJavaFormat('2.9.0').style("GOOGLE")
    // optional: you can also format Javadocs, requires at least Palantir 2.39.0
    palantirJavaFormat('2.39.0').formatJavadoc(true)
```

### prince-of-space

[homepage](https://github.com/agustafson/prince-of-space). Requires a JDK 17+ host runtime.
```gradle
spotless {
  java {
    princeOfSpace()
    // optional: configure any of the formatter's options
    princeOfSpace('2.2.0')
        .indentStyle('SPACES') // or 'TABS'
        .indentSize(4)
        .lineLength(120)
        .wrapStyle('BALANCED') // or 'WIDE', 'NARROW'
        .closingParenOnNewLine(true)
        .trailingCommas(false)
        .javaLanguageLevel(17)
```

### eclipse jdt

[homepage](https://download.eclipse.org/eclipse/downloads/). See [here](../ECLIPSE_SCREENSHOTS.md) for screenshots that demonstrate how to get and install the config file mentioned below.

```gradle
spotless {
  java {
    eclipse()
    // optional: you can specify a specific version and/or config file
    eclipse('4.26').configFile('eclipse-prefs.xml')
    // Or supply the configuration properties as a string
    eclipse('4.26').configProperties("""
    ...
    """)
    // Or supply the configuration XML as a string
    eclipse('4.26').configXml("""
    ...
    """)
    // if the access to the p2 repositories is restricted, mirrors can be
    // specified using a URI prefix map as follows:
    eclipse().withP2Mirrors(['https://download.eclipse.org/eclipse/updates/4.29/':'https://some.internal.mirror/4-29-updates-p2/']) 
```

#### Sort Members

Not only can you format your code with Eclipse JDT, but you can also sort the members as you know it from Eclipse IDE.
This ensures that the methods are always in sorted order (and thus reduces the likelihood of collisions in a version 
control system). It is turned off by default, but you might want to consider enabling it when setting coding standards
for a project.

The format to specify the sort order follows the `outlinesortoption` and `org.eclipse.jdt.ui.visibility.order`
properties that can be found in the workspace folder of your Eclipse IDE. You can look at the
file `.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs` in your workspace directory.

```gradle
spotless {
  java {
    eclipse()
      // Optional: Enable the Sort Members feature globally. (default: false)
      .sortMembersEnabled(true)
      // Optional: Specify the sort order of the member categories. (default: T,SF,SI,SM,F,I,C,M)
      //   SF,SI,SM,F,I,C,M,T = Static Fields, Static Initializers, Static Methods, Fields, Initializers, Constructors, Methods, (Nested) Types
      .sortMembersOrder("SF,SI,SM,F,I,C,M,T")
      // Optional: Enable the reordering of fields, enum constants, and initializers. (default: true)
      .sortMembersDoNotSortFields(false)
      // Optional: Enable reordering of members of the same category by the visibility within the category. (default: false)
      .sortMembersVisibilityOrderEnabled(true)
      // Optional: Specify the ordering of members of the same category by the visibility within the category. (default: B,V,R,D)
      //   B,R,D,V = Public, Protected, Package, Private
      .sortMembersVisibilityOrder("B,R,D,V")
```

You can enable/disable the globally defined sort properties on file level by adding the following comments:
- `// @SortMembers:enabled=false` - disable the Sort Members feature for this file
- `// @SortMembers:doNotSortFields=true` - disable the sorting of static and instance fields
- `// @SortMembers:sortByVisibility=false` - don't sort members by its visibility modifier

### formatAnnotations

Type annotations should be on the same line as the type that they qualify.

```java
  @Override
  @Deprecated
  @Nullable @Interned String s;
```

However, some tools format them incorrectly, like this:

```java
  @Override
  @Deprecated
  @Nullable
  @Interned
  String s;
```

To fix the incorrect formatting, add the `formatAnnotations()` rule after a Java formatter.  For example:

```gradle
spotless {
  java {
    googleJavaFormat()
    formatAnnotations()
  }
}
```

This does not re-order annotations, it just removes incorrect newlines.

A type annotation is an annotation that is meta-annotated with `@Target({ElementType.TYPE_USE})`.
Spotless has a default list of well-known type annotations.
You can use `addTypeAnnotation()` and `removeTypeAnnotation()` to override its defaults:

```gradle
    formatAnnotations().addTypeAnnotation("Empty").addTypeAnnotation("NonEmpty").removeTypeAnnotation("Localized")
```

You can make a pull request to add new annotations to Spotless's default list.

### cleanthat

[homepage](https://github.com/solven-eu/cleanthat). CleanThat enables automatic refactoring of Java code. [ChangeLog](https://github.com/solven-eu/cleanthat/blob/master/CHANGES.MD)

```gradle
spotless {
  java {
    cleanthat()
    // optional: you can specify a specific version and/or config file
    cleanthat()
      .groupArtifact('io.github.solven-eu.cleanthat:java') // Optional. Default is 'io.github.solven-eu.cleanthat:java'
      .version('2.25')                                     // You may force a custom version of Cleanthat
      .javaparserVersion('3.26.4')                         // Advanced: override the JavaParser version transitively pulled by Cleanthat
      .sourceCompatibility('1.7')                          // default is '1.7'
      .addMutator('SafeAndConsensual')                     // Default includes the SafeAndConsensual composite mutator
      .addMutator('your.custom.MagicMutator')              // List of mutators: https://github.com/solven-eu/cleanthat/blob/master/MUTATORS.generated.MD
      .excludeMutator('UseCollectionIsEmpty')              // You may exclude some mutators (from Composite ones)
      .includeDraft(false)                                 // You may exclude draft mutators (from Composite ones)
```

### tabletest-formatter

[homepage](https://github.com/nchaugen/tabletest-formatter). [changelog](https://github.com/nchaugen/tabletest-formatter/releases). Formats [`@TableTest`](https://github.com/nchaugen/tabletest) tables in Java source files. All configuration is read from `.editorconfig` files.

```gradle
spotless {
  java {
    tableTestFormatter()
    // optional: you can specify a specific version
    tableTestFormatter('1.1.2')
```

<a name="applying-to-groovy-source"></a>

## Groovy

- `com.diffplug.gradle.spotless.GroovyExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/GroovyExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GroovyExtension.java)
- `com.diffplug.gradle.spotless.GroovyGradleExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/GroovyGradleExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GroovyGradleExtension.java)

Configuration for Groovy is similar to [Java](#java), in that it also supports `licenseHeader` and `importOrder`.

The groovy formatter's default behavior is to format all `.groovy` and `.java` files found in the Java and Groovy source sets.  If you would like to exclude the `.java` files, set the parameter `excludeJava`, or you can set the `target` parameter as described in the [Custom rules](#custom) section.

```gradle
apply plugin: 'groovy'
spotless {
  groovy {
    // Use the default importOrder configuration
    importOrder()
    // optional: you can specify import groups directly
    // note: you can use an empty string for all the imports you didn't specify explicitly, and '\\#` prefix for static imports
    importOrder('java', 'javax', 'com.acme', '', '\\#com.acme', '\\#')
    // optional: instead of specifying import groups directly you can specify a config file
    // export config file: https://github.com/diffplug/spotless/blob/main/ECLIPSE_SCREENSHOTS.md#creating-spotlessimportorder
    importOrderFile('eclipse-import-order.txt') // import order file as exported from eclipse
    // removes semicolons at the end of lines
    removeSemicolons()
    // the Groovy Eclipse formatter extends the Java Eclipse formatter,
    // so it formats Java files by default (unless `excludeJava` is used).
    greclipse() // has its own section below
    
    licenseHeader('/* (C) $YEAR */') // or licenseHeaderFile

    //---- Below is for `groovy` only ----
    
    // excludes all Java sources within the Groovy source dirs from formatting
    excludeJava()
  }
  groovyGradle {
    target '*.gradle' // default target of groovyGradle
    greclipse()
  }
}
```

### eclipse groovy

[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.

```gradle
spotless {
  groovy {
    // Use the default version and Groovy-Eclipse default configuration
    greclipse()
    // optional: you can specify a specific version or config file(s), version matches the Eclipse Platform
    greclipse('4.26').configFile('spotless.eclipseformat.xml', 'org.codehaus.groovy.eclipse.ui.prefs')
    // Or supply the configuration properties as a string
    greclipse('4.26').configProperties("""
    ...
    """)
    // Or supply the configuration XML as a string
    greclipse('4.26').configXml("""
    ...
    """)
```

Groovy-Eclipse formatting errors/warnings lead per default to a build failure. This behavior can be changed by adding the property/key value `ignoreFormatterProblems=true` to a configuration file. In this scenario, files causing problems, will not be modified by this formatter step.

## Kotlin

- `com.diffplug.gradle.spotless.KotlinExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/KotlinExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/KotlinExtension.java)
- `com.diffplug.gradle.spotless.KotlinGradleExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/KotlinGradleExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/KotlinGradleExtension.java)


```gradle
spotless { // if you are using build.gradle.kts, instead of 'spotless {' use:
           // configure<com.diffplug.gradle.spotless.SpotlessExtension> {
  kotlin {
    // by default the target is every '.kt' and '.kts` file in the java sourcesets
    ktfmt()    // has its own section below
    ktlint()   // has its own section below
    diktat()   // has its own section below
    prettier() // has its own section below
    tableTestFormatter() // has its own section below
    licenseHeader '/* (C)$YEAR */' // or licenseHeaderFile
  }
  kotlinGradle {
    target('*.gradle.kts') // default target for kotlinGradle
    ktlint() // or ktfmt() or prettier()
  }
}
```

> [!WARNING]
> The target is usually inferred automatically from the java source sets. However, Spotless cannot automatically detect [android](https://github.com/diffplug/spotless/issues/111) or [java-gradle-plugin](https://github.com/diffplug/spotless/issues/437) sources, but you can fix this easily:
> 
> ```gradle
> spotless {
>   kotlin {
>     target 'src/*/kotlin/**/*.kt', 'src/*/java/**/*.kt'
> ```

### ktfmt

[homepage](https://github.com/Kotlin/ktfmt). [changelog](https://github.com/Kotlin/ktfmt/releases).

```kotlin
spotless {
  kotlin {
    // version, style and all configurations here are optional
    ktfmt("0.51").googleStyle().configure {
      it.setMaxWidth(80)
      it.setBlockIndent(4)
      it.setContinuationIndent(4)
      it.setRemoveUnusedImports(false)
      it.setTrailingCommaManagementStrategy(TrailingCommaManagementStrategy.NONE)
    }
  }
}
```

<a name="applying-ktlint-to-kotlin-files"></a>

### ktlint

[homepage](https://github.com/pinterest/ktlint). [changelog](https://github.com/pinterest/ktlint/releases).

Spotless respects the `.editorconfig` settings by providing `editorConfigPath` option.
([ktlint docs](https://github.com/pinterest/ktlint#editorconfig)).
Default value is the `.editorconfig` file located in the top project.
Passing `null` will clear the option.

Additionally, `editorConfigOverride` options will override what's supplied in `.editorconfig` file.

```kotlin
spotless {
  kotlin {
    // version, editorConfigPath, editorConfigOverride and customRuleSets are all optional
    ktlint("1.0.0")
      .setEditorConfigPath("$projectDir/config/.editorconfig")  // sample unusual placement
      .editorConfigOverride(
        mapOf(
          "indent_size" to 2,
          // intellij_idea is the default style we preset in Spotless, you can override it referring to https://pinterest.github.io/ktlint/latest/rules/code-styles.
          "ktlint_code_style" to "intellij_idea",
        )
      )
      .customRuleSets(
        listOf(
          "io.nlopez.compose.rules:ktlint:0.4.25"
        )
      )
  }
}
```

### diktat

[homepage](https://github.com/cqfn/diKTat). [changelog](https://github.com/cqfn/diKTat/releases). You can provide configuration path manually as `configFile`.

```kotlin
spotless {
  kotlin {
    // version and configFile are both optional
    diktat('1.0.1').configFile("full/path/to/diktat-analysis.yml")
```

### tabletest-formatter

[homepage](https://github.com/nchaugen/tabletest-formatter). [changelog](https://github.com/nchaugen/tabletest-formatter/releases). Formats [`@TableTest`](https://github.com/nchaugen/tabletest) tables in Kotlin source files. All configuration is read from `.editorconfig` files.

```kotlin
spotless {
  kotlin {
    tableTestFormatter()
    // optional: you can specify a specific version
    tableTestFormatter('1.1.2')
```

<a name="applying-scalafmt-to-scala-files"></a>

## Scala

`com.diffplug.gradle.spotless.ScalaExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/ScalaExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/ScalaExtension.java)

```gradle
spotless {
  scala {
    // by default, all `.scala` and `.sc` files in the java sourcesets will be formatted

    scalafmt() // has its own section below

    licenseHeader '/* (C) $YEAR */', 'package ' // or licenseHeaderFile
    // note the 'package ' argument - this is a regex which identifies the top
    // of the file, be careful that all of your sources have a package declaration,
    // or pick a regex which works better for your code
  }
}
```

### scalafmt

[homepage](https://scalameta.org/scalafmt/). [changelog](https://github.com/scalameta/scalafmt/releases). [config docs](https://scalameta.org/scalafmt/docs/configuration.html).

```gradle
spotless {
  scala {
    // version and configFile, scalaMajorVersion are all optional
    scalafmt('3.5.9').configFile('scalafmt.conf').scalaMajorVersion('2.13')
```

<a name="applying-to-cc-sources"></a>

## C/C++

`com.diffplug.gradle.spotless.CppExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/CppExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/CppExtension.java)

```gradle
spotless {
  cpp {
    target 'src/native/**' // you have to set the target manually

    clangFormat()  // has its own section below
    eclipseCdt()   // has its own section below

    licenseHeader '/* (C) $YEAR */' // or licenseHeaderFile
  }
}
```

<a name="eclipse-cdt-formatter"></a>

### eclipse cdt

[homepage](https://www.eclipse.org/cdt/). [compatible versions](https://github.com/diffplug/spotless/tree/main/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_cdt_formatter).

```gradle
spotles {
  cpp {
    // version and configFile are both optional
    eclipseCdt('4.13.0').configFile('eclipse-cdt.xml')
    // Or supply the configuration properties as a string
    eclipseCdt('4.13.0').configProperties("""
    ...
    """)
    // Or supply the configuration XML as a string
    eclipseCdt('4.13.0').configXml("""
    ...
    """)
  }
}
```

## Python

`com.diffplug.gradle.spotless.PythonExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/PythonExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/PythonExtension.java)

```gradle
spotless {
  python {
    target 'src/main/**/*.py' // have to set manually

    black()  // has its own section below

    licenseHeader '/* (C) $YEAR */', 'REGEX_TO_DEFINE_TOP_OF_FILE' // or licenseHeaderFile
  }
}
```

### black

[homepage](https://github.com/psf/black). [changelog](https://github.com/psf/black/blob/master/CHANGES.md).

```gradle
black('19.10b0') // version is optional. Explicitly allow "any found version" with '*'.

// if black is not on your path, you must specify its location manually
black().pathToExe('C:/myuser/.pyenv/versions/3.8.0/scripts/black.exe')
// Spotless always checks the version of the black it is using
// and will fail with an error if it does not match the expected version
// (whether manually specified or default). If there is a problem, Spotless
// will suggest commands to help install the correct version.
//   TODO: handle installation & packaging automatically - https://github.com/diffplug/spotless/issues/674
```

<a name="applying-freshmark-to-markdown-files"></a>

## Protobuf

### buf

`com.diffplug.gradle.spotless.ProtobufExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/ProtobufExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/ProtobufExtension.java)

**WARNING** this step **must** be the first step in the chain, steps before it will be ignored. Thumbs up [this issue](https://github.com/bufbuild/buf/issues/1035) for a resolution, see [here](https://github.com/diffplug/spotless/pull/1208#discussion_r1264439669) for more details on the problem.

```gradle
spotless {
  protobuf {
    // by default the target is every '.proto' file in the project
    buf()

    licenseHeader '/* (C) $YEAR */' // or licenseHeaderFile
  }
}
```

When used in conjunction with the [buf-gradle-plugin](https://github.com/bufbuild/buf-gradle-plugin), the `buf` executable can be resolved from its `bufTool` configuration:

```gradle
spotless {
  protobuf {
    buf().pathToExe(configurations.getByName(BUF_BINARY_CONFIGURATION_NAME).getSingleFile().getAbsolutePath())
  }
}

// Be sure to disable the buf-gradle-plugin's execution of `buf format`:
buf {
  enforceFormat = false
}
```

## FreshMark

`com.diffplug.gradle.spotless.FreshMarkExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/FreshMarkExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FreshMarkExtension.java)

[homepage](https://github.com/diffplug/freshmark). [changelog](https://github.com/diffplug/freshmark/blob/master/CHANGES.md). FreshMark lets you generate markdown in the comments of your markdown.  This helps to keep badges and links up-to-date (see the source for this file), and can
also be helpful for generating complex tables (see the source for [the parent readme](../README.md)).

To apply freshmark to all of the `.md` files in your project, with all of your project's properties available for templating, use this snippet:

```gradle
spotless {
  freshmark {
    target '*.md' // you have to set the target manually
    propertiesFile('gradle.properties')		// loads all the properties in the given file
    properties {
      it.put('key', 'value')				// specify other properties manually
    }
  }
}
```

## Flexmark

`com.diffplug.gradle.spotless.FlexmarkExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/FlexmarkExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FlexmarkExtension.java)

[homepage](https://github.com/vsch/flexmark-java). Flexmark is a flexible Commonmark/Markdown parser that can be used to format Markdown files. It supports different [flavors of Markdown](https://github.com/vsch/flexmark-java#markdown-processor-emulation) and [many formatting options](https://github.com/vsch/flexmark-java/wiki/Markdown-Formatter#options).

The default configuration uses a pegdown compatible parser with `COMMONMARK` as `FORMATTER_EMULATION_PROFILE`.
You can change the `emulationProfile` to one of the other [supported profiles](https://github.com/vsch/flexmark-java/blob/master/flexmark/src/main/java/com/vladsch/flexmark/parser/ParserEmulationProfile.java).
The `pegdownExtensions` can be configured as a list of [constants](https://github.com/vsch/flexmark-java/blob/master/flexmark/src/main/java/com/vladsch/flexmark/parser/PegdownExtensions.java) or as a custom bitset as an integer.
Any other `extension` can be configured using either the simple name as shown in the example or using a full-qualified class name.

Arbitrary formatter options from the [flexmark-java Markdown Formatter](https://github.com/vsch/flexmark-java/wiki/Markdown-Formatter#options) can be set via `formatterOptions`. Each key is a `SCREAMING_SNAKE_CASE` constant from [`com.vladsch.flexmark.formatter.Formatter`](https://github.com/vsch/flexmark-java/blob/master/flexmark/src/main/java/com/vladsch/flexmark/formatter/Formatter.java) (e.g. `RIGHT_MARGIN`). Supported value types are `Integer`, `Boolean`, and `String`.

To apply flexmark to all of the `.md` files in your project, use this snippet:

```gradle
spotless {
  flexmark {
    target '**/*.md' // you have to set the target manually
    flexmark() // or flexmark('0.64.8') // version is optional
      .emulationProfile('COMMONMARK') // optional
      .pegdownExtensions('ALL') // optional
      .extensions('YamlFrontMatter') // optional
      .formatterOptions(['RIGHT_MARGIN': '120']) // optional
  }
}
```

## Antlr4

`com.diffplug.gradle.spotless.Antlr4Extension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/Antlr4Extension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/Antlr4Extension.java)

```gradle
spotless {
  antlr4 {
    target 'src/*/antlr4/**/*.g4' // default value, you can change if you want
    antlr4Formatter() // has its own section below
    licenseHeader '/* (C) $YEAR */' // or licenseHeaderFile
  }
}
```

### antlr4formatter

[homepage](https://github.com/antlr/Antlr4Formatter). [available versions](https://search.maven.org/artifact/com.khubla.antlr4formatter/antlr4-formatter).

```gradle
antlr4formatter('1.2.1') // version is optional
```

## Asciidoc

`com.diffplug.gradle.spotless.AsciidocExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/AsciidocExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/AsciidocExtension.java)

```gradle
spotless {
  asciidoc {
    target 'src/docs/**/*.adoc' // you have to set the target manually

    adocfmt() // has its own section below
  }
}
```

### adocfmt

[homepage](https://github.com/dheid/adocfmt). [available versions](https://search.maven.org/artifact/org.drjekyll/adocfmt).

```gradle
adocfmt('0.3.1') // version is optional
  .normalizeSetextHeadings(false)       // convert === underlines to ATX == (default: false)
  .collapseConsecutiveBlankLines(true)  // max 1 blank line (default: true)
  .oneSentencePerLine(false)            // each sentence on its own line (default: false)
  .normalizeBlockDelimiters(true)       // exactly 4 characters (e.g. ----) (default: true)
  .removeTrailingHeaderEqualsSign(true) // == Title == -> == Title (default: true)
  .titleCase(false)                     // Title Case headings (default: false)
  .removeTrailingWhitespace(true)       // trim end of line (default: true)
  .normalizeListBullets(false)          // - -> * (default: false)
  .normalizeOrderedListMarkers(false)   // 1. -> . (default: false)
  .ensureHeadingBlankLines(true)        // blank line before/after headings (default: true)
  .ensureSourceDelimiters(false)        // wrap [source] in ---- (default: false)
  .formatTables(true)                   // format AsciiDoc tables (default: true)
  .tableLayout('AUTO')                  // AUTO, EXPANDED, PRESERVE (default: AUTO)
  .tableMaxLineWidth(120)               // max line width for compact table layout (default: 120)
  .tableBlankLines('ALL')               // NONE, HEADER, ALL, PRESERVE (default: ALL)
```

Options default to `true` or `false` as shown above. This formatter is designed to help you maintain a clean, consistent AsciiDoc structure. Surface-altering options like `oneSentencePerLine` and `normalizeSetextHeadings` default to `false` so that zero-config formatting is conservative; opt in explicitly if you want those transforms.

<a name="sql-dbeaver"></a>
<a name="applying-dbeaver-to-sql-scripts"></a>

## SQL

`com.diffplug.gradle.spotless.SqlExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/SqlExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SqlExtension.java)

```gradle
spotless {
  sql {
    target 'src/main/resources/**/*.sql' // have to set manually

    dbeaver()  // has its own section below
    prettier() // has its own section below
    idea()     // has its own section below
  }
}
```

### dbeaver

[homepage](https://dbeaver.io/). DBeaver is only distributed as a monolithic jar, so the formatter used here was copy-pasted into Spotless, and thus there is no version to change.

```gradle
spotless {
  sql {
    dbeaver().configFile('dbeaver.properties') // configFile is optional
```

Default configuration file, other options [available here](https://github.com/diffplug/spotless/blob/main/lib/src/main/java/com/diffplug/spotless/sql/dbeaver/DBeaverSQLFormatterConfiguration.java).

```properties
# case of the keywords (UPPER, LOWER or ORIGINAL)
sql.formatter.keyword.case=UPPER
# Statement delimiter
sql.formatter.statement.delimiter=;
# Indentation style (space or tab)
sql.formatter.indent.type=space
# Number of indentation characters
sql.formatter.indent.size=4
```

## Maven POM

`com.diffplug.gradle.spotless.PomExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/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).

```
/* Detailed source-code truncated for AI context efficiency. */
```

<a name="applying-to-typescript-source"></a>

## Typescript

- `com.diffplug.gradle.spotless.TypescriptExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/TypescriptExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java)

```gradle
spotless {
  typescript {
    target 'src/**/*.ts' // you have to set the target manually

    tsfmt()    // has its own section below
    prettier() // has its own section below
    eslint()   // has its own section below
    biome()    // has its own section below

    licenseHeader '/* (C) $YEAR */', '(import|const|declare|export|var) ' // or licenseHeaderFile
    // note the '(import|const|...' argument - this is a regex which identifies the top
    // of the file, be careful that all of your sources have a suitable top-level declaration,
    // or pick a regex which works better for your code
  }
}
```

### tsfmt

[npm](https://www.npmjs.com/package/typescript-formatter). [changelog](https://github.com/vvakame/typescript-formatter/blob/master/CHANGELOG.md). *Please note:*
The auto-discovery of config files (up the file tree) will not work when using tsfmt within spotless,
  hence you are required to provide resolvable file paths for config files, or alternatively provide the configuration inline. See [tsfmt's default config settings](https://github.com/vvakame/typescript-formatter/blob/7764258ad42ac65071399840d1b8701868510ca7/lib/utils.ts#L11L32) for what is available.

```gradle
spotless {
  typescript {
    tsfmt('7.2.2')
      // provide config inline: https://github.com/vvakame/typescript-formatter/blob/7764258ad42ac65071399840d1b8701868510ca7/lib/utils.ts#L11L32
      .config(['indentSize': 1, 'convertTabsToSpaces': true])
      // or according to tsfmt-parameters: https://github.com/vvakame/typescript-formatter/blob/7764258ad42ac65071399840d1b8701868510ca7/lib/index.ts#L27L34
      .tsconfigFile('tsconfig.json')
      .tslintFile('tslint.json')
      .vscodeFile('vscode.json')
      .tsfmtFile('tsfmt.json')
```

**Prerequisite: tsfmt requires a working NodeJS version**

For details, see the [npm detection](#npm-detection), [`.npmrc` detection](#npmrc-detection) and [caching results of `npm install`](#caching-results-of-npm-install) sections of prettier, which apply also to tsfmt.


### ESLint (Typescript)

[npm](https://www.npmjs.com/package/eslint). [changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md). *Please note:*
The auto-discovery of config files (up the file tree) will not work when using ESLint within spotless,
hence you are required to provide resolvable file paths for config files, or alternatively provide the configuration inline.

The configuration is very similar to the [ESLint (Javascript)](#eslint-javascript) configuration. In typescript, a
reference to a `tsconfig.json` is required.

```gradle
spotless {
  typescript {
    eslint('8.30.0') // version is optional
    eslint(['my-eslint-fork': '1.2.3', 'my-eslint-plugin': '1.2.1']) // can specify exactly which npm packages to use

    eslint()
      // configuration is mandatory. Provide inline config or a config file.
      // a) inline-configuration
      .configJs('''
        {
          env: {
            browser: true,
            es2021: true
          },
          extends: 'standard-with-typescript',
          overrides: [
          ],
          parserOptions: {
            ecmaVersion: 'latest',
            sourceType: 'module',
            project: './tsconfig.json',
          },
          rules: {
          }
        }
      ''')
      // b) config file
      .configFile('.eslintrc.js')
      // recommended: provide a tsconfig.json - especially when using the styleguides
      .tsconfigFile('tsconfig.json')
  }
}
```

**Prerequisite: ESLint requires a working NodeJS version**

For details, see the [npm detection](#npm-detection), [`.npmrc` detection](#npmrc-detection) and [caching results of `npm install`](#caching-results-of-npm-install) sections of prettier, which apply also to ESLint.

## Javascript

- `com.diffplug.gradle.spotless.JavascriptExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/JavascriptExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JavascriptExtension.java)

```gradle
spotless {
  javascript {
    target 'src/**/*.js' // you have to set the target manually

    prettier() // has its own section below
    eslint()   // has its own section below
    biome()    // has its own section below

    licenseHeader '/* (C) $YEAR */', 'REGEX_TO_DEFINE_TOP_OF_FILE' // or licenseHeaderFile
  }
}
```

### ESLint (Javascript)

[npm](https://www.npmjs.com/package/eslint). [changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md). *Please note:*
The auto-discovery of config files (up the file tree) will not work when using ESLint within spotless,
hence you are required to provide resolvable file paths for config files, or alternatively provide the configuration inline.

The configuration is very similar to the [ESLint (Typescript)](#eslint-typescript) configuration. In javascript, *no*
`tsconfig.json` is supported.

```gradle
spotless {
  javascript {
    eslint('8.30.0') // version is optional
    eslint(['my-eslint-fork': '1.2.3', 'my-eslint-plugin': '1.2.1']) // can specify exactly which npm packages to use

    eslint()
      // configuration is mandatory. Provide inline config or a config file.
      // a) inline-configuration
      .configJs('''
        {
          env: {
            browser: true,
            es2021: true
          },
          extends: 'standard',
          overrides: [
          ],
          parserOptions: {
            ecmaVersion: 'latest',
            sourceType: 'module'
          },
          rules: {
          }
        }
      ''')
      // b) config file
      .configFile('.eslintrc.js')
  }
}
```

**Prerequisite: ESLint requires a working NodeJS version**

For details, see the [npm detection](#npm-detection), [`.npmrc` detection](#npmrc-detection) and [caching results of `npm install`](#caching-results-of-npm-install) sections of prettier, which apply also to ESLint.

## JSON

- `com.diffplug.gradle.spotless.JsonExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/JsonExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JsonExtension.java)

```gradle
spotless {
  json {
    target 'src/**/*.json'                // you have to set the target manually
    simple()                              // has its own section below
    prettier().config(['parser': 'json']) // see Prettier section below
    eclipseWtp('json')                    // see Eclipse web tools platform section
    gson()                                // has its own section below
    jackson()                             // has its own section below
    biome()                               // has its own section below
    jsonPatch([])                         // has its own section below
  }
}
```

### simple

Uses a JSON pretty-printer that optionally allows configuring the number of spaces that are used to pretty print objects:

```gradle
spotless {
  json {
    target 'src/**/*.json'
    simple()
    // optional: specify the number of spaces to use
    simple().indentWithSpaces(6)
  }
}
```

### Gson

Uses Google Gson to also allow sorting by keys besides custom indentation - useful for i18n files.

```gradle
spotless {
  json {
    target 'src/**/*.json'
    gson()
      .indentWithSpaces(6) // optional: specify the number of spaces to use
      .sortByKeys()        // optional: sort JSON by its keys
      .escapeHtml()        // optional: escape HTML in values
      .version('2.8.1')    // optional: specify version
  }
}
```

Notes:
* There's no option in Gson to leave HTML as-is (i.e. escaped HTML would remain escaped, raw would remain raw). Either
  all HTML characters are written escaped or none. Set `escapeHtml` if you prefer the former.
* `sortByKeys` will apply lexicographic order on the keys of the input JSON. See the
  [javadoc of String](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#compareTo(java.lang.String))
  for details.

### Jackson

Uses Jackson for json files.

```gradle
spotless {
  json {
    target 'src/**/*.json'
    jackson()
      .spaceBeforeSeparator(false)                   // optional: add a whitespace before key separator. False by default
      .feature('INDENT_OUTPUT', true)                // optional: true by default
      .feature('ORDER_MAP_ENTRIES_BY_KEYS', true)    // optional: false by default
      .feature('ANY_OTHER_FEATURE', true|false)      // optional: any SerializationFeature can be toggled on or off
      .jsonFeature('ANY_OTHER_FEATURE', true|false)  // any JsonGenerator.Feature can be toggled on or off
  }
}
```

### jsonPatch

Uses [zjsonpatch](https://github.com/flipkart-incubator/zjsonpatch) to apply [JSON Patches](https://jsonpatch.com/) as per [RFC 6902](https://datatracker.ietf.org/doc/html/rfc6902/) to JSON documents.

This enables you to add, replace or remove properties at locations in the JSON document that you specify using [JSON Pointers](https://datatracker.ietf.org/doc/html/rfc6901/).

In Spotless Gradle, these JSON patches are represented as a `List<Map<String, Object>>`, or a list of patch operations.

Each patch operation must be a map with the following properties:

* `"op"` - the operation to apply, one of `"replace"`, `"add"` or `"remove"`.
* `"path"` - a JSON Pointer string, for example `"/foo"`
* `"value"` - the value to `"add"` or `"replace"` at the specified path. Not needed for `"remove"` operations.

For example, to apply the patch from the [JSON Patch homepage](https://jsonpatch.com/#the-patch):

```gradle
spotless {
  json {
    target 'src/**/*.json'
    jsonPatch([
      [op: 'replace', path: '/baz', value: 'boo'],
      [op: 'add', path: '/hello', value: ['world']],
      [op: 'remove', path: '/foo']
    ])
  }
}
```

Or using the Kotlin DSL:

```kotlin
spotless {
  json {
    target("src/**/*.json")
    jsonPatch(listOf(
      mapOf("op" to "replace", "path" to "/baz", "value" to "boo"),
      mapOf("op" to "add", "path" to "/hello", "value" to listOf("world")),
      mapOf("op" to "remove", "path" to "/foo")
    ))
  }
}
```

## YAML

- `com.diffplug.gradle.spotless.YamlExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/YamlExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/YamlExtension.java)

```gradle
spotless {
  yaml {
    target 'src/**/*.yaml'                // you have to set the target manually
    jackson()                             // has its own section below
    prettier()                            // has its own section below
  }
}
```

### Jackson

Uses Jackson for `yaml` files.

```gradle
spotless {
  yaml {
    target 'src/**/*.yaml'
    jackson()
      .spaceBeforeSeparator(false)                   // optional: add a whitespace before key separator. False by default
      .feature('INDENT_OUTPUT', true)                // optional: true by default
      .feature('ORDER_MAP_ENTRIES_BY_KEYS', true)    // optional: false by default
      .feature('ANY_OTHER_FEATURE', true|false)      // optional: any SerializationFeature can be toggled on or off
      .yamlFeature('ANY_OTHER_FEATURE', true|false)  // any YAMLGenerator.Feature can be toggled on or off
  }
}
```

## Shell

`com.diffplug.gradle.spotless.ShellExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/ShellExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/ShellExtension.java)

```gradle
spotless {
  shell {
    target 'scripts/**/*.sh' // default: '**/*.sh'

    shfmt()  // has its own section below
  }
}
```

### shfmt

[homepage](https://github.com/mvdan/sh). [changelog](https://github.com/mvdan/sh/blob/master/CHANGELOG.md).

When formatting shell scripts via `shfmt`, configure `shfmt` settings via `.editorconfig`. 
Refer to the `shfmt` [man page](https://github.com/mvdan/sh/blob/master/cmd/shfmt/shfmt.1.scd) for `.editorconfig` settings. 

```gradle
shfmt('3.8.0') // version is optional. Explicitly allow "any found version" with '*'.

// if shfmt is not on your path, you must specify its location manually
shfmt().pathToExe('/opt/homebrew/bin/shfmt')

// Spotless always checks the version of the shfmt it is using
// and will fail with an error if it does not match the expected version
// (whether manually specified or default). If there is a problem, Spotless
// will suggest commands to help install the correct version.
//   TODO: handle installation & packaging automatically - https://github.com/diffplug/spotless/issues/674
```

<a name="applying-freshmark-to-markdown-files"></a>

## TableTest

- `com.diffplug.gradle.spotless.TableTestExtension` [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TableTestExtension.java)

```gradle
spotless {
  tableTest {
    target 'src/**/*.table' // you have to set the target manually
    tableTestFormatter()    // has its own section below
  }
}
```

### tabletest-formatter

[homepage](https://github.com/nchaugen/tabletest-formatter). [changelog](https://github.com/nchaugen/tabletest-formatter/releases). Formats standalone [TableTest](https://github.com/nchaugen/tabletest) `.table` files.

```gradle
spotless {
  tableTest {
    target 'src/**/*.table'
    tableTestFormatter()
    // optional: you can specify a specific version
    tableTestFormatter('1.1.2')
  }
}
```

## Gherkin

- `com.diffplug.gradle.spotless.GherkinExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/GherkinExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GherkinExtension.java)

```gradle
spotless {
  gherkin {
    target 'src/**/*.feature' // you have to set the target manually
    gherkinUtils() // has its own section below
  }
}
```

### gherkinUtils

[homepage](https://github.com/cucumber/gherkin-utils). [changelog](https://github.com/cucumber/gherkin-utils/blob/main/CHANGELOG.md).

Uses a Gherkin pretty-printer that optionally allows configuring the number of spaces that are used to pretty print objects:

```gradle
spotless {
  gherkin {
    target 'src/**/*.feature'     // required to be set explicitly
    gherkinUtils()
      .version('9.0.0')           // optional: custom version of 'io.cucumber:gherkin-utils'
  }
}
```

## CSS

`com.diffplug.gradle.spotless.CssExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/CssExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/CssExtension.java)

```gradle
spotless {
  css {
    target 'css/**/*.css' // default: '**/*.css'

    biome('1.8.3')  // has its own section below
  }
}
```

Note regarding biome: Biome supports formatting CSS as of 1.8.0 (experimental, opt-in) and 1.9.0 (stable).

## Prettier

[homepage](https://prettier.io/). [changelog](https://github.com/prettier/prettier/blob/master/CHANGELOG.md). [official plugins](https://prettier.io/docs/en/plugins.html#official-plugins). [community plugins](https://prettier.io/docs/en/plugins.html#community-plugins). Prettier is a formatter that can format almost every anything - JavaScript, JSX, Angular, Vue, Flow, TypeScript, CSS, Less, SCSS, HTML, JSON, GraphQL, Markdown (including GFM and MDX), and YAML.  It can format even more [using plugins](https://prettier.io/docs/en/plugins.html) (PHP, Ruby, Swift, XML, Apex, Elm, Java (!!), Kotlin, pgSQL, .properties, solidity, svelte, toml, shellscript, ...).

You can use prettier in any language-specific format, but usually you will be creating a generic format.

```gradle
spotless {
  format 'styling', {
    // you have to set the target manually
    target 'src/*/webapp/**/*.css', 'src/*/webapp/**/*.scss'

    prettier('2.0.4') // version is optional
    prettier(['my-prettier-fork': '1.16.4']) // can specify exactly which npm packages to use

    // by default, prettier uses the file's extension to guess a parser
    // but you can override that and specify the parser manually
    prettier().config(['parser': 'css'])

    // you can also set some style options
    // https://prettier.io/docs/en/configuration.html
    prettier().config(['tabWidth': 4])

    // you can also slurp from a file or even provide both (inline always takes precedence over file)
    prettier().config(['tabWidth': 4]).configFile('path-to/.prettierrc.yml')
  }
}
```

**Limitations:**
- The auto-discovery of config files (up the file tree) will not work when using prettier within spotless.
- Prettier's override syntax is not supported when using prettier within spotless.

To apply prettier to more kinds of files, just add more formats

<a name="using-plugins-for-prettier"></a>

### prettier plugins

Since spotless uses the actual npm prettier package behind the scenes, it is possible to use prettier with
[plugins](https://prettier.io/docs/en/plugins.html#official-plugins) or [community-plugins](https://www.npmjs.com/search?q=prettier-plugin) in order to support even more file types.

#### prettier version below 3

```gradle
spotless {
  java {
    prettier(['prettier': '2.8.8', 'prettier-plugin-java': '2.2.0']).config(['parser': 'java', 'tabWidth': 4])
  }
  format 'php', {
    target 'src/**/*.php'
    prettier(['prettier': '2.8.8', '@prettier/plugin-php': '0.19.6']).config(['parser': 'php', 'tabWidth': 3])
  }
}
```

#### prettier version 3+

With version 3 prettier it is required to pass in an additional 'plugins' parameter to the config block with a list of plugins you want to use.

```gradle
spotless {
  java {
    prettier(['prettier': '3.0.3', 'prettier-plugin-java': '2.3.0'])
      .config(['parser': 'java', 'tabWidth': 4, 'plugins': ['prettier-plugin-java']])
  }
  format 'php', {
    target 'src/**/*.php'
    prettier(['prettier': '3.0.3', '@prettier/plugin-php': '0.20.1'])
      .config(['parser': 'php', 'tabWidth': 3, 'plugins': ['@prettier/plugin-php']])
  }
}
```

### npm detection

Prettier is based on NodeJS, so a working NodeJS installation (especially npm) is required on the host running spotless.
Spotless will try to auto-discover an npm installation. If that is not working for you, it is possible to directly configure the npm
and/or node binary to use.

```gradle
spotless {
  format 'javascript', {
    prettier().npmExecutable('/usr/bin/npm').nodeExecutable('/usr/bin/node').config(...)
```

If you provide both `npmExecutable` and `nodeExecutable`, spotless will use these paths. If you specify only one of the
two, spotless will assume the other one is in the same directory.

If you use the `gradle-node-plugin` ([github](https://github.com/node-gradle/gradle-node-plugin)), it is possible to use the
node- and npm-binaries dynamically installed by this plugin. See
[this](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/test/resources/com/diffplug/gradle/spotless/NpmTestsWithoutNpmInstallationTest_gradle_node_plugin_example_1.gradle)
or [this](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/test/resources/com/diffplug/gradle/spotless/NpmTestsWithoutNpmInstallationTest_gradle_node_plugin_example_2.gradle) example.

### `.npmrc` detection

Spotless picks up npm configuration stored in a `.npmrc` file either in the project directory or in your user home.
Alternatively you can supply spotless with a location of the `.npmrc` file to use. (This can be combined with
`npmExecutable` and `nodeExecutable`, of course.)

```gradle
spotless {
  typescript {
    prettier().npmrc("$projectDir/config/.npmrc").config(...)
```

### Caching results of `npm install`

Spotless uses `npm` behind the scenes to install `prettier`. This can be a slow process, especially if you are using a slow internet connection or
if you need large plugins. You can instruct spotless to cache the results of the `npm install` calls, so that for the next installation,
it will not need to download the packages again, but instead reuse the cached version.

```gradle
spotless {
  typescript {
    prettier().npmInstallCache() // will use the default cache directory (the build-directory of the respective module)
    prettier().npmInstallCache("${rootProject.rootDir}/.gradle/spotless-npm-cache") // will use the specified directory (creating it if not existing)
```

Depending on your filesystem and the location of the cache directory, spotless will use hardlinks when caching the npm packages. If that is not
possible, it will fall back to copying the files.

## clang-format

[homepage](https://clang.llvm.org/docs/ClangFormat.html). [changelog](https://releases.llvm.org/download.html). `clang-format` is a formatter for c, c++, c#, objective-c, protobuf, javascript, and java. You can use clang-format in any language-specific format, but usually you will be creating a generic format.

```gradle
spotless {
  format 'csharp', {
    // you have to set the target manually
    target 'src/**/*.cs'

    clangFormat('10.0.1') // version is optional. Explicitly allow "any found version" with '*'.

    // can also specify a code style
    clangFormat().style('LLVM') // or Google, Chromium, Mozilla, WebKit
    // TODO: support arbitrary .clang-format

    // if clang-format is not on your path, you must specify its location manually
    clangFormat().pathToExe('/usr/local/Cellar/clang-format/10.0.1/bin/clang-format')
    // Spotless always checks the version of the clang-format it is using
    // and will fail with an error if it does not match the expected version
    // (whether manually specified or default). If there is a problem, Spotless
    // will suggest commands to help install the correct version.
    //   TODO: handle installation & packaging automatically - https://github.com/diffplug/spotless/issues/673
  }
}
```

<a name="applying-eclipse-wtp-to-css--html--etc"></a>

## Eclipse web tools platform

[changelog](https://www.eclipse.org/webtools/). [compatible versions](https://github.com/diffplug/spotless/tree/main/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_wtp_formatters).

```gradle
spotless {
  format 'xml', {
    target 'src/**/*.xml' // must specify target
    eclipseWtp('xml')     // must specify a type (table below)
    eclipseWtp('xml', '11.0') // optional version, others at https://download.eclipse.org/tools/cdt/releases/
    // you can also specify an arbitrary number of config files
    eclipseWtp('xml').configFile('spotless.xml.prefs', 'spotless.common.properties'
  }
}
```
The WTP formatter accept multiple configuration files. All Eclipse configuration file formats are accepted as well as simple Java property files. Omit the `configFile` entirely to use the default Eclipse configuration. The following formatters and configurations are supported:

| Type | Configuration       | File location
| ---- | ------------------- | -------------
| CSS  | editor preferences  | .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.css.core.prefs
|      | cleanup preferences | .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.css.core.prefs
| HTML | editor preferences  | .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.html.core.prefs
|      | cleanup preferences | .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.html.core.prefs
|      | embedded CSS        | .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.css.core.prefs
|      | embedded JS         | Use the export in the Eclipse editor configuration dialog
| JS   | editor preferences  | Use the export in the Eclipse editor configuration dialog
| JSON | editor preferences  | .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.json.core.prefs
| XML  | editor preferences  | .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.xml.core.prefs

Note that `HTML` should be used for `X-HTML` sources instead of `XML`.

The Eclipse XML catalog cannot be configured for the Spotless WTP formatter, instead a
user defined catalog file can be specified using the property `userCatalog`. Catalog versions
1.0 and 1.1 are supported by Spotless.

Unlike Eclipse, Spotless WTP ignores per default external URIs in schema location hints and
external entities. To allow the access of external URIs, set the property `resolveExternalURI`
to true.

## Biome

[homepage](https://biomejs.dev/). [changelog](https://github.com/biomejs/biome/blob/main/CHANGELOG.md). Biome is
a formatter that for the frontend written in Rust, which has a native binary, does not require Node.js and as such,
is pretty fast. It can currently format JavaScript, TypeScript, JSX, and JSON, and may support
[more frontend languages](https://biomejs.dev/internals/language-support/) such as CSS in the future.

You can use Biome in any language-specific format for supported languages, but
usually you will be creating a generic format.

Note regarding biome: Biome supports formatting CSS as of 1.8.0 (experimental, opt-in) and 1.9.0 (stable).

```gradle
spotless {
  format 'styling', {
    // you have to set the target manually
    target 'src/*/webapp/**/*.js'

    // Download Biome from the network if not already downloaded, see below for more info
    biome('2.1.0')

    // (optional) Path to the directory with the biome.json conig file
    biome('2.1.0').configPath("path/config/dir")

    // (optional) Biome will auto detect the language based on the file extension.
    // See below for possible values.
    biome('2.1.0').language("js")
  }
}
```

To apply Biome to more kinds of files with a different configuration, just add
more formats:

```gradle
spotless {
  format 'biome-js', {
    target '**/*.js'
    biome('2.1.0')
  }
  format 'biome-ts', {
    target '**/*.ts'
    biome('2.1.0')
  }
  format 'biome-json', {
    target '**/*.json'
    biome('2.1.0')
  }
}
```

**Limitations:**

- The auto-discovery of config files (up the file tree) will not work when using
  Biome within spotless.
- The `ignore` option of the `biome.json` configuration file will not be applied.
  Include and exclude patterns are configured in the spotless configuration in the
  Gradle settings file instead.

Note: Due to a limitation of biome, if the name of a file matches a pattern in
the `ignore` option of the specified `biome.json` configuration file, it will not be
formatted, even if included in the biome configuration section of the Gradle settings
file.

You could specify a different `biome.json` configuration file without an `ignore`
pattern to circumvent this.

Note 2: Biome is hard-coded to ignore certain special files, such as `package.json`
or `tsconfig.json`. These files will never be formatted.

### Biome binary

To format with Biome, spotless needs to find the Biome binary. By default,
spotless downloads the binary for the given version from the network. This
should be fine in most cases, but may not work e.g. when there is not connection
to the internet.

To download the Biome binary from the network, just specify a version:

```gradle
spotless {
  format 'biome', {
    target '**/*.js','**/*.ts','**/*.json'
    biome('1.2.0')
  }
}
```

Spotless uses a default version when you do not specify a version, but this
may change at any time, so we recommend that you always set the Biome version
you want to use. Optionally, you can also specify a directory for the downloaded
Biome binaries (defaults to `~/.m2/repository/com/diffplug/spotless/spotless-data/biome`):

```gradle
spotless {
  format 'biome', {
    target '**/*.js','**/*.ts','**/*.json'
     // Relative paths are resolved against the project's base directory
    biome('1.2.0').downloadDir("${project.gradle.gradleUserHomeDir}/biome")
  }
}
```

To use a fixed binary, omit the `version` and specify a `pathToExe`:

```gradle
spotless {
  format 'biome', {
    target '**/*.js','**/*.ts','**/*.json'
    biome().pathToExe("${project.layout.buildDirectory.asFile.get().absolutePath}/bin/biome")
  }
}
```

Absolute paths are used as-is. Relative paths are resolved against the project's
base directory. To use a pre-installed Biome binary on the user's path, specify
just a name without any slashes / backslashes:

```gradle
spotless {
  format 'biome', {
    target '**/*.js','**/*.ts','**/*.json'
    // Uses the "biome" command, which must be on the user's path. -->
    biome().pathToExe('biome')
  }
}
```

### Biome configuration file

Biome is a biased formatter and linter without many options, but there are a few
basic options. Biome uses a file named [biome.json](https://biomejs.dev/reference/configuration/)
for its configuration. When none is specified, the default configuration from
Biome is used. To use a custom configuration:

```gradle
spotless {
  format 'biome', {
    target '**/*.js','**/*.ts','**/*.json'
    // Must point to the directory with the "biome.json" config file -->
    // Relative paths are resolved against the project's base directory -->
    biome('2.1.0').configPath('./config')
  }
}
```

__If spotless does not format any files__, this might be because you excluded those files in you biome.json
configuration file. If you are using biome 2.x, you can create a custom config file for spotless and inherit from
your main config file like this:

```jsonc
// biome-spotless.json
{
  "extends": "./biome.json",
  "include": ["**"]
}
```

Then simply specify the path to this file in your spotless configuration:

```gradle
spotless {
  format 'biome', {
    biome('2.1.0').configPath('./config/biome-spotless.json')
  }
}
```

### Biome input language

By default, Biome detects the language / syntax of the files to format
automatically from the file extension. This may fail if your source code files
have unusual extensions for some reason. If you are using the generic format,
you can force a certain language like this:

```xml
spotless {
  format 'biome', {
    target 'src/**/typescript/**/*.mjson'
    biome('1.2.0').language('json')
  }
}
```

The following languages are currently recognized:

* `js` -- JavaScript
* `jsx` -- JavaScript + JSX (React)
* `js?` -- JavaScript, with or without JSX, depending on the file extension
* `ts` -- TypeScript
* `tsx` -- TypeScript + JSX (React)
* `ts?` -- TypeScript, with or without JSX, depending on the file extension
* `json` -- JSON

## IntelliJ IDEA

[homepage](https://www.jetbrains.com/idea/). [changelog](https://www.jetbrains.com/idea/whatsnew/). 

`IntelliJ IDEA` is a powerful IDE for java, kotlin and many more languages. There are [specific variants](https://www.jetbrains.com/products/) for almost any modern language
and a plethora of [plugins](https://plugins.jetbrains.com/).

Spotless provides access to IntelliJ IDEA's command line formatter. 

```gradle
spotless {
  format 'myFormatter', {
    // you have to set the target manually
    target 'src/main/**/*.java','jbang/*.java'

    idea()
      .codeStyleSettingsPath('/path/to/config') // if you have custom formatting rules, see below for how to extract/reference them
      .withDefaults(false) // Disable using default code style settings when no custom code style is defined for a file type (default: true)

    // if idea is not on your path, you must specify the path to the executable
    idea().binaryPath('/path/to/idea')
  }
}
```

### How to generate code style settings files
See [here](../INTELLIJ_IDEA_SCREENSHOTS.md) for an explanation on how to extract or reference existing code style files. 

### Limitations
- Currently, only IntelliJ IDEA is supported - none of the other jetbrains IDE. Consider opening a PR if you want to change this.
- Launching IntelliJ IDEA from the command line is pretty expensive and as of now, we do this for each file. If you want to change this, consider opening a PR.

## Generic steps

[Prettier](#prettier), [eclipse wtp](#eclipse-web-tools-platform), [IntelliJ IDEA](#intellij-idea) and [license header](#license-header) are available in every format, and they each have their own section. As mentioned in the [quickstart](#quickstart), there are a variety of simple generic steps which are also available in every format, here are examples of these:

```gradle
spotless {
  // run a native binary
  format 'terraform', {
    target 'src/**/*.tf', 'src/**/*.tfvars' // you have to set the target manually
    nativeCmd('terraform', '/opt/homebrew/bin/terraform', ['fmt', '-']) // name, path to binary, additional arguments
  }
}
```

<a name="license-header-options"></a>

## License header

If the license header (specified with `licenseHeader` or `licenseHeaderFile`) contains `$YEAR` or `$today.year`, then that token will be replaced with the current 4-digit year.  For example, if Spotless is launched in 2020, then `/* Licensed under Apache-2.0 $YEAR. */` will produce `/* Licensed under Apache-2.0 2020. */`

Once a file's license header has a valid year, whether it is a year (`2020`) or a year range (`2017-2020`), it will not be changed.  If you want the date to be updated when it changes, enable the [`ratchetFrom` functionality](#ratchet), and the year will be automatically set to today's year according to the following table (assuming the current year is 2020):

* No license header -> `2020`
* `2017` -> `2017-2020`
* `2017-2019` -> `2017-2020`

See the [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/FormatExtension.LicenseHeaderConfig.html) for a complete listing of options.

<a name="retroactively-populating-year-range-from-git-history"></a>

### Retroactively slurp years from git history

If your project has not been rigorous with copyright headers, and you'd like to use git history to repair this retroactively, you can do so with `-PspotlessSetLicenseHeaderYearsFromGitHistory=true`.  When run in this mode, Spotless will do an expensive search through git history for each file, and set the copyright header based on the oldest and youngest commits for that file.  This is intended to be a one-off sort of thing.

### Files with fixed header lines

Some files have fixed header lines (e.g. `<?xml version="1.0" ...` in XMLs, or `#!/bin/bash` in bash scripts). Comments cannot precede these, so the license header has to come after them, too.

To define what lines to skip at the beginning of such files, fill the `skipLinesMatching` option with a regular expression that matches them (e.g. `.skipLinesMatching("^#!.+?\$")` to skip shebangs).

<a name="ratchet"></a>

## How can I enforce formatting gradually? (aka "ratchet")

If your project is not currently enforcing formatting, then it can be a noisy transition.  Having a giant commit where every single file gets changed makes the history harder to read.  To address this, you can use the `ratchet` feature:

```gradle
spotless {
  ratchetFrom 'origin/main' // only format files which have changed since origin/main
```

In this mode, Spotless will apply only to files which have changed since `origin/main`.  You can ratchet from [any point you want](https://javadoc.io/doc/org.eclipse.jgit/org.eclipse.jgit/5.6.1.202002131546-r/org/eclipse/jgit/lib/Repository.html#resolve-java.lang.String-), even `HEAD`.  You can also set `ratchetFrom` per-format if you prefer (e.g. `spotless { java { ratchetFrom ...`).

However, we strongly recommend that you use a non-local branch, such as a tag or `origin/main`.  The problem with `HEAD` or any local branch is that as soon as you commit a file, that is now the canonical formatting, even if it was formatted incorrectly.  By instead specifying `origin/main` or a tag, your CI server will fail unless every changed file is at least as good or better than it was before the change.

This is especially helpful for injecting accurate copyright dates using the [license step](#license-header).

### Using `ratchetFrom` on CI systems

Many popular CI systems (GitHub, GitLab, BitBucket, and Travis) use a "shallow clone". This means that `ratchetFrom 'origin/main'` will fail with `No such reference`. You can fix this by:

- calling `git fetch origin main` before you call Spotless
- disabling the shallow clone [like so](https://github.com/diffplug/spotless/issues/710)

## `spotless:off` and `spotless:on`

Sometimes there is a chunk of code  which you have carefully handcrafted, and you would like to exclude just this one little part from getting clobbered by the autoformat. Some formatters have a way to do this, many don't, but who cares.  If you setup your spotless like this:

```gradle
spotless {
  java { // or kotlin, or c, or python, or whatever
    toggleOffOn()
```

Then whenever Spotless encounters a pair of `spotless:off` / `spotless:on`, it will exclude the code between them from formatting, regardless of all other rules. If you want, you can change the tags to be whatever you want, e.g. `toggleOffOn('fmt:off', 'fmt:on')`. If you decide to change the default, be sure to [read this](https://github.com/diffplug/spotless/pull/691) for some gotchas.

<a name="invisible"></a>

## Line endings and encodings (invisible stuff)

Spotless uses UTF-8 by default, but you can use [any encoding which the JVM supports](https://docs.oracle.com/javase/8/docs/technotes/guides/intl/encoding.doc.html).  You can set it globally, and you can also set it per-format.

```gradle
spotless {
  encoding 'UTF-8' // all formats will be interpreted as UTF-8
  java {
    encoding 'Cp1252' // except java, which will be Cp1252
```

Line endings can also be set globally or per-format using the `lineEndings` property.  Spotless supports

- constant modes (`UNIX`, `WINDOWS`, `MAC_CLASSIC`)
- simple modes (`PLATFORM_NATIVE`, `PRESERVE`)
- and git-aware modes (`GIT_ATTRIBUTES`, `GIT_ATTRIBUTES_FAST_ALLSAME`)

The default value is `GIT_ATTRIBUTES_FAST_ALLSAME`, and *we highly recommend that you* ***do not change*** *this value*.  Git has opinions about line endings, and if Spotless and git disagree, then you're going to have a bad time. `FAST_ALLSAME` just means that Spotless can assume that every file being formatted has the same line endings ([more info](https://github.com/diffplug/spotless/pull/1838)).

You can easily set the line endings of different files using [a `.gitattributes` file](https://help.github.com/articles/dealing-with-line-endings/).  Here's an example `.gitattributes` which sets all files to unix newlines: `* text eol=lf`.

<a name="custom"></a>
<a name="custom-steps"></a>

## Custom steps

As described in the [quickstart](#quickstart), Spotless is just a set of files ("target"), passed through a list of `String -> String` functions.  The string each function gets will always have unix `\n` endings, and Spotless doesn't care which endings the function provides back, it will renormalize regardless.  You can easily make a new step directly in your buildscript, like so:

```gradle
spotless {
  format 'misc', {
    custom 'lowercase', { str -> str.toLowerCase() }
```

However, custom rules will disable up-to-date checking and caching, unless you read [this javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/FormatExtension.html#bumpThisNumberIfACustomStepChanges-int-) and follow its instructions carefully.

Another option is to create proper `FormatterStep` in your `buildSrc`, and then call [`addStep`](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/FormatExtension.html#addStep-com.diffplug.spotless.FormatterStep-).  The contributing guide describes [how to do this](https://github.com/diffplug/spotless/blob/main/CONTRIBUTING.md#how-to-add-a-new-formatterstep).  If the step is generally-useful, we hope you'll open a PR to share it!


```gradle
spotless {
  format 'misc', {
    addStep(MyFormatterStep.create())
```

### Throwing errors

Ideally, your formatter will be able to silently fix any problems that it finds, that's the beauty of the `String -> String` model.  But sometimes that's not possible.  If you throw

- `AssertionError` or a subclass -> Spotless reports as a problem in the file being formatted
- anything else -> Spotless reports as a bug in the formatter itself

## Multiple (or custom) language-specific blocks

If you want to have two independent `java` blocks, you can do something like this:

```gradle
spotless { java { ... } }
spotless { format 'javaFoo', com.diffplug.gradle.spotless.JavaExtension, { ... } }
// has to be 'javaFoo' not 'java' because each format needs a unique name
```

That's how the [real `spotless { java {` works anyway](https://github.com/diffplug/spotless/blob/1a19b3f6e92da9ccfb6e4a0024b8fc5de8898ade/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtensionBase.java#L109-L113). As a follow-on, you can make your own subclass to `FormatExtension` in the `buildSrc` directory, and then use it in your buildscript like so:

```gradle
spotless {
  format 'foo', com.acme.FooLanguageExtension, {
```

If you'd like to create a one-off Spotless task outside of the `check`/`apply` framework, see [`FormatExtension.createIndependentApplyTask`](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/FormatExtension.html#createIndependentApplyTask-java.lang.String-).

## Inception (languages within languages within...)

In very rare cases, you might want to format e.g. javascript which is written inside JSP templates, or maybe java within a markdown file, or something wacky like that.  You can specify hunks within a file using either open/close tags or a regex with a single capturing group, and then specify rules within it, like so.  See [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/8.10.4/com/diffplug/gradle/spotless/FormatExtension.html#withinBlocks-java.lang.String-java.lang.String-java.lang.String-org.gradle.api.Action-) for more details.

```gradle
import com.diffplug.gradle.spotless.JavaExtension

spotless {
  format 'templates', {
    target 'src/templates/**/*.foo.html'
    prettier().config(['parser': 'html'])
    withinBlocks 'javascript block', '<script>', '</script>', {
      prettier().config(['parser': 'javascript'])
    }
    withinBlocksRegex 'single-line @(java-expresion)', '@\\((.*?)\\)', JavaExtension, {
      googleJavaFormat()
    }
```

<a name="enforceCheck"></a>

## Disabling warnings and error messages

The `check` task is Gradle's built-in task for grouping all verification tasks - unit tests, static analysis, etc.  By default, `spotlessCheck` is added as a dependency to `check`.

You might want to disable this behavior.  We [recommend against this](https://github.com/diffplug/spotless/issues/79#issuecomment-290844602), but it's easy to do if you'd like:

```gradle
spotless {
  enforceCheck false
}
```

When a misformatted file throws an exception, it will be for one of two reasons:

1) Spotless calculated the properly formatted version, and it is different than the current contents.
2) One of the formatters threw an exception while attempting to calculate the properly formatted version.

You can fix (1) by excluding the file from formatting using the `targetExclude` method, see the [quickstart](#quickstart) section for details.  You can fix (2) and turn these exceptions into warnings like this:

```gradle
spotless {
  java {
    custom 'my-glitchy-step', { ... }

    ignoreErrorForStep('my-glitchy-step')   // ignore errors on all files thrown by a specific step
    ignoreErrorForPath('path/to/file.java') // ignore errors by all steps on this specific file
```

<a name="dependency-resolution-modes"></a>
## Dependency resolution modes

By default, Spotless resolves dependencies on a per-project basis. For very large parallel builds, this can sometimes cause problems. As an alternative, Spotless can be configured to resolve all dependencies in the root project like so:

```gradle
spotlessPredeclare {
  java { eclipse() }
  kotlin { ktfmt('0.28') }
}
```

By default, `spotlessPredeclare` resolves dependencies from the root project's repositories. Alternatively, you can resolve dependencies from the buildscript repositories rather than the project repositories:

```gradle
buildscript {
  repositories { mavenCentral() }
}
spotlessPredeclare {
  fromBuildscriptRepositories()
  java { eclipse() }
  kotlin { ktfmt('0.28') }
}
```

The older `spotless { predeclareDeps() }` and `spotless { predeclareDepsFromBuildscript() }` APIs are still supported.

If you use this feature, you will get an error if you use a formatter in a subproject which is not declared in the `spotlessPredeclare` block.

Note that this feature is also incompatible with Isolated projects, because every project must reference the root project.

<a name="preview"></a>

## How do I preview what `spotlessApply` will do?

- Save your working tree with `git add -A`, then `git commit -m "Checkpoint before spotless."`
- Run `gradlew spotlessApply`
- View the changes with `git diff`
- If you don't like what spotless did, `git reset --hard`
- If you'd like to remove the "checkpoint" commit, `git reset --soft head~1` will make the checkpoint commit "disappear" from history, but keeps the changes in your working directory.

## Can I apply Spotless to specific files?

You can target specific files by setting the `spotlessFiles` project property to a comma-separated list of file patterns:

```
cmd> gradle spotlessApply -PspotlessFiles=my/file/pattern.java,more/generic/.*-pattern.java
```

The patterns are matched using `String#matches(String)` against the absolute file path.

<a name="central-configuration"></a>

## How to centralize Spotless configuration

If you want to centralize your Spotless configuration for use across many projects, you might want to consider the [Blowdryer](https://github.com/diffplug/blowdryer) plugin.

If you are content with only centralizing configuration files, it is possible to define a common configuration that is deployed as a standard artifact so that it can be then be reused by each project. For example:

```kotlin
configurations {
  spotlessConfig
}
dependencies {
  // the files `java-import-order.txt` and `java-formatter.xml` should be at the root of the deployed `org.mycompany:code-configuration:1.0.0` jar.
  spotlessConfig("org.mycompany:code-configuration:1.0.0")
}
spotless {
  java {
    removeUnusedImports()
    importOrder(resources.text.fromArchiveEntry(configurations.spotlessConfig, "java-import-order.txt").asString())
    eclipse().configXml(resources.text.fromArchiveEntry(spotlessConfig, "java-formatter.xml").asString())
  }
}
```

<a name="examples"></a>

## Example configurations (from real-world projects)

* [A few thousand github projects](https://github.com/search?l=gradle&q=spotless&type=Code)
* [JUnit 5](https://github.com/junit-team/junit-lambda/blob/151d52ffab07881de71a8396a9620f18072c65ec/build.gradle#L86-L101) (aka JUnit Lambda)
* [Apache Beam](https://beam.apache.org/) ([direct link to spotless section in its build.gradle](https://github.com/apache/beam/blob/1d9daf1aca101fa5a194cbbba969886734e08902/buildSrc/src/main/groovy/org/apache/beam/gradle/BeamModulePlugin.groovy#L776-L789))
* [opentest4j](https://github.com/ota4j-team/opentest4j/blob/aab8c204be05609e9f76c2c964c3d6845cd0de14/build.gradle#L63-L80)
* [Durian](https://github.com/diffplug/durian) ([direct link to spotless section in its build.gradle](https://github.com/diffplug/durian/blob/v3.2.0/build.gradle#L65-L85))
* [DurianRx](https://github.com/diffplug/durian-rx) ([direct link to spotless section in its build.gradle](https://github.com/diffplug/durian-rx/blob/v1.1.0/build.gradle#L92-L113))
* [DurianSwt](https://github.com/diffplug/durian-swt) ([direct link to spotless section in its build.gradle](https://github.com/diffplug/durian-swt/blob/v1.3.0/build.gradle#L137-L158))
* [MatConsoleCtl](https://github.com/diffplug/matconsolectl) ([direct link to spotless section in its build.gradle](https://github.com/diffplug/matconsolectl/blob/v4.4.1/build.gradle#L169-L189))
* [MatFileRW](https://github.com/diffplug/matfilerw) ([direct link to spotless section in its build.gradle](https://github.com/diffplug/matfilerw/blob/v1.3.1/build.gradle#L129-L149))
* [Goomph](https://github.com/diffplug/goomph) ([direct link to spotless section in its build.gradle](https://github.com/diffplug/goomph/blob/v1.0.0/build.gradle#L78-L99))
* [FreshMark](https://github.com/diffplug/freshmark) ([direct link to spotless section in its build.gradle](https://github.com/diffplug/freshmark/blob/v1.3.0/build.gradle#L52-L73))
* [JScriptBox](https://github.com/diffplug/jscriptbox) ([direct link to spotless section in its build.gradle](https://github.com/diffplug/jscriptbox/blob/v3.0.0/build.gradle#L45-L65))
* [Compose Guard](https://github.com/j-roskopf/ComposeGuard) ([direct link to spotless section in its build.gradle.kts](https://github.com/j-roskopf/ComposeGuard/blob/main/compose-guard/build.gradle.kts#L28-L48))
* (Your project here)

---

### Overview (`plugin-maven/README.md`)

# <img align="left" src="../_images/spotless_logo.png"> Spotless: Keep your code spotless with Maven


[](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.diffplug.spotless%22%20AND%20a%3A%22spotless-maven-plugin%22)
[](CHANGES.md)
[](https://javadoc.io/doc/com.diffplug.spotless/spotless-maven-plugin/3.10.4/index.html)




Spotless is a general-purpose formatting plugin used by [6,000 projects on GitHub (Jan 2023)](https://github.com/search?l=Maven+POM&q=spotless&type=Code).  It is completely à la carte, but also includes powerful "batteries-included" if you opt-in. Plugin requires a version of Maven higher or equal to 3.1.0.

To people who use your build, it looks like this:

```console
user@machine repo % mvn spotless:check
[ERROR]  > The following files had format violations:
[ERROR]  src\main\java\com\diffplug\gradle\spotless\FormatExtension.java
[ERROR]    -\t\t····if·(targets.length·==·0)·{
[ERROR]    +\t\tif·(targets.length·==·0)·{
[ERROR]  Run 'mvn spotless:apply' to fix these violations.
user@machine repo % mvn spotless:apply
[INFO] BUILD SUCCESS
user@machine repo % mvn spotless:check
[INFO] BUILD SUCCESS
```

### Table of Contents

- [**Quickstart**](#quickstart)
  - [Requirements](#requirements)
  - [Git hook (optional)](#git-hook)
  - [Binding to maven phase](#binding-to-maven-phase)
- **Languages**
  - [Java](#java) ([removeUnusedImports](#removeunusedimports), [forbidWildcardImports](#forbidwildcardimports), [expandWildcardImports](#expandwildcardimports), [forbidModuleImports](#forbidmoduleimports), [shortenFullyQualifiedTypes](#shortenfullyqualifiedtypes), [google-java-format](#google-java-format), [eclipse jdt](#eclipse-jdt), [prettier](#prettier), [palantir-java-format](#palantir-java-format), [prince-of-space](#prince-of-space), [formatAnnotations](#formatAnnotations), [cleanthat](#cleanthat), [tabletest-formatter](#tabletest-formatter), [IntelliJ IDEA](#intellij-idea))
  - [Groovy](#groovy) ([eclipse groovy](#eclipse-groovy))
  - [Kotlin](#kotlin) ([ktfmt](#ktfmt), [ktlint](#ktlint), [diktat](#diktat), [tabletest-formatter](#tabletest-formatter-1), [prettier](#prettier))
  - [Scala](#scala) ([scalafmt](#scalafmt))
  - [Asciidoc](#asciidoc) ([adocfmt](#adocfmt))
  - [C/C++](#cc) ([eclipse cdt](#eclipse-cdt), [clang-format](#clang-format))
  - [Python](#python) ([black](#black))
  - [Antlr4](#antlr4) ([antlr4formatter](#antlr4formatter))
  - [Sql](#sql) ([dbeaver](#dbeaver), [prettier](#prettier), [IntelliJ IDEA](#intellij-idea))
  - [Maven Pom](#maven-pom) ([sortPom](#sortpom))
  - [Markdown](#markdown) ([flexmark](#flexmark))
  - [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))
  - [YAML](#yaml)
  - [Gherkin](#gherkin)
  - [Go](#go)
  - [RDF](#RDF)
  - [Protobuf](#protobuf) ([buf](#buf), [clang-format](#clang))
  - Multiple languages
    - [Prettier](#prettier) ([plugins](#prettier-plugins), [npm detection](#npm-detection), [`.npmrc` detection](#npmrc-detection), [caching `npm install` results](#caching-results-of-npm-install))
    - [eclipse web tools platform](#eclipse-web-tools-platform)
    - [Biome](#biome) ([binary detection](#biome-binary), [config file](#biome-configuration-file), [input language](#biome-input-language))
    - [IntelliJ IDEA](#intellij-idea)
- **Language independent**
  - [Generic steps](#generic-steps)
  - [License header](#license-header) ([slurp year from git](#retroactively-slurp-years-from-git-history))
  - [How can I enforce formatting gradually? (aka "ratchet")](#ratchet)
  - [`spotless:off` and `spotless:on`](#spotlessoff-and-spotlesson)
  - [Line endings and encodings (invisible stuff)](#line-endings-and-encodings-invisible-stuff)
  - [Disabling warnings and error messages](#disabling-warnings-and-error-messages)
  - [How do I preview what `mvn spotless:apply` will do?](#how-do-i-preview-what-mvn-spotlessapply-will-do)
  - [Can I apply Spotless to specific files?](#can-i-apply-spotless-to-specific-files)
  - [How to centralize Spotless configuration](#central-configuration)
  - [Example configurations (from real-world projects)](#example-configurations-from-real-world-projects)

***Contributions are welcome, see [the contributing guide](../CONTRIBUTING.md) for development info.***

## Quickstart

To use it in your pom, just [add the Spotless plugin](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.diffplug.spotless%22%20AND%20a%3A%22spotless-maven-plugin%22), and configure it like so:

```xml
<plugin>
  <groupId>com.diffplug.spotless</groupId>
  <artifactId>spotless-maven-plugin</artifactId>
  <version>${spotless.version}</version>
  <configuration>
    
    <ratchetFrom>origin/main</ratchetFrom>
    <formats>
      
      <format>
        
        <includes>
          <include>.gitattributes</include>
          <include>.gitignore</include>
        </includes>
        
        <trimTrailingWhitespace/>
        <endWithNewline/>
        <indent>
          <tabs>true</tabs>
          <spacesPerTab>4</spacesPerTab>
        </indent>
      </format>
    </formats>
    
    <java>
      

      
      <googleJavaFormat>
        <version>1.8</version>
        <style>AOSP</style>
        <reflowLongStrings>true</reflowLongStrings>
        <formatJavadoc>false</formatJavadoc>
      </googleJavaFormat>

      
      <licenseHeader>
        <content>/* (C)$YEAR */</content>  
      </licenseHeader>
    </java>
  </configuration>
</plugin>
```

Spotless consists of a list of formats (in the example above, `misc` and `java`), and each format has:
- a `target` (the files to format), which you set with [`includes` and `excludes`](https://github.com/diffplug/spotless/blob/989abbecff4d8373c6111c1a98f359eadc532429/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java#L51-L55)
- a list of `FormatterStep`, which are just `String -> String` functions, such as [`replace`](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/Replace.java), [`replaceRegex`](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/ReplaceRegex.java), [`trimTrailingWhitespace`](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/TrimTrailingWhitespace.java), [`indent`](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/Indent.java), [`prettier`](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/Prettier.java), [`eclipseWtp`](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/EclipseWtp.java), and [`licenseHeader`](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/LicenseHeader.java).
- **order matters**, and this is good! (More info [here](https://github.com/diffplug/spotless/blob/main/PADDEDCELL.md) and [here](https://github.com/diffplug/spotless/blob/main/CONTRIBUTING.md#how-spotless-works))
  - For example, `googleJavaFormat` always indents with spaces, but some wish it had a tab mode
    - ```xml
      <googleJavaFormat/> // this works
      <indent><tabs>true</tabs><spacesPerTab>2</spacesPerTab></indent>
       ```
    - ```xml
      <indent><tabs>true</tabs><spacesPerTab>2</spacesPerTab></indent>
      <googleJavaFormat/> // the tab indentation gets overwritten
       ```

### Requirements

Spotless requires Maven to be running on JRE 17+. 

- If you're stuck on JRE 11, use [`2.46.1`](https://github.com/diffplug/spotless/blob/main/plugin-maven/CHANGES.md#2461---2025-07-21).
- If you're stuck on JRE 8, go back to [`2.30.0` or older](https://github.com/diffplug/spotless/blob/main/plugin-maven/CHANGES.md#2300---2023-01-13).

### Git hook

If you want, you can run `mvn spotless:install-git-pre-push-hook` and it will install a hook such that

1. When you push, it runs `spotless:check`
2. If formatting issues are found:
   - It automatically runs `spotless:apply` to fix them
   - Aborts the push with a message
   - You can then commit the changes and push again

This ensures your code is always clean before it leaves your machine.

If you prefer instead to have a "pre-commit" hook so that every single commit is clean, see [#623](https://github.com/diffplug/spotless/issues/623) for a workaround or to contribute a permanent fix.

### Binding to maven phase

By default, spotless:check is bound to verify maven phase. This means it is not required to
explicitly bind the plugin execution, and the following will suffice;

```xml
<executions>
  <execution>
    <goals>
      <goal>check</goal>
    </goals>
  </execution>
</executions>
```

with this `mvn verify` will run `spotless:check`. If you require the check goal to be run with
any other maven phase (i.e. compile) then it can be configured as below;

```xml
<executions>
  <execution>
    <goals>
      <goal>check</goal>
    </goals>
    <phase>compile</phase>
  </execution>
</executions>
```

<a name="applying-to-java-source"></a>

## Java

[code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java). [available steps](https://github.com/diffplug/spotless/tree/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/java).

```xml
<configuration>
  <java>
    
    <includes>
      <include>src/main/java/**/*.java</include>
      <include>src/test/java/**/*.java</include>
    </includes>

    
    <cleanthat />        

    <googleJavaFormat /> 
    <eclipse />          
    <prettier />         
    <idea />             

    <tableTestFormatter /> 

    <importOrder /> 
    <importOrder>  
      <wildcardsLast>false</wildcardsLast> 
      <order>java|javax,org,com,com.diffplug,,\#com.diffplug,\#</order>  
      
      <semanticSort>false</semanticSort> 
      <treatAsPackage> 
        <package>com.example.MyPackage</package>
      </treatAsPackage>
      <treatAsClass> 
        <class>com.example.myClass</class>
      </treatAsClass>
    </importOrder>

    <removeUnusedImports /> 
    <forbidWildcardImports /> 
    <forbidModuleImports /> 
    <shortenFullyQualifiedTypes /> 

    <formatAnnotations />  

    <licenseHeader>
      <content>/* (C)$YEAR */</content>  
    </licenseHeader>
  </java>
</configuration>
```

### removeUnusedImports

```xml
<removeUnusedImports>
  <engine>google-java-format</engine>    
</removeUnusedImports>
```

### forbidWildcardImports

```xml
<forbidWildcardImports/>
```

### expandWildcardImports

This step expands all wildcard imports to single class imports.
To do this, [JavaParser](https://javaparser.org/) is used to parse the complete sourcecode and resolve the full qualified name of all used classes and static methods from the full classpath.
This operation can be resource intensive when formatting many source files, so you may want to change to `forbidWildcardImports` when your codebase is cleaned and stable.

```xml
<expandWildcardImports/>
```

### forbidModuleImports

```xml
<forbidModuleImports/>
```

### shortenFullyQualifiedTypes

Replaces fully-qualified type names with their simple names, adding the imports they need. Useful for cleaning up generated code, or code where inline fully-qualified names have crept in.

[JavaParser](https://javaparser.org/) parses the source and only type positions in the AST are rewritten, so fully-qualified names appearing in strings, text blocks, and comments are left alone. Unlike [`expandWildcardImports`](#expandwildcardimports), it works from the source file alone and does not need your compile classpath.

New imports are appended after the existing ones, so run this before `<importOrder>`:

```xml
<shortenFullyQualifiedTypes/>
<importOrder/>
<removeUnusedImports/>
```

Before:

```java
package com.acme;

public class UserService {
  private final java.util.Map<String, java.util.List<String>> cache = new java.util.HashMap<>();

  public java.util.List<String> getUsers(java.util.function.Predicate<String> filter) throws java.io.IOException {
    return new java.util.ArrayList<>();
  }
}
```

After:

```java
package com.acme;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;

public class UserService {
  private final Map<String, List<String>> cache = new HashMap<>();

  public List<String> getUsers(Predicate<String> filter) throws IOException {
    return new ArrayList<>();
  }
}
```

A name is left fully-qualified whenever shortening it could change what the code means:

- two different fully-qualified names in the file would collapse to the same simple name (e.g. `java.util.List` and `java.awt.List`)
- an existing import already binds that simple name to a different type
- the file does not parse

Types in `java.lang` and in the file's own package are shortened without adding an import.

### google-java-format

[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).

```xml
<googleJavaFormat>
  <version>1.8</version>                      
  <style>GOOGLE</style>                       
  <reflowLongStrings>true</reflowLongStrings> 
  <formatJavadoc>false</formatJavadoc>        
  <reorderImports>false</reorderImports>.     
  
  <groupArtifact>com.google.googlejavaformat:google-java-format</groupArtifact>
</googleJavaFormat>
```

Note: when enabling `AOSP` style, `reorderImports` needs to be enabled to apply the correct import order from [the AOSP guidelines](https://source.android.com/docs/setup/contribute/code-style#order-import-statements).

### palantir-java-format

[homepage](https://github.com/palantir/palantir-java-format). [changelog](https://github.com/palantir/palantir-java-format/releases). [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/PalantirJavaFormat.java).

```xml
<palantirJavaFormat>
  <version>2.39.0</version>                     
  <style>PALANTIR</style>                       
  <formatJavadoc>false</formatJavadoc>          
</palantirJavaFormat>
```

### prince-of-space

[homepage](https://github.com/agustafson/prince-of-space). [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/PrinceOfSpace.java). Requires a JDK 17+ host runtime.

```xml
<princeOfSpace>
  <version>2.2.0</version>                      
  <indentStyle>SPACES</indentStyle>              
  <indentSize>4</indentSize>                     
  <lineLength>120</lineLength>                   
  <wrapStyle>BALANCED</wrapStyle>                
  <closingParenOnNewLine>true</closingParenOnNewLine>  
  <trailingCommas>false</trailingCommas>         
  <javaLanguageLevel>17</javaLanguageLevel>      
</princeOfSpace>
```

### eclipse jdt

[homepage](https://download.eclipse.org/eclipse/downloads/). [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Eclipse.java). See [here](../ECLIPSE_SCREENSHOTS.md) for screenshots that demonstrate how to get and install the config file mentioned below.

```xml
<eclipse>
  
  <version>4.26</version>
  
  <file>${project.basedir}/eclipse-formatter.xml</file>
  
  <p2Mirrors>
    <p2Mirror>
      <prefix>https://download.eclipse.org/eclipse/updates/4.26/</prefix>
      <url>https://some.internal.mirror/4-26-updates-p2/</url>
    </p2Mirror>
  </p2Mirrors>
</eclipse>
```

#### Sort Members

Not only can you format your code with Eclipse JDT, but you can also sort the members as you know it from Eclipse IDE.
This ensures that the methods are always in sorted order (and thus reduces the likelihood of collisions in a version
control system). It is turned off by default, but you might want to consider enabling it when setting coding standards
for a project.

The format to specify the sort order follows the `outlinesortoption` and `org.eclipse.jdt.ui.visibility.order`
properties that can be found in the workspace folder of your Eclipse IDE. You can look at the
file `.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs` in your workspace directory.

```xml
<eclipse>
  
  <sortMembersEnabled>true</sortMembersEnabled>
  
  <sortMembersOrder>SF,SI,SM,F,I,C,M,T</sortMembersOrder>
  
  <sortMembersDoNotSortFields>false</sortMembersDoNotSortFields>
  
  <sortMembersVisibilityOrderEnabled>true</sortMembersVisibilityOrderEnabled>
  
  <sortMembersVisibilityOrder>B,R,D,V</sortMembersVisibilityOrder>
</eclipse>
```

You can enable/disable the globally defined sort properties on file level by adding the following comments:
- `// @SortMembers:enabled=false` - disable the Sort Members feature for this file
- `// @SortMembers:doNotSortFields=true` - disable the sorting of static and instance fields
- `// @SortMembers:sortByVisibility=false` - don't sort members by its visibility modifier

### formatAnnotations

Type annotations should be on the same line as the type that they qualify.

```java
  @Override
  @Deprecated
  @Nullable @Interned String s;
```

However, some tools format them incorrectly, like this:

```java
  @Override
  @Deprecated
  @Nullable
  @Interned
  String s;
```

To fix the incorrect formatting, add the `formatAnnotations` rule after a Java formatter.  For example:

```XML
<googleJavaFormat />
<formatAnnotations />
```

This does not re-order annotations, it just removes incorrect newlines.

A type annotation is an annotation that is meta-annotated with `@Target({ElementType.TYPE_USE})`.
Because Spotless cannot necessarily examine the annotation definition, it uses a hard-coded
list of well-known type annotations.  You can make a pull request to add new ones.
In the future there will be mechanisms to add/remove annotations from the list.
These mechanisms already exist for the Gradle plugin.

### Cleanthat

[homepage](https://github.com/solven-eu/cleanthat). CleanThat enables automatic refactoring of Java code. [ChangeLog](https://github.com/solven-eu/cleanthat/blob/master/CHANGES.MD)

```xml
<cleanthat>
  <version>2.25</version>                         
  <javaparserVersion>3.26.4</javaparserVersion>   
  <sourceJdk>${maven.compiler.source}</sourceJdk> 
  <mutators>
    <mutator>SafeAndConsensual</mutator>          
  </mutators>
  <mutators>            
    <mutator>LiteralsFirstInComparisons</mutator> 
  </mutators>
  <excludedMutators>
    <excludedMutator>OptionalNotEmpty</excludedMutator> 
  </excludedMutators>
  <includeDraft>false</includeDraft>              
</cleanthat>
```

### tabletest-formatter

[homepage](https://github.com/nchaugen/tabletest-formatter). [changelog](https://github.com/nchaugen/tabletest-formatter/releases). [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/TableTestFormatter.java). Formats [`@TableTest`](https://github.com/nchaugen/tabletest) tables in Java source files. All configuration is read from `.editorconfig` files.

```xml
<tableTestFormatter>
  <version>1.1.2</version> 
</tableTestFormatter>
```

## Groovy

[code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/groovy/Groovy.java). [available steps](https://github.com/diffplug/spotless/tree/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/groovy).

```xml
<configuration>
  <groovy>
    
    <includes>
      <include>src/main/groovy/**/*.groovy</include>
      <include>src/test/groovy/**/*.groovy</include>
    </includes>

    <importOrder/> 
    <importOrder>  
      <order>java|javax,org,com,com.diffplug,,\#com.diffplug,\#</order>  
      
    </importOrder>
    
    <removeSemicolons/> 
    <greclipse/>          

    <excludeJava/>
    <licenseHeader>
      <content>/* (C)$YEAR */</content>  
    </licenseHeader>
  </groovy>
</configuration>
```

### eclipse groovy

[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.

```xml
<greclipse>
  <version>4.26</version>  
  <file>${project.basedir}/greclipse.properties</file> 
</greclipse>
```

Groovy-Eclipse formatting errors/warnings lead per default to a build failure. This behavior can be changed by adding the property/key value `ignoreFormatterProblems=true` to a configuration file. In this scenario, files causing problems, will not be modified by this formatter step.

<a name="applying-to-kotlin-source"></a>

## Kotlin

[code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/kotlin/Kotlin.java). [available steps](https://github.com/diffplug/spotless/tree/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/kotlin).

```xml
<configuration>
  <kotlin>
    
    <includes>
      <include>src/main/kotlin/**/*.kt</include>
      <include>src/test/kotlin/**/*.kt</include>
    </includes>

    <ktfmt />    
    <ktlint />   
    <diktat />   
    <prettier /> 

    <tableTestFormatter /> 

    <licenseHeader>
      <content>/* (C)$YEAR */</content>  
    </licenseHeader>
  </kotlin>
</configuration>
```

### ktfmt

[homepage](https://github.com/Kotlin/ktfmt). [changelog](https://github.com/Kotlin/ktfmt/releases). [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/kotlin/Ktfmt.java).

```xml
<ktfmt>
  <version>0.51</version> 
  <style>KOTLINLANG</style> 
  <maxWidth>120</maxWidth> 
  <blockIndent>4</blockIndent> 
  <continuationIndent>8</continuationIndent> 
  <removeUnusedImports>false</removeUnusedImports> 
  <trailingCommaManagementStrategy>COMPLETE</trailingCommaManagementStrategy> 
</ktfmt>
```

<a name="applying-ktlint-to-kotlin-files"></a>

### ktlint

[homepage](https://github.com/pinterest/ktlint). [changelog](https://github.com/pinterest/ktlint/releases).
[code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/kotlin/Ktlint.java).

Spotless respects the `.editorconfig` settings by providing `editorConfigPath` option.
([ktlint docs](https://github.com/pinterest/ktlint#editorconfig)).

Additionally, `editorConfigOverride` options will override what's supplied in `.editorconfig` file.

```xml
<ktlint>
  <version>1.0.0</version> 
  <editorConfigOverride> 
    <ij_kotlin_allow_trailing_comma>true</ij_kotlin_allow_trailing_comma>
    <ij_kotlin_allow_trailing_comma_on_call_site>true</ij_kotlin_allow_trailing_comma_on_call_site>
    
    <ktlint_code_style>intellij_idea</ktlint_code_style>
  </editorConfigOverride>
  <customRuleSets> 
    <value>io.nlopez.compose.rules:ktlint:0.4.25</value>
  </customRuleSets>
</ktlint>
```

### diktat

[homepage](https://github.com/cqfn/diKTat). [changelog](https://github.com/cqfn/diKTat/releases). [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/kotlin/Diktat.java). You can provide configuration path manually as `configFile`.

```xml
<diktat>
  <version>1.0.1</version> 
  <configFile>full/path/to/diktat-analysis.yml</configFile> 
</diktat>
```

### tabletest-formatter

[homepage](https://github.com/nchaugen/tabletest-formatter). [changelog](https://github.com/nchaugen/tabletest-formatter/releases). [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/kotlin/TableTestFormatter.java). Formats [`@TableTest`](https://github.com/nchaugen/tabletest) tables in Kotlin source files. All configuration is read from `.editorconfig` files.

```xml
<tableTestFormatter>
  <version>1.1.2</version> 
</tableTestFormatter>
```

<a name="applying-to-scala-source"></a>

## Scala

[code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/scala/Scala.java). [available steps](https://github.com/diffplug/spotless/tree/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/scala).

```xml
<configuration>
  <scala>
    
    <includes>
      <include>src/main/scala/**/*.scala</include>
      <include>src/test/scala/**/*.scala</include>
      <include>src/main/scala/**/*.sc</include>
      <include>src/test/scala/**/*.sc</include>
    </includes>

    <scalafmt /> 

    <licenseHeader>
      <content>/* (C)$YEAR */</content>  
      <delimiter>package </delimiter> 
    </licenseHeader>
  </scala>
</configuration>
```

### scalafmt

[homepage](https://scalameta.org/scalafmt/). [changelog](https://github.com/scalameta/scalafmt/releases). [config docs](https://scalameta.org/scalafmt/docs/configuration.html). [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/scala/Scalafmt.java).

```xml
<scalafmt>
  <version>3.5.9</version>              
  <file>${project.basedir}/scalafmt.conf</file> 
  <scalaMajorVersion>2.13</scalaMajorVersion> 
</scalafmt>
```

<a name="cpp"></a>

<a name="applying-to-cc-source"></a>

## C/C++

[code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/cpp/Cpp.java). [available steps](https://github.com/diffplug/spotless/tree/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/cpp).

```xml
<configuration>
  <cpp>
    <includes> 
      <include>src/native/**</include>
    </includes>

    <eclipseCdt /> 

    <licenseHeader>
      <content>/* (C)$YEAR */</content>  
    </licenseHeader>
  </cpp>
</configuration>
```

### eclipse cdt

[homepage](https://www.eclipse.org/cdt/). [compatible versions](https://github.com/diffplug/spotless/tree/main/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_cdt_formatter). [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/cpp/EclipseCdt.java).

```xml
<eclipseCdt>
  <version>11.0</version> 
  <file>${project.basedir}/eclipse-cdt.xml</file> 
</eclipseCdt>
```

### clang-format

[homepage](https://clang.llvm.org/docs/ClangFormat.html). [changelog](https://releases.llvm.org/download.html). `clang-format` is a formatter for c, c++, c#, objective-c, protobuf, javascript, and java. You can use clang-format in any language-specific format, but usually you will be creating a generic format.

```xml
<clangFormat>
  <version>14.0.0-1ubuntu1.1</version> 
  <pathToExe>/path/to/buf</pathToExe>  
  <style>LLVM</style>  
</clangFormat>
```

## Python

[code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/python/Python.java). [available steps](https://github.com/diffplug/spotless/tree/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/python/Black.java).

```xml
<configuration>
  <python>
    
    <includes>
      <include>src/main/**/*.py</include>
    </includes>

    <black />  
  </python>
</configuration>
```

### black

[homepage](https://github.com/psf/black). [changelog](https://github.com/psf/black/blob/master/CHANGES.md).

```xml
<black>
  <version>19.10b0</version> 
  
  <pathToExe>C:/myuser/.pyenv/versions/3.8.0/scripts/black.exe</pathToExe>
  
</black>
```

## Antlr4

[code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/antlr4/Antlr4.java). [available steps](https://github.com/diffplug/spotless/tree/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/antlr4).

```xml
<configuration>
  <antlr4>
    
    <includes>
      <include>src/*/antlr4/**/*.g4</include>
    </includes>

    <antlr4Formatter /> 

    <licenseHeader>
      <content>/* (C)$YEAR */</content>  
    </licenseHeader>
  </antlr4>
</configuration>
```

### antlr4Formatter

[homepage](https://github.com/antlr/Antlr4Formatter). [available versions](https://search.maven.org/artifact/com.khubla.antlr4formatter/antlr4-formatter). [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/antlr4/Antlr4Formatter.java).

```xml
<antlr4Formatter>
  <version>1.2.1</version> 
</antlr4Formatter>
```

## Asciidoc

[code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/asciidoc/Asciidoc.java). [available steps](https://github.com/diffplug/spotless/tree/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/asciidoc).

```xml
<configuration>
  <asciidoc>
    <includes> 
      <include>src/docs/**/*.adoc</include>
    </includes>

    <adocfmt /> 
  </asciidoc>
</configuration>
```

### adocfmt

[homepage](https://github.com/dheid/adocfmt). [available versions](https://search.maven.org/artifact/org.drjekyll/adocfmt). [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/asciidoc/Adocfmt.java).

```xml
<adocfmt>
  <version>0.3.1</version> 
  <normalizeSetextHeadings>true</normalizeSetextHeadings>       
  <collapseConsecutiveBlankLines>true</collapseConsecutiveBlankLines> 
  <oneSentencePerLine>true</oneSentencePerLine>            
  <normalizeBlockDelimiters>true</normalizeBlockDelimiters>      
  <removeTrailingHeaderEqualsSign>true</removeTrailingHeaderEqualsSign> 
  <titleCase>false</titleCase>                     
  <removeTrailingWhitespace>true</removeTrailingWhitespace>      
  <normalizeListBullets>false</normalizeListBullets>          
  <normalizeOrderedListMarkers>false</normalizeOrderedListMarkers>   
  <ensureHeadingBlankLines>true</ensureHeadingBlankLines>       
  <ensureSourceDelimiters>false</ensureSourceDelimiters>        
  <formatTables>true</formatTables>                  
  <tableLayout>AUTO</tableLayout>                   
  <tableMaxLineWidth>120</tableMaxLineWidth>         
  <tableBlankLines>ALL</tableBlankLines>             
</adocfmt>
```

Options default to `true` or `false` as shown above. This formatter is opinionated and designed to help you maintain a clean, consistent AsciiDoc structure. For example, `<oneSentencePerLine>` is a highly recommended practice in the AsciiDoc community for better version control diffs.

## SQL

[code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/sql/Sql.java). [available steps](https://github.com/diffplug/spotless/tree/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/sql).

```xml
<configuration>
  <sql>
    
    <includes>
      <include>src/main/resources/**/*.sql</include>
    </includes>

    <dbeaver />  
    <prettier /> 
    <idea />     
  </sql>
</configuration>
```

### dbeaver

[homepage](https://dbeaver.io/). DBeaver is only distributed as a monolithic jar, so the formatter used here was copy-pasted into Spotless, and thus there is no version to change.

```xml
<dbeaver>
    <configFile>dbeaver.properties</configFile> 
</dbeaver>
```

Default configuration file, other options [available here](https://github.com/diffplug/spotless/blob/main/lib/src/main/java/com/diffplug/spotless/sql/dbeaver/DBeaverSQLFormatterConfiguration.java).

```properties
# case of the keywords (UPPER, LOWER or ORIGINAL)
sql.formatter.keyword.case=UPPER
# Statement delimiter
sql.formatter.statement.delimiter=;
# Indentation style (space or tab)
sql.formatter.indent.type=space
# Number of identation characters
sql.formatter.indent.size=4
```

## Maven POM

[code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/pom/Pom.java). [available steps](https://github.com/diffplug/spotless/tree/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/pom/SortPom.java).

```xml
<configuration>
  <pom>
    
    <includes>
      <include>pom.xml</include>
    </includes>

    <sortPom /> 

  </pom>
</configuration>
```

### sortPom

[homepage](https://github.com/Ekryd/sortpom). [code](https://github.com/diffplug/spotless/tree/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/pom/SortPom.java).

All configuration settings are optional, they are described in detail [here](https://github.com/Ekryd/sortpom/wiki/Parameters).

```xml
<sortPom>

  <encoding>UTF-8</encoding> 

  <lineSeparator>${line.separator}</lineSeparator> 

  <expandEmptyElements>true</expandEmptyElements> 

  <spaceBeforeCloseEmptyElement>false</spaceBeforeCloseEmptyElement> 

  <keepBlankLines>true</keepBlankLines> 

  <endWithNewline>true</endWithNewline> 

  <nrOfIndentSpace>2</nrOfIndentSpace> 

  <indentBlankLines>false</indentBlankLines> 

  <indentSchemaLocation>false</indentSchemaLocation> 

  <indentAttribute></indentAttribute> 

  <predefinedSortOrder>recommended_2008_06</predefinedSortOrder> 

  <sortOrderFile></sortOrderFile> 

  <sortDependencies></sortDependencies> 

  <sortDependencyManagement></sortDependencyManagement> 

  <sortDependencyExclusions></sortDependencyExclusions> 

  <sortPlugins></sortPlugins> 

  <sortProperties>false</sortProperties> 

  <sortModules>false</sortModules> 

  <sortExecutions>false</sortExecutions> 
</sortPom>
```

## Markdown

[code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/markdown/Markdown.java). [available steps](https://github.com/diffplug/spotless/tree/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/markdown).

```xml
<configuration>
  <markdown>
    <includes> 
      <include>**/*.md</include>
    </includes>

    <flexmark/> 
  </markdown>
</configuration>
```

### Flexmark

[homepage](https://github.com/vsch/flexmark-java). [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/markdown/Flexmark.java). Flexmark is a flexible Commonmark/Markdown parser that can be used to format Markdown files. It supports different [flavors of Markdown](https://github.com/vsch/flexmark-java#markdown-processor-emulation) and [many formatting options](https://github.com/vsch/flexmark-java/wiki/Markdown-Formatter#options).

The default configuration uses a pegdown compatible parser with `COMMONMARK` as `FORMATTER_EMULATION_PROFILE`.
You can change the `emulationProfile` to one of the other [supported profiles](https://github.com/vsch/flexmark-java/blob/master/flexmark/src/main/java/com/vladsch/flexmark/parser/ParserEmulationProfile.java).
The `pegdownExtensions` can be configured as a comma-seperated list of [constants](https://github.com/vsch/flexmark-java/blob/master/flexmark/src/main/java/com/vladsch/flexmark/parser/PegdownExtensions.java) or as a custom bitset as an integer.
Any other `extension` can be configured using either the simple name as shown in the example or using a full-qualified class name.

Arbitrary formatter options from the [flexmark-java Markdown Formatter](https://github.com/vsch/flexmark-java/wiki/Markdown-Formatter#options) can be set via `formatterOptions`. Each key is a camelCase version of the corresponding `SCREAMING_SNAKE_CASE` constant on [`com.vladsch.flexmark.formatter.Formatter`](https://github.com/vsch/flexmark-java/blob/master/flexmark/src/main/java/com/vladsch/flexmark/formatter/Formatter.java) (e.g. `rightMargin` maps to `Formatter.RIGHT_MARGIN`). Supported value types are `Integer`, `Boolean`, and `String`.

```xml
<flexmark>
  <emulationProfile>COMMONMARK</emulationProfile>
  <pegdownExtensions>ALL,TOC</pegdownExtensions>
  <extensions>YamlFrontMatter,Emoji</extensions>
  <formatterOptions>
    <rightMargin>120</rightMargin>
  </formatterOptions>
</flexmark>
```

<a name="applying-to-typescript-source"></a>

## Typescript

[code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/typescript/Typescript.java). [available steps](https://github.com/diffplug/spotless/tree/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/typescript).

```xml
<configuration>
  <typescript>
    <includes> 
      <include>src/**/*.ts</include>
    </includes>

    <tsfmt/>    
    <prettier/> 
    <eslint/>   
    <biome/>    

    <licenseHeader>
      <content>/* (C)$YEAR */</content>  
      <delimiter>(import|const|declare|export|var) </delimiter> 
    </licenseHeader>
  </typescript>
</configuration>
```

### tsfmt

[npm](https://www.npmjs.com/package/typescript-formatter). [changelog](https://github.com/vvakame/typescript-formatter/blob/master/CHANGELOG.md). [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/typescript/Tsfmt.java). *Please note:*
The auto-discovery of config files (up the file tree) will not work when using tsfmt within spotless,
  hence you are required to provide resolvable file paths for config files, or alternatively provide the configuration inline. See [tsfmt's default config settings](https://github.com/vvakame/typescript-formatter/blob/7764258ad42ac65071399840d1b8701868510ca7/lib/utils.ts#L11L32) for what is available.

```xml
<tsfmt>
  <typescriptFormatterVersion>7.2.2</typescriptFormatterVersion> 
  <typescriptVersion>3.9.5</typescriptVersion> 
  <tslintVersion>6.1.2</tslintVersion> 

  <config> 
    <indentSize>1</indentSize>
    <convertTabsToSpaces>true</convertTabsToSpaces>
  </config>
  
  <tsconfigFile>${project.basedir}/tsconfig.json</tsconfigFile>
  <tslintFile>${project.basedir}/tslint.json</tslintFile>
  <vscodeFile>${project.basedir}/vscode.json</vscodeFile>
  <tsfmtFile>${project.basedir}/tsfmt.json</tsfmtFile>
</tsfmt>
```

**Prerequisite: tsfmt requires a working NodeJS version**

For details, see the [npm detection](#npm-detection), [`.npmrc` detection](#npmrc-detection) and [caching results of `npm install`](#caching-results-of-npm-install) sections of prettier, which apply also to tsfmt.

### ESLint (typescript)

[npm](https://www.npmjs.com/package/eslint). [changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md). *Please note:*
The auto-discovery of config files (up the file tree) will not work when using ESLint within spotless,
hence you are required to provide resolvable file paths for config files, or alternatively provide the configuration inline.

The configuration is very similar to the [ESLint (Javascript)](#eslint-javascript) configuration. In typescript, a
reference to a `tsconfig.json` is required.

```xml
<eslint>
  
  <eslintVersion>8.30.0</eslintVersion>
  <devDependencies>
    <myEslintFork>8.30.0</myEslintFork>
    <myEslintPlugin>1.2.1</myEslintPlugin>
  </devDependencies>
  <devDependencyProperties>
    <property>
      <name>eslint</name>
      <value>8.30.0</value>
    </property>
    <property>
      <name>@eslint/my-plugin-typescript</name> 
      <value>0.14.2</value>
    </property>
  </devDependencyProperties>
  
  <configFile>${project.basedir}/.eslintrc.js</configFile>
  <configJs>
    {
      env: {
        browser: true,
        es2021: true
      },
      extends: 'standard-with-typescript',
      overrides: [
      ],
      parserOptions: {
        ecmaVersion: 'latest',
        sourceType: 'module',
        project: './tsconfig.json',
      },
      rules: {
      }
    }
  </configJs>
  
  <tsconfigFile>${project.basedir}/tsconfig.json</tsconfigFile>
</eslint>
```

**Prerequisite: ESLint requires a working NodeJS version**

For details, see the [npm detection](#npm-detection), [`.npmrc` detection](#npmrc-detection) and [caching results of `npm install`](#caching-results-of-npm-install) sections of prettier, which apply also to ESLint.


## Javascript

[code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/javascript/Javascript.java). [available steps](https://github.com/diffplug/spotless/tree/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/javascript).

```xml
<configuration>
  <typescript>
    <includes> 
      <include>src/**/*.js</include>
    </includes>

    <prettier/> 
    <eslint/>   
    <biome/>    

    <licenseHeader>
      <content>/* (C)$YEAR */</content>  
      <delimiter>REGEX_TO_DEFINE_TOP_OF_FILE</delimiter> 
    </licenseHeader>
  </typescript>
</configuration>
```

### ESLint (Javascript)

[npm](https://www.npmjs.com/package/eslint). [changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md). *Please note:*
The auto-discovery of config files (up the file tree) will not work when using ESLint within spotless,
hence you are required to provide resolvable file paths for config files, or alternatively provide the configuration inline.

The configuration is very similar to the [ESLint (Typescript)](#eslint-typescript) configuration. In javascript, *no*
`tsconfig.json` is supported.

```xml
<eslint>
  
  <eslintVersion>8.30.0</eslintVersion>
  <devDependencies>
    <myEslintFork>8.30.0</myEslintFork>
    <myEslintPlugin>1.2.1</myEslintPlugin>
  </devDependencies>
  <devDependencyProperties>
    <property>
      <name>eslint</name>
      <value>8.30.0</value>
    </property>
    <property>
      <name>@eslint/my-plugin-javascript</name> 
      <value>0.14.2</value>
    </property>
  </devDependencyProperties>
  
  <configFile>${project.basedir}/.eslintrc.js</configFile>
  <configJs>
    {
      env: {
        browser: true,
        es2021: true
      },
      extends: 'standard',
      overrides: [
      ],
      parserOptions: {
        ecmaVersion: 'latest',
        sourceType: 'module'
      },
      rules: {
      }
    }
  </configJs>
</eslint>
```

**Prerequisite: ESLint requires a working NodeJS version**

For details, see the [npm detection](#npm-detection), [`.npmrc` detection](#npmrc-detection) and [caching results of `npm install`](#caching-results-of-npm-install) sections of prettier, which apply also to ESLint.

## JSON

- `com.diffplug.spotless.maven.json.Json` [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/json/Json.java)

```xml
<configuration>
  <json>
    <includes>    
      <include>src/**/*.json</include>
    </includes>

    <simple />         
    <gson />           
    <jackson />        
    <biome />          
    <jsonPatch />      
  </json>
</configuration>
```

### simple

Uses a JSON pretty-printer that optionally allows configuring the number of spaces that are used to pretty print objects:

```xml
<simple>
  <indentSpaces>4</indentSpaces>    
</simple>
```

### Gson

Uses Google Gson to also allow sorting by keys besides custom indentation - useful for i18n files.

```xml
<gson>
  <indentSpaces>4</indentSpaces>        
  <sortByKeys>false</sortByKeys>        
  <escapeHtml>false</escapeHtml>      
  <version>2.8.1</version>              
</gson>
```

Notes:
* There's no option in Gson to leave HTML as-is (i.e. escaped HTML would remain escaped, raw would remain raw). Either
all HTML characters are written escaped or none. Set `escapeHtml` if you prefer the former.
* `sortByKeys` will apply lexicographic order on the keys of the input JSON. See the
[javadoc of String](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#compareTo(java.lang.String))
for details.

### Jackson

Uses Jackson for formatting.

```xml
<jackson>
  <version>2.14.1</version>    
  <features>                   
    <INDENT_OUTPUT>true</INDENT_OUTPUT>                            
    <ORDER_MAP_ENTRIES_BY_KEYS>false</ORDER_MAP_ENTRIES_BY_KEYS>   
    <ANY_OTHER_FEATURE>true|false</ANY_OTHER_FEATURE>              
  </features>
  <jsonFeatures>
    <QUOTE_FIELD_NAMES>false</QUOTE_FIELD_NAMES>                   
    <ANY_OTHER_FEATURE>true|false</ANY_OTHER_FEATURE>              
  </jsonFeatures>
  <spaceBeforeSeparator>false</spaceBeforeSeparator>               
</jackson>
```

<a name="applying-prettier-to-javascript--flow--typescript--css--scss--less--jsx--graphql--yaml--etc"></a>

### jsonPatch

Uses [zjsonpatch](https://github.com/flipkart-incubator/zjsonpatch) to apply [JSON Patches](https://jsonpatch.com/) as per [RFC 6902](https://datatracker.ietf.org/doc/html/rfc6902/) to JSON documents.

This enables you to add, replace or remove properties at locations in the JSON document that you specify using [JSON Pointers](https://datatracker.ietf.org/doc/html/rfc6901/).

For example, to apply the patch from the [JSON Patch homepage](https://jsonpatch.com/#the-patch):

```xml
<jsonPatch>[
  { "op": "replace", "path": "/baz", "value": "boo" },
  { "op": "add", "path": "/hello", "value": ["world"] },
  { "op": "remove", "path": "/foo" }
]</jsonPatch>
```

## YAML

- `com.diffplug.spotless.maven.FormatterFactory.addStepFactory(FormatterStepFactory)` [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/yaml/Yaml.java)

```xml
<configuration>
  <yaml>
    <includes>     
      <include>src/**/*.yaml</include>
    </includes>

    <jackson />    
    <prettier />   
  </yaml>
</configuration>
```

### jackson

Uses Jackson and YAMLFactory to pretty print objects:

```xml
<jackson>
  <version>2.14.1</version>    
  <features>                   
    <INDENT_OUTPUT>true</INDENT_OUTPUT>                            
    <ORDER_MAP_ENTRIES_BY_KEYS>false</ORDER_MAP_ENTRIES_BY_KEYS>   
    <ANY_OTHER_FEATURE>true|false</ANY_OTHER_FEATURE>              
  </features>
  <yamlFeatures>
    <WRITE_DOC_START_MARKER>true</WRITE_DOC_START_MARKER>          
    <MINIMIZE_QUOTES>false</MINIMIZE_QUOTES>                       
    <ANY_OTHER_FEATURE>true|false</ANY_OTHER_FEATURE>              
  </yamlFeatures>
  <spaceBeforeSeparator>false</spaceBeforeSeparator>   
</jackson>
```

## Shell

- `com.diffplug.spotless.maven.FormatterFactory.addStepFactory(FormatterStepFactory)` [code](./src/main/java/com/diffplug/spotless/maven/shell/Shell.java)

```xml
<configuration>
  <shell>
    <includes>     
      <include>scripts/**/*.sh</include>
    </includes>
    
    <shfmt />    
  </shell>
</configuration>
```

### shfmt

[homepage](https://github.com/mvdan/sh). [changelog](https://github.com/mvdan/sh/blob/master/CHANGELOG.md).

When formatting shell scripts via `shfmt`, configure `shfmt` settings via `.editorconfig`.

```xml
<shfmt>
  <version>3.8.0</version>                         
  <pathToExe>/opt/homebrew/bin/shfmt</pathToExe>   
</shfmt>
```

## TableTest

[code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/tabletest/TableTest.java). [available steps](https://github.com/diffplug/spotless/tree/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/tabletest).

```xml
<configuration>
  <tableTest>
    <includes>
      <include>src/**/*.table</include>
    </includes>
    <tableTestFormatter>
      <version>1.1.2</version> 
    </tableTestFormatter>
  </tableTest>
</configuration>
```

[homepage](https://github.com/nchaugen/tabletest-formatter). [changelog](https://github.com/nchaugen/tabletest-formatter/releases). Formats standalone [TableTest](https://github.com/nchaugen/tabletest) `.table` files.

## Gherkin

- `com.diffplug.spotless.maven.FormatterFactory.addStepFactory(FormatterStepFactory)` [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/gherkin/Gherkin.java)

```xml
<configuration>
  <gherkin>
    <includes>     
      <include>src/**/*.feature</include>
    </includes>

    <gherkinUtils />    
  </gherkin>
</configuration>
```

### gherkinUtils

[homepage](https://github.com/cucumber/gherkin-utils). [changelog](https://github.com/cucumber/gherkin-utils/blob/main/CHANGELOG.md).

Uses a Gherkin pretty-printer that optionally allows configuring the number of spaces that are used to pretty print objects:

```xml
<gherkinUtils>
  <version>9.0.0</version>                 
</gherkinUtils>
```

## Go

- `com.diffplug.spotless.maven.FormatterFactory.addStepFactory(FormatterStepFactory)` [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/go/Go.java)

```xml
<configuration>
  <go>
    <includes>     
      <include>src/**/*.go</include>
    </includes>

    <gofmt />    
  </go>
</configuration>
```

### gofmt

Standard Go formatter, part of Go distribution.

```xml
<gofmt>
  <version>go1.25.1</version>                 
  <goExecutablePath>/opt/sdks/go1.25.1/bin/go</goExecutablePath>
</gofmt>
```

## RDF

### Generic Options

List of generic configuration `parameters (type/default)` 

* `failOnWarning (boolean/true)`: The Jena parser produces three levels of problem reports: warning, error, and fatal. By default, 
the build fails for any of them. You can ignore warnings using this parameter. They will still be logged in the plugin's 
output.
* `verify (boolean/true)`: If `true`, the content before and after formatting is parsed to an RDF model and compared for isomorphicity.   
* `turtleFormatterVersion (string|RdfFormatterStep.LATEST_TURTLE_FORMATTER_VERSION)`: the version of Cool RDF Formatter to use (see below).

### Supported RDF formats: only TTL (at the moment)

Formatting TTL is done using [Cool RDF Formatter](https://github.com/cool-rdf/cool-rdf/tree/main/cool-rdf-formatter),
which is highly configurable (have a look at the [Style Documentation](https://github.com/cool-rdf/cool-rdf/tree/main/cool-rdf-formatter))
and will handle blank nodes the way you'd hope.

The style options can be configured via spotless. Wherever the style wants a URI (for example, for the `predicateOrder`, you can
use the abbreviated form if it is a known `RdfPrefix` from Cool RDF's `Prefixes` enum.
Error messages will give you hints. To configure the TTL formatting style, pass the configuration parameters under `<turtle>`.
For example, Cool RDF Formatter versions which support `preserveBlankNodeLabelsAndOrdering` (default true) can set it with
`<preserveBlankNodeLabelsAndOrdering>false</preserveBlankNodeLabelsAndOrdering>`.Set it to `false`, to use Cool RDF's default behavior (stable blank node ordering).

### Examples
Minimal:
```xml
<configuration>
  <rdf>
    <includes>
      <include>**/*.ttl</include>
    </includes>
    <format/>
  </rdf>
</configuration>
```
Configuring some generic and TTL options:
```xml
<configuration>
  <rdf>
    <includes>
      <include>**/*.ttl</include>
    </includes>
    <format>
      <failOnWarning>false</failOnWarning>
      <verify>false</verify>
      <turtleFormatterVersion>2.0.0</turtleFormatterVersion>
      <turtle>
        <alignPrefixes>RIGHT</alignPrefixes>
        <enableDoubleFormatting>true</enableDoubleFormatting>
        <preserveBlankNodeLabelsAndOrdering>false</preserveBlankNodeLabelsAndOrdering>
      </turtle>
    </format>
  </rdf>
</configuration>
```
### Libraries and versions

RDF parsing is done via [Apache Jena](https://jena.apache.org/) in the version that
[Cool RDF Formatter](https://github.com/cool-rdf/cool-rdf/tree/main/cool-rdf-formatter) depends on (not necessarily the latest).

## Protobuf

[code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/protobuf/Protobuf.java). [available steps](https://github.com/diffplug/spotless/tree/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/protobuf).
```xml
<configuration>
  <includes>  
    <include>proto/*.proto</include>
  </includes>

  <excludes>  
    <exclude>target/**/<exclude>
  </excludes>
  
  <protobuf>
    <buf />  
  </protobuf>
</configuration>
```

### buf

[homepage](https://buf.build/) [buf repo](https://github.com/bufbuild/buf).
```xml
 <buf>
    <version>1.44.0</version>    
    <pathToExe>/path/to/buf</pathToExe>  
 </buf>        
```


## CSS

[code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/css/Css.java). [available steps](https://github.com/diffplug/spotless/tree/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/css).

```xml
<configuration>
  <css>
    
    <includes>
      <include>src/main/css/**/*.css</include>
      <include>src/test/css/**/*.css</include>
    </includes>

    <biome />          

    <licenseHeader>
      <content>/* (C)$YEAR */</content>  
    </licenseHeader>
  </css>
</configuration>
```

Note regarding biome: Biome supports formatting CSS as of 1.8.0 (experimental, opt-in) and 1.9.0 (stable).

## Prettier

[homepage](https://prettier.io/). [changelog](https://github.com/prettier/prettier/blob/master/CHANGELOG.md). [official plugins](https://prettier.io/docs/en/plugins.html#official-plugins). [community plugins](https://prettier.io/docs/en/plugins.html#community-plugins). Prettier is a formatter that can format almost every anything - JavaScript, JSX, Angular, Vue, Flow, TypeScript, CSS, Less, SCSS, HTML, JSON, GraphQL, Markdown (including GFM and MDX), and YAML.  It can format even more [using plugins](https://prettier.io/docs/en/plugins.html) (PHP, Ruby, Swift, XML, Apex, Elm, Java (!!), Kotlin, pgSQL, .properties, solidity, svelte, toml, shellscript, ...).

You can use prettier in any language-specific format, but usually you will be creating a generic format.

```xml
<configuration>
  <formats>
    <format>
      <includes>
        <include>src/**/typescript/**/*.ts</include>
      </includes>

      <prettier>
        
        <prettierVersion>1.19.0</prettierVersion>
        <devDependencies>
            <prettier>1.19.0</prettier>
        </devDependencies>
        <devDependencyProperties>
          <property>
            <name>prettier</name>
            <value>2.8.8</value>
          </property>
          <property>
            <name>@prettier/plugin-php</name> 
            <value>0.19.6</value>
          </property>
        </devDependencyProperties>
        
        <configFile>${project.basedir}/path/to/configfile</configFile>
        <config>
            <useTabs>true</useTabs>
            
            <plugins>@prettier/plugin-php</plugins>
        </config>
      </prettier>
    </format>

  </formats>
</configuration>
```

**Limitations:**
- The auto-discovery of config files (up the file tree) will not work when using prettier within spotless.
- Prettier's override syntax is not supported when using prettier within spotless.

To apply prettier to more kinds of files, just add more formats

```xml
<configuration>
  <formats>
    <format><includes>src/**/*.ts</includes><prettier/></format>
    <format><includes>src/**/*.css</includes><prettier/></format>
```

<a name="using-plugins-for-prettier"></a>

### prettier plugins

Since spotless uses the actual npm prettier package behind the scenes, it is possible to use prettier with
[plugins](https://prettier.io/docs/en/plugins.html#official-plugins) or [community-plugins](https://www.npmjs.com/search?q=prettier-plugin) in order to support even more file types.

```xml
<configuration>
  <formats>
    
    <format>
      <includes>
        <include>src/*/java/**/*.java</include>
      </includes>

      <prettier>
        <devDependencies>
            <prettier>2.8.8</prettier>
            <prettier-plugin-java>2.2.0</prettier-plugin-java>
        </devDependencies>
        <config>
            <tabWidth>4</tabWidth>
            <parser>java</parser>
            <plugins>prettier-plugin-java</plugins>
        </config>
      </prettier>
    </format>

    
    <format>
      <includes>
        <include>src/**/*.php</include>
      </includes>

      <prettier>
        
        <devDependencyProperties>
          <property>
            <name>prettier</name>
            <value>2.8.8</value>
          </property>
          <property>
            <name>@prettier/plugin-php</name>
            <value>0.19.6</value>
          </property>
        </devDependencyProperties>
        <config>
            <tabWidth>3</tabWidth>
            <parser>php</parser>
            <plugins>@prettier/plugin-php</plugins>
        </config>
      </prettier>
    </format>

  </formats>
</configuration>
```

### npm detection

Prettier is based on NodeJS, so to use it, a working NodeJS installation (especially npm) is required on the host running spotless.
Spotless will try to auto-discover an npm installation. If that is not working for you, it is possible to directly configure the npm
and/or node binary to use.

```xml
<prettier>
  <npmExecutable>/usr/bin/npm</npmExecutable>
  <nodeExecutable>/usr/bin/node</nodeExecutable>
```

If you provide both `npmExecutable` and `nodeExecutable`, spotless will use these paths. If you specify only one of the
two, spotless will assume the other one is in the same directory.

### `.npmrc` detection

Spotless picks up npm configuration stored in a `.npmrc` file either in the project directory or in your user home.
Alternatively you can supply spotless with a location of the `.npmrc` file to use. (This can be combined with
`npmExecutable` and `nodeExecutable`, of course.)

```xml
<prettier>
  <npmrc>/usr/local/shared/.npmrc</npmrc>
```

### Caching results of `npm install`

Spotless uses `npm` behind the scenes to install `prettier`. This can be a slow process, especially if you are using a slow internet connection or
if you need large plugins. You can instruct spotless to cache the results of the `npm install` calls, so that for the next installation,
it will not need to download the packages again, but instead reuse the cached version.

```xml
<prettier>
  <npmInstallCache>true</npmInstallCache> 
  <npmInstallCache>/usr/local/shared/.spotless-npm-install-cache</npmInstallCache> 
```

Depending on your filesystem and the location of the cache directory, spotless will use hardlinks when caching the npm packages. If that is not
possible, it will fall back to copying the files.

<a name="applying-eclipse-wtp-to-css--html--etc"></a>

## Eclipse web tools platform

[changelog](https://www.eclipse.org/webtools/). [compatible versions](https://github.com/diffplug/spotless/tree/main/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_wtp_formatter).

```xml
<configuration>
  <formats>
    <format>
      <includes>
        <include>src/**/resources/**/*.xml</include>
        <include>src/**/resources/**/*.xsd</include>
      </includes>

      <eclipseWtp>
        <type>XML</type> 
        <files> 
          <file>${project.basedir}/xml.prefs</file>
          <file>${project.basedir}/additional.properties</file>
        </files>
        <version>4.21.0</version> 
      </eclipseWtp>
    </format>
  </formats>
</configuration>
```

The WTP formatter accept multiple configuration files. All Eclipse configuration file formats are accepted as well as simple Java property files. Omit the `<files>` entirely to use the default Eclipse configuration. The following formatters and configurations are supported:

| Type | Configuration       | File location
| ---- | ------------------- | -------------
| CSS  | editor preferences  | .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.css.core.prefs
|      | cleanup preferences | .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.css.core.prefs
| HTML | editor preferences  | .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.html.core.prefs
|      | cleanup preferences | .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.html.core.prefs
|      | embedded CSS        | .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.css.core.prefs
|      | embedded JS         | Use the export in the Eclipse editor configuration dialog
| JS   | editor preferences  | Use the export in the Eclipse editor configuration dialog
| JSON | editor preferences  | .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.json.core.prefs
| XML  | editor preferences  | .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.xml.core.prefs

Note that `HTML` should be used for `X-HTML` sources instead of `XML`.

The Eclipse XML catalog cannot be configured for the Spotless WTP formatter, instead a
user defined catalog file can be specified using the property `userCatalog`. Catalog versions
1.0 and 1.1 are supported by Spotless.

Unlike Eclipse, Spotless WTP ignores per default external URIs in schema location hints and
external entities. To allow the access of external URIs, set the property `resolveExternalURI`
to true.

<a name="format"></a>
<a name="custom rules"></a>

## Biome

[homepage](https://biomejs.dev/). [changelog](https://github.com/biomejs/biome/blob/main/CHANGELOG.md). Biome is
a formatter that for the frontend written in Rust, which has a native binary, does not require Node.js and as such,
is pretty fast. It can currently format JavaScript, TypeScript, JSX, and JSON, and may support
[more frontend languages](https://biomejs.dev/internals/language-support/) such as CSS in the future.

You can use Biome in any language-specific format for supported languages, but
usually you will be creating a generic format.

Note regarding CSS: Biome supports formatting CSS as of 1.8.0 (experimental, opt-in) and 1.9.0 (stable).

```xml
<configuration>
  <formats>
    <format>
      <includes>
        <include>src/**/typescript/**/*.ts</include>
      </includes>

      <biome>
        
        <version>2.1.1</version>

        
        <configPath>${project.basedir}/path/to/config/dir</configPath>

        
        
        <language>ts</language>
      </prettier>
    </biome>

  </formats>
</configuration>
```

To apply Biome to more kinds of files with a different configuration, just add
more formats:

```xml
<configuration>
  <formats>
    <format><includes>src/**/*.ts</includes><biome/></format>
    <format><includes>src/**/*.js</includes><biome/></format>
</configuration>
```

**Limitations:**
- The auto-discovery of config files (up the file tree) will not work when using
  Biome within spotless.
- The `ignore` option of the `biome.json` configuration file will not be applied.
  Include and exclude patterns are configured in the spotless configuration in the
  Maven pom instead.

Note: Due to a limitation of biome, if the name of a file matches a pattern in
the `ignore` option of the specified `biome.json` configuration file, it will not be
formatted, even if included in the biome configuration section of the Maven pom.
You could specify a different `biome.json` configuration file without an `ignore`
pattern to circumvent this.

Note 2: Biome is hard-coded to ignore certain special files, such as `package.json`
or `tsconfig.json`. These files will never be formatted.

### Biome binary

To format with Biome, spotless needs to find the Biome binary. By default,
spotless downloads the binary for the given version from the network. This
should be fine in most cases, but may not work e.g. when there is not connection
to the internet.

To download the Biome binary from the network, just specify a version:

```xml
<biome>
  <version>2.1.0</version>
</biome>
```

Spotless uses a default version when you do not specify a version, but this
may change at any time, so we recommend that you always set the Biome version
you want to use. Optionally, you can also specify a directory for the downloaded
Biome binaries (defaults to `~/.m2/repository/com/diffplug/spotless/spotless-data/biome`):

```xml
<biome>
  <version>2.1.0</version>
  
  <downloadDir>${user.home}/biome</downloadDir>
</biome>
```

To use a fixed binary, omit the `version` and specify a `pathToExe`:

```xml
<biome>
  <pathToExe>${project.basedir}/bin/biome</pathToExe>
</biome>
```

Absolute paths are used as-is. Relative paths are resolved against the project's
base directory. To use a pre-installed Biome binary on the user's path, specify
just a name without any slashes / backslashes:


```xml
<biome>
  
  <pathToExe>biome</pathToExe>
</biome>
```

### Biome configuration file

Biome is a biased formatter and linter without many options, but there are a few
basic options. Biome uses a file named [biome.json](https://biomejs.dev/reference/configuration/)
for its configuration. When none is specified, the default configuration from
Biome is used. To use a custom configuration:

```xml
<biome>
  
  
  
  <configPath>${project.basedir}</configPath>
</biome>
```

__If spotless does not format any files__, this might be because you excluded those files in you biome.json
configuration file. If you are using biome 2.x, you can create a custom config file for spotless and inherit from
your main config file like this:

```jsonc
// biome-spotless.json
{
  "extends": "./biome.json",
  "include": ["**"]
}
```

Then simply specify the path to this file in your spotless configuration:

```xml
<biome>
  <configPath>${project.basedir}/biome-spotless.json</configPath>
</biome>
```

### Biome input language

By default, Biome detects the language / syntax of the files to format
automatically from the file extension. This may fail if your source code files
have unusual extensions for some reason. If you are using the generic format,
you can force a certain language like this:

```xml
<configuration>
  <formats>
    <format>
      <includes>
        <include>src/**/typescript/**/*.mjson</include>
      </includes>

      <biome>
        <version>1.2.0</version>
        <language>json</language>
      </biome>
    </format>
  </formats>
</configuration>
```

The following languages are currently recognized:

* `js` -- JavaScript
* `jsx` -- JavaScript + JSX (React)
* `js?` -- JavaScript, with or without JSX, depending on the file extension
* `ts` -- TypeScript
* `tsx` -- TypeScript + JSX (React)
* `ts?` -- TypeScript, with or without JSX, depending on the file extension
* `json` -- JSON

## IntelliJ IDEA

[homepage](https://www.jetbrains.com/idea/). [changelog](https://www.jetbrains.com/idea/whatsnew/).

`IntelliJ IDEA` is a powerful IDE for java, kotlin and many more languages. There are [specific variants](https://www.jetbrains.com/products/) for almost any modern language
and a plethora of [plugins](https://plugins.jetbrains.com/).

Spotless provides access to IntelliJ IDEA's command line formatter.

```xml
<configuration>
  <formats>
    <format>
      <includes>
        <include>src/main/**/*.java</include>
        <include>jbang/*.java</include>
      </includes>

      <idea>
        
        <codeStyleSettingsPath>/path/to/config</codeStyleSettingsPath>
        
        <withDefaults>false</withDefaults>
        
        <binaryPath>/path/to/idea</binaryPath>
      </idea>
    </format>
  </formats>
</configuration>
```

### How to generate code style settings files
See [here](../INTELLIJ_IDEA_SCREENSHOTS.md) for an explanation on how to extract or reference existing code style files.

### Limitations
- Currently, only IntelliJ IDEA is supported - none of the other jetbrains IDE. Consider opening a PR if you want to change this.
- Launching IntelliJ IDEA from the command line is pretty expensive and as of now, we do this for each file. If you want to change this, consider opening a PR.

## Generic steps

[Prettier](#prettier), [eclipse wtp](#eclipse-web-tools-platform), [IntelliJ IDEA](#intellij-idea) and [license header](#license-header) are available in every format, and they each have their own section. As mentioned in the [quickstart](#quickstart), there are a variety of simple generic steps which are also available in every format, here are examples of these:

```xml
<trimTrailingWhitespace /> 

<endWithNewline /> 

<indent> 
  <spaces>true</spaces> 
  <spacesPerTab>4</spacesPerTab> 
</indent>

<jsr223> 
  <name>Greetings to Mars</name>
  <dependency>org.codehaus.groovy:groovy-jsr223:3.0.9</dependency> 
  <engine>groovy</engine> 
  <script>source.replace('World','Mars');</script> 
</jsr223>

<nativeCmd> 
  <name>Greetings to Mars from sed</name>
  <pathToExe>/usr/bin/sed</pathToExe> 
  <arguments> 
    <argument>s/World/Mars/g</argument>
  </arguments>
</nativeCmd>

<replace> 
  <name>Say Hello to Mars</name>
  <search>World</search>
  <replacement>Mars</replacement>
</replace>

<replaceRegex> 
  <name>Say Hello to Mars from Regex</name>
  <searchRegex>(Hello) W[a-z]{3}d</searchRegex>
  <replacement>$1 Mars</replacement>
</replaceRegex>

<forbidRegex>
  <name>Forbid FooBar</name>
  <searchRegex>import foo\.bar\.(.*)</searchRegex>
  <lintDetail>foobar is officially abandoned, use fizzbuzz instead</lintDetail>
</forbidRegex>
```

<a name="license-header-options"></a>

## License header

Spotless can inject a license header into your files, including populating an accurate copyright header from today's date or from git history.

```xml
<licenseHeader> 
  <content>/* (C)$YEAR */</content>  
  <delimiter>#</delimiter>  
</licenseHeader>
```

If the license header (specified with `content` or `file`) contains `$YEAR` or `$today.year`, then that token will be replaced with the current 4-digit year.  For example, if Spotless is launched in 2020, then `/* Licensed under Apache-2.0 $YEAR. */` will produce `/* Licensed under Apache-2.0 2020. */`

Once a file's license header has a valid year, whether it is a year (`2020`) or a year range (`2017-2020`), it will not be changed.  If you want the date to be updated when it changes, enable the [`ratchetFrom` functionality](#ratchet), and the year will be automatically set to today's year according to the following table (assuming the current year is 2020):

* No license header -> `2020`
* `2017` -> `2017-2020`
* `2017-2019` -> `2017-2020`

### Retroactively slurp years from git history

If your project has not been rigorous with copyright headers, and you'd like to use git history to repair this retroactively, you can do so with `-DspotlessSetLicenseHeaderYearsFromGitHistory=true`.  When run in this mode, Spotless will do an expensive search through git history for each file, and set the copyright header based on the oldest and youngest commits for that file.  This is intended to be a one-off sort of thing.

### Files with fixed header lines

Some files have fixed header lines (e.g. `<?xml version="1.0" ...` in XMLs, or `#!/bin/bash` in bash scripts). Comments cannot precede these, so the license header has to come after them, too.

To define what lines to skip at the beginning of such files, fill the `skipLinesMatching` option with a regular expression that matches them (e.g. `<skipLinesMatching>^#!.+?$</skipLinesMatching>` to skip shebangs).

### Skip headers and multiple license headers

Sometimes it may be necessary to disable a license rule for specific files, or to maintain dual licenses.

To define alternate replacements: 

```xml
<licenseHeader>
    <name>PrimaryHeaderLicense</name>
    <content>/** Base License Header */</content>
    <onlyIfContentMatches>Best</onlyIfContentMatches>
</licenseHeader>
<licenseHeader>
  <name>SecondaryHeaderLicense</name>
  <content>/** Alternate License Header */</content>
  <onlyIfContentMatches>.*Test.+</onlyIfContentMatches>
</licenseHeader>
```

<a name="invisible"></a>

<a name="ratchet"></a>

## Incremental up-to-date checking and formatting

**This feature is enabled by default starting from version 2.35.0.**

Execution of `spotless:check` and `spotless:apply` for large projects can take time.
By default, Spotless Maven plugin needs to read and format each source file.
Repeated executions of `spotless:check` or `spotless:apply` are completely independent.

If your project has many source files managed by Spotless and formatting takes a long time, you can
enable incremental up-to-date checking with the following configuration:

```xml
<configuration>
  <upToDateChecking>
    <enabled>true</enabled>
    <indexFile>${project.basedir}/custom-index-file</indexFile> 
  </upToDateChecking>
  
</configuration>
```

With up-to-date checking enabled, Spotless creates an index file in the `target` directory.
The index file contains source file paths and corresponding last modified timestamps.
It allows Spotless to skip already formatted files that have not changed.

**Note:** the index file is located in the `target` directory. Executing `mvn clean` will delete
the index file, and Spotless will need to check/format all the source files. You can override the default index file location with the `indexFile` configuration parameter.

Spotless will remove the index file when up-to-date checking is explicitly turned off with the
following configuration:

```xml
<configuration>
  <upToDateChecking>
    <enabled>false</enabled>
    <indexFile>${project.basedir}/custom-index-file</indexFile> 
  </upToDateChecking>
  
</configuration>
```

Consider using this configuration if you experience issues with up-to-date checking.

## How can I enforce formatting gradually? (aka "ratchet")

If your project is not currently enforcing formatting, then it can be a noisy transition.  Having a giant commit where every single file gets changed makes the history harder to read.  To address this, you can use the `ratchet` feature:

```xml
<configuration>
  <ratchetFrom>origin/main</ratchetFrom> 
  
</configuration>
```

In this mode, Spotless will apply only to files which have changed since `origin/main`.  You can ratchet from [any point you want](https://javadoc.io/doc/org.eclipse.jgit/org.eclipse.jgit/5.6.1.202002131546-r/org/eclipse/jgit/lib/Repository.html#resolve-java.lang.String-), even `HEAD`.  You can also set `ratchetFrom` per-format if you prefer (e.g. `<configuration><java><ratchetFrom>...`).

However, we strongly recommend that you use a non-local branch, such as a tag or `origin/main`.  The problem with `HEAD` or any local branch is that as soon as you commit a file, that is now the canonical formatting, even if it was formatted incorrectly.  By instead specifying `origin/main` or a tag, your CI server will fail unless every changed file is at least as good or better than it was before the change.

This is especially helpful for injecting accurate copyright dates using the [license step](#license-header).

You can explicitly disable ratchet functionality by providing the value 'NONE':
```xml
<configuration>
  <ratchetFrom>NONE</ratchetFrom>
</configuration>
```
This is useful for disabling the ratchet functionality in child projects where the parent defines a ratchetFrom value.

### Using `ratchetFrom` on CI systems

Many popular CI systems (GitHub, GitLab, BitBucket, and Travis) use a "shallow clone". This means that `<ratchetFrom>origin/main</ratchetFrom>` will fail with `No such reference`. You can fix this by:

- calling `git fetch origin main` before you call Spotless
- disabling the shallow clone [like so](https://github.com/diffplug/spotless/issues/710)

## `spotless:off` and `spotless:on`

Sometimes there is a chunk of code  which you have carefully handcrafted, and you would like to exclude just this one little part from getting clobbered by the autoformat. Some formatters have a way to do this, many don't, but who cares. If you setup your spotless like this:

```xml
<configuration>
  <java> 
    <toggleOffOn />
    ...
```

Then whenever Spotless encounters a pair of `spotless:off` / `spotless:on`, it will exclude that subsection of code from formatting. If you want, you can change the tags to be whatever you want, e.g. `<toggleOffOn><off>fmt:off</off><on>fmt:on</on></toggleOffOn>')`. If you change the default, [read this](https://github.com/diffplug/spotless/pull/691) for some gotchas.

## Line endings and encodings (invisible stuff)

Spotless uses UTF-8 by default, but you can use [any encoding which Java supports](https://docs.oracle.com/javase/8/docs/technotes/guides/intl/encoding.doc.html).  You can set it globally, and you can also set it per-format.

```xml
<configuration>
  <java>
    <encoding>Cp1252</encoding>
    
  </java>
  <encoding>US-ASCII</encoding>
</configuration>
```

Line endings can also be set globally or per-format using the `lineEndings` property.  Spotless supports

- constant modes (`UNIX`, `WINDOWS`, `MAC_CLASSIC`)
- simple modes (`PLATFORM_NATIVE`, `PRESERVE`)
- and git-aware modes (`GIT_ATTRIBUTES`, `GIT_ATTRIBUTES_FAST_ALLSAME`)

The default value is `GIT_ATTRIBUTES_FAST_ALLSAME`, and *we highly recommend that you* ***do not change*** *this value*.  Git has opinions about line endings, and if Spotless and git disagree, then you're going to have a bad time. `FAST_ALLSAME` just means that Spotless can assume that every file being formatted has the same line endings ([more info](https://github.com/diffplug/spotless/pull/1838)).

You can easily set the line endings of different files using [a `.gitattributes` file](https://help.github.com/articles/dealing-with-line-endings/). Here's an example `.gitattributes` which sets all files to unix newlines: `* text eol=lf`.

<a name="enforceCheck"></a>

## Disabling Spotless goals

By default, `spotless:check` is bound to the `verify` phase. You might want to disable Spotless for some builds. We [recommend against this](https://github.com/diffplug/spotless/issues/79#issuecomment-290844602), but the following properties are available:

| Property | Scope | Effect |
| --- | --- | --- |
| `spotless.skip` | `spotless:check` and `spotless:apply` | Skips both formatting goals |
| `spotless.check.skip` | `spotless:check` only | Skips only the check goal |
| `spotless.apply.skip` | `spotless:apply` only | Skips only the apply goal |

You can set them at the command line or in the `<properties>` section of the `pom.xml`:

- `-Dspotless.skip=true` / `<spotless.skip>true</spotless.skip>` — skip both `spotless:check` and `spotless:apply`
- `-Dspotless.check.skip=true` / `<spotless.check.skip>true</spotless.check.skip>` — skip only `spotless:check` (including when it is bound to `verify`)
- `-Dspotless.apply.skip=true` / `<spotless.apply.skip>true</spotless.apply.skip>` — skip only `spotless:apply`

`spotless.check.skip` does **not** skip `spotless:apply`, and `spotless.apply.skip` does **not** skip `spotless:check`. Use `spotless.skip` when you want both. These properties do **not** affect `spotless:install-git-pre-push-hook`.

### Suppressing lint errors

Sometimes Spotless will encounter lint errors that can't be auto-fixed. For example, if you run `mvn spotless:check`, you might see:

```
[ERROR] Unable to format file src/main/java/com/example/App.java
[ERROR] Step 'forbidWildcardImports' found problem in 'App.java':
[ERROR]   Do not use wildcard imports
```

To suppress these lints, you can use the `<lintSuppressions>` configuration:

```xml
<plugin>
  <groupId>com.diffplug.spotless</groupId>
  <artifactId>spotless-maven-plugin</artifactId>
  <version>${spotless.version}</version>
  <configuration>
    <java>
      <forbidWildcardImports/>
    </java>
    <lintSuppressions>
      <lintSuppression>
        <path>src/main/java/com/example/App.java</path>
        <step>forbidWildcardImports</step>
        <shortCode>*</shortCode>
      </lintSuppression>
    </lintSuppressions>
  </configuration>
</plugin>
```

Each `<lintSuppression>` can match by:
- `<path>` - file path (supports wildcards like `*`)
- `<step>` - step name (supports wildcards like `*`)
- `<shortCode>` - specific error code (supports wildcards like `*`)

You can suppress multiple patterns:

```xml
<lintSuppressions>
  
  <lintSuppression>
    <path>src/main/java/com/example/legacy/*</path>
    <step>forbidWildcardImports</step>
    <shortCode>*</shortCode>
  </lintSuppression>
  
  <lintSuppression>
    <path>*</path>
    <step>forbidWildcardImports</step>
    <shortCode>*</shortCode>
  </lintSuppression>
</lintSuppressions>
```

Spotless is primarily a formatter, _not_ a linter. In our opinion, a linter is just a broken formatter. But formatters do break sometimes, and representing these failures as lints that can be suppressed is more useful than just giving up.

<a name="preview"></a>

## How do I preview what `mvn spotless:apply` will do?

- Save your working tree with `git add -A`, then `git commit -m "Checkpoint before spotless."`
- Run `mvn spotless:apply`
- View the changes with `git diff`
- If you don't like what spotless did, `git reset --hard`
- If you'd like to remove the "checkpoint" commit, `git reset --soft head~1` will make the checkpoint commit "disappear" from history, but keeps the changes in your working directory.

## Can I apply Spotless to specific files?

You can target specific files by setting the `spotlessFiles` project property to a comma-separated list of file patterns:

```
cmd> mvn spotless:apply -DspotlessFiles=my/file/pattern.java,more/generic/.*-pattern.java
```

The patterns are matched using `String#matches(String)` against the absolute file path.

## Does Spotless support incremental builds in Eclipse?

Spotless comes with [m2e](https://eclipse.dev/m2e/) support. However, by default its execution is skipped in incremental builds as most developers want to fix all issues in one go via explicit `mvn spotless:apply` prior to raising a PR and don't want to be bothered with Spotless issues during working on the source code in the IDE.
To enable it use the following parameter

```
<configuration>
    <m2eEnableForIncrementalBuild>true</m2eEnableForIncrementalBuild>
</configuration>
```

In addition Eclipse problem markers are being emitted for goal `check`. By default they have the severity `WARNING`.
You can adjust this with 

```
<configuration>
    <m2eIncrementalBuildMessageSeverity>ERROR</m2eIncrementalBuildMessageSeverity>
</configuration>
```

Note that for Incremental build support the goals have to be bound to a phase prior to `test`.

<a name="central-configuration"></a>

## How to centralize Spotless configuration

Rather than copying the formatter files across many projects, it is possible to define a common configuration that is deployed as a standard artifact so that it can be then be reused by each project; for example:

```xml
<plugin>
  <groupId>com.diffplug.spotless</groupId>
  <artifactId>spotless-maven-plugin</artifactId>
  <version>${spotless-maven-plugin.version}</version>
  <dependencies>
    <dependency>
      <groupId>org.mycompany</groupId>
      <artifactId>code-configuration</artifactId>
      <version>1.0.0</version>
    </dependency>
  </dependencies>
  <configuration>
    <java>
      <removeUnusedImports/>
      <importOrder>
        <file>java-import-order.txt</file>
      </importOrder>
      <eclipse>
        <file>java-formatter.xml</file>
      </eclipse>
      <lineEndings>UNIX</lineEndings>
    </java>
  </configuration>
```

In this example, the files `java-import-order.txt` and `java-formatter.xml` should be at the root of the deployed `org.mycompany:code-configuration:1.0.0` jar.

## Example configurations (from real-world projects)

- [Apache Avro](https://github.com/apache/avro/blob/8026c8ffe4ef67ab419dba73910636bf2c1a691c/lang/java/pom.xml#L307-L334)
- [JUNG: Java Universal Network/Graph Framework](https://github.com/jrtom/jung/blob/b3a2461b97bb3ab40acc631e21feef74976489e4/pom.xml#L187-L208)

---

--- METRICS ---
- Files Extracted: 3
- Estimated Token Budget: ~50700 tokens
- Canonical Reference: https://codewiki.google/github.com/diffplug/spotless
