# Spotless plugin for Gradle
*Keep your code Spotless with Gradle*
[![Gradle plugin](https://img.shields.io/badge/plugins.gradle.org-com.diffplug.spotless-blue.svg)](https://plugins.gradle.org/plugin/com.diffplug.spotless)
[![Changelog](https://img.shields.io/badge/changelog-6.25.0-blue.svg)](CHANGES.md)
[![MavenCentral](https://img.shields.io/badge/mavencentral-here-blue.svg)](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.diffplug.spotless%22%20AND%20a%3A%22spotless-plugin-gradle%22)
[![Javadoc](https://img.shields.io/badge/javadoc-here-blue.svg)](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/6.25.0/index.html)
[![VS Code plugin](https://img.shields.io/badge/IDE-VS_Code-blueviolet.svg)](https://marketplace.visualstudio.com/items?itemName=richardwillis.vscode-spotless-gradle)
[![IntelliJ plugin](https://img.shields.io/badge/IDE-IntelliJ-blueviolet.svg)](https://plugins.jetbrains.com/plugin/18321-spotless-gradle)
[![Add other IDE](https://img.shields.io/badge/IDE-add_yours-blueviolet.svg)](IDE_HOOK.md)
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)
- **Languages**
- [Java](#java) ([google-java-format](#google-java-format), [eclipse jdt](#eclipse-jdt), [clang-format](#clang-format), [prettier](#prettier), [palantir-java-format](#palantir-java-format), [formatAnnotations](#formatAnnotations), [cleanthat](#cleanthat))
- [Groovy](#groovy) ([eclipse groovy](#eclipse-groovy))
- [Kotlin](#kotlin) ([ktfmt](#ktfmt), [ktlint](#ktlint), [diktat](#diktat), [prettier](#prettier))
- [Scala](#scala) ([scalafmt](#scalafmt))
- [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))
- [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))
- javascript, jsx, angular, vue, flow, typescript, css, less, scss, html, json, graphql, markdown, ymaml
- [clang-format](#clang-format)
- c, c++, c#, objective-c, protobuf, javascript, java
- [eclipse web tools platform](#eclipse-web-tools-platform)
- css, html, js, json, xml
- [Biome](#biome) ([binary detection](#biome-binary), [config file](#biome-configuration-file), [input language](#biome-input-language))
- **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)
- [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()
indentWithTabs() // or spaces. 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/6.25.0/com/diffplug/gradle/spotless/FormatExtension.html#target-java.lang.Object...-) and [`targetExclude`](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/6.25.0/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/6.25.0/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/6.25.0/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/6.25.0/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/6.25.0/com/diffplug/gradle/spotless/FormatExtension.html#custom-java.lang.String-groovy.lang.Closure-), [`prettier`](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/6.25.0/com/diffplug/gradle/spotless/FormatExtension.html#prettier--), [`eclipseWtp`](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/6.25.0/com/diffplug/gradle/spotless/FormatExtension.html#eclipseWtp-com.diffplug.spotless.extra.wtp.EclipseWtpFormatterStep-), [`licenseHeader`](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/6.25.0/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/6.25.0/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 11+ and Gradle 6.1.1 or newer.
- 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 an older 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).
## Java
`com.diffplug.gradle.spotless.JavaExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/6.25.0/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)
```gradle
spotless {
java {
// 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, '|' to join group without blank line, 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
removeUnusedImports()
// Cleanthat will refactor your code, but it may break your style: apply it before your formatter
cleanthat() // has its own section below
// Choose one of these formatters.
googleJavaFormat() // has its own section below
eclipse() // has its own section below
prettier() // has its own section below
clangFormat() // has its own section below
formatAnnotations() // fixes formatting of type annotations, see below
licenseHeader '/* (C) $YEAR */' // or licenseHeaderFile
}
}
```
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')
```
### 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)
```
### eclipse jdt
[homepage](https://www.eclipse.org/downloads/packages/). [compatible versions](https://github.com/diffplug/spotless/tree/main/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_jdt_formatter). 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')
// if the access to the p2 repositories is restricted, mirrors can be
// specified using a URI prefix map as follows:
echlise().withP2Mirrors(['https://download.eclipse.org/eclipse/updates/4.29/':'https://some.internal.mirror/4-29-updates-p2/'])
```
### 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.8') // You may force a custom version of 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)
```
## Groovy
- `com.diffplug.gradle.spotless.GroovyExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/6.25.0/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/6.25.0/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')
```
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/6.25.0/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/6.25.0/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 {
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
licenseHeader '/* (C)$YEAR */' // or licenseHeaderFile
}
kotlinGradle {
target '*.gradle.kts' // default target for kotlinGradle
ktlint() // or ktfmt() or prettier()
}
}
```
### ktfmt
[homepage](https://github.com/facebookincubator/ktfmt). [changelog](https://github.com/facebookincubator/ktfmt/releases).
```kotlin
spotless {
kotlin {
ktfmt('0.30').dropboxStyle() // version and dropbox style are optional
```
### 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,
)
)
.customRuleSets(
listOf(
"io.nlopez.compose.rules:ktlint:0.3.3"
)
)
}
}
```
### 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")
```
## Scala
`com.diffplug.gradle.spotless.ScalaExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/6.25.0/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')
```
## C/C++
`com.diffplug.gradle.spotless.CppExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/6.25.0/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
}
}
```
### 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')
}
}
```
## Python
`com.diffplug.gradle.spotless.PythonExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/6.25.0/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
// 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
```
## Protobuf
### buf
`com.diffplug.gradle.spotless.ProtobufExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/6.25.0/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/6.25.0/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/6.25.0/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).
Currently, none of the available options can be configured yet. It uses only the default options together with `COMMONMARK` as `FORMATTER_EMULATION_PROFILE`.
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
}
}
```
## Antlr4
`com.diffplug.gradle.spotless.Antlr4Extension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/6.25.0/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
```
## SQL
`com.diffplug.gradle.spotless.SqlExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/6.25.0/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
}
}
```
### 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/6.25.0/com/diffplug/gradle/spotless/PomExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/PomExtension.java)
```gradle
spotless {
pom {
target('pom.xml') // default value, you can change if you want
sortPom() // has its own section below
}
}
```
### sortPom
[homepage](https://github.com/Ekryd/sortpom).
All configuration settings are optional, they are described in detail [here](https://github.com/Ekryd/sortpom/wiki/Parameters).
```gradle
spotless {
pom {
sortPom('3.4.0')
.encoding('UTF-8') // The encoding of the pom files
.lineSeparator(System.getProperty('line.separator')) // line separator to use
.expandEmptyElements(true) // Should empty elements be expanded
.spaceBeforeCloseEmptyElement(false) // Should a space be added inside self-closing elements
.keepBlankLines(true) // Keep empty lines
.endWithNewline(true) // Whether sorted pom ends with a newline
.nrOfIndentSpace(2) // Indentation
.indentBlankLines(false) // Should empty lines be indented
.indentSchemaLocation(false) // Should schema locations be indented
.predefinedSortOrder('recommended_2008_06') // Sort order of elements: https://github.com/Ekryd/sortpom/wiki/PredefinedSortOrderProfiles
.sortOrderFile(null) // Custom sort order of elements: https://raw.githubusercontent.com/Ekryd/sortpom/master/sorter/src/main/resources/custom_1.xml
.sortDependencies(null) // Sort dependencies: https://github.com/Ekryd/sortpom/wiki/SortDependencies
.sortDependencyManagement(null) // Sort dependency management: https://github.com/Ekryd/sortpom/wiki/SortDependencies
.sortDependencyExclusions(null) // Sort dependency exclusions: https://github.com/Ekryd/sortpom/wiki/SortDependencies
.sortPlugins(null) // Sort plugins: https://github.com/Ekryd/sortpom/wiki/SortPlugins
.sortProperties(false) // Sort properties
.sortModules(false) // Sort modules
.sortExecutions(false) // Sort plugin executions
}
}
```
## Typescript
- `com.diffplug.gradle.spotless.TypescriptExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/6.25.0/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/6.25.0/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/6.25.0/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