Spotless is a general-purpose formatting plugin. 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:
cmd> mvn spotless:check
...
[ERROR] ... The following files had format violations:
[ERROR] src\main\java\com\diffplug\gradle\spotless\FormatExtension.java
[ERROR] @@ -109,7 109,7 @@
[ERROR] ...
[ERROR] -\t\t····if·(targets.length·==·0)·{
[ERROR] \t\tif·(targets.length·==·0)·{
[ERROR] ...
[ERROR] Run 'mvn spotless:apply' to fix these violations.
...
cmd> mvn spotless:apply
...
[INFO] BUILD SUCCESS
...
cmd> mvn spotless:check
...
[INFO] BUILD SUCCESS
...
To use it in your pom, just add the Spotless dependency, and configure it like so:
<plugin>
<groupId>com.diffplug.spotless</groupId>
<artifactId>spotless-maven-plugin</artifactId>
<version>${spotless.version}</version>
<configuration>
<java>
<eclipse>
<file>${basedir}/eclipse-fmt.xml</file>
<version>4.7.1</version>
</eclipse>
</java>
</configuration>
</plugin>
Spotless supports the following powerful formatters:
- Eclipse's java code formatter (including style and import ordering)
- Eclipse's CDT C/C code formatter
- Eclipse's WTP Web-Tools code formatters
- Google's google-java-format
- Typescript Tsfmt formatter
- Prettier formatter
- User-defined license enforcement, regex replacement, etc.
Contributions are welcome, see the contributing guide for development info.
Spotless requires Maven to be running on JRE 8 .
By default, all files matching src/main/java/**/*.java
and src/test/java/**/*.java
Ant style pattern will be formatted. Each element under <java>
is a step, and they will be applied in the order specified. Every step is optional, and they will be applied in the order specified. It doesn't make sense to use both eclipse and google-java-format.
<configuration>
<java>
<licenseHeader>
<!-- Specify either content or file, but not both -->
<content>/* Licensed under Apache-2.0 */</content>
<file>${basedir}/license-header</file>
</licenseHeader>
<eclipse>
<!-- Optional, otherwise Eclipse defaults are used. Eclipse preference or property files are also supported. -->
<file>${basedir}/eclipse-format.xml</file>
<!-- Optional, available versions: https://github.com/diffplug/spotless/tree/master/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_jdt_formatter -->
<version>4.7.1</version>
</eclipse>
<googleJavaFormat>
<!-- Optional, available versions: https://search.maven.org/#search|gav|1|g:"com.google.googlejavaformat" AND a:"google-java-format" -->
<version>1.5</version>
<!-- Optional, available versions: GOOGLE, AOSP https://github.com/google/google-java-format/blob/master/core/src/main/java/com/google/googlejavaformat/java/JavaFormatterOptions.java -->
<style>GOOGLE</style>
</googleJavaFormat>
<removeUnusedImports/>
<importOrder>
<!-- Specify either order or file, but not both -->
<order>java,javax,org,com,com.diffplug,</order>
<file>${basedir}/eclipse.importorder</file>
</importOrder>
</java>
</configuration>
See ECLIPSE_SCREENSHOTS for screenshots that demonstrate how to get and install the Eclipse format configuration file and Eclipse import order file mentioned above.
By default, all files matching src/main/scala/**/*.scala
, src/test/scala/**/*.scala
, src/main/scala/**/*.sc
and src/test/scala/**/*.sc
Ant style pattern will be formatted. Each element under <scala>
is a step, and they will be applied in the order specified. Every step is optional.
<configuration>
<scala>
<licenseHeader>
<!-- Specify either content or file, but not both -->
<content>/* Licensed under Apache-2.0 */</content>
<file>${basedir}/license-header</file>
</licenseHeader>
<endWithNewline/>
<trimTrailingWhitespace/>
<scalafmt>
<file>${basedir}/scalafmt.conf</file>
<!-- Optional, available versions: https://github.com/scalameta/scalafmt/releases -->
<version>1.1.0</version>
</scalafmt>
</scala>
</configuration>
By default, all files matching src/main/kotlin/**/*.kt
and src/test/kotlin/**/*.kt
Ant style pattern will be formatted. Each element under <kotlin>
is a step, and they will be applied in the order specified. Every step is optional.
Applying ktlint to Kotlin files
<configuration>
<kotlin>
<licenseHeader>
<!-- Specify either content or file, but not both -->
<content>/* Licensed under Apache-2.0 */</content>
<file>${basedir}/license-header</file>
</licenseHeader>
<endWithNewline/>
<trimTrailingWhitespace/>
<ktlint>
<!-- Optional, available versions: https://github.com/pinterest/ktlint/releases -->
<version>0.14.0</version>
</ktlint>
</kotlin>
</configuration>
Applying ktfmt to Kotlin files
<configuration>
<kotlin>
<licenseHeader>
<!-- Specify either content or file, but not both -->
<content>/* Licensed under Apache-2.0 */</content>
<file>${basedir}/license-header</file>
</licenseHeader>
<endWithNewline/>
<trimTrailingWhitespace/>
<ktfmt>
<!-- Optional, available versions: https://github.com/facebookincubator/ktfmt/releases -->
<version>0.11</version>
</ktfmt>
</kotlin>
</configuration>
By default, all files matching src/main/cpp/**/*.<ext>
and src/test/cpp/**/*.<ext>
Ant style pattern will be formatted, whereas the file extensions c
, h
, C
, cpp
, cxx
, cc
, c
, h
, hpp
, hh
, hxx
and inc
are supported. Each element under <cpp>
is a step, and they will be applied in the order specified. Every step is optional, and they will be applied in the order specified.
<configuration>
<cpp>
<licenseHeader>
<!-- Specify either content or file, but not both -->
<content>/* Licensed under Apache-2.0 */</content>
<file>${basedir}/license-header</file>
</licenseHeader>
<eclipse>
<file>${basedir}/eclipse-fmt.xml</file>
<!-- Optional, available versions: https://github.com/diffplug/spotless/tree/master/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_cdt_formatter -->
<version>4.7.3a</version>
</eclipse>
</cpp>
</configuration>
Use the Eclipse to define the Code Style preferences (see Eclipse documentation). Within the preferences Edit... dialog, you can export your configuration as XML file, which can be used as a configuration <file>
. If no <file>
is provided, the CDT default configuration is used.
<configuration>
<typescript>
<!-- optionally define which files will be formatted. -->
<includes>
<include>src/**/*.ts</include> <!-- default value if nothing is specified -->
</includes>
<tsfmt>
<!-- must specify exactly one of the following "{foo}File" or "config" elements -->
<tslintFile>${basedir}/path/to/repo/tslint.json</tslintFile>
<tsfmtFile>${basedir}/path/to/repo/tsfmt.json</tsfmtFile>
<tsconfigFile>${basedir}/path/to/repo/tsconfig.json</tsconfigFile>
<vscodeFile>${basedir}/path/to/repo/vscode.json</vscodeFile>
<config>
<indentSize>1</indentSize>
<convertTabsToSpaces>true</convertTabsToSpaces>
</config>
<!-- optionally configure following versions to use, shown values are defaults-->
<typescriptFormatterVersion>7.2.2</typescriptFormatterVersion>
<typescriptVersion>3.3.3</typescriptVersion>
<tslintVersion>5.12.1</tslintVersion>
</tsfmt>
</typescript>
</configuration>
Supported config file types are tsconfigFile
, tslintFile
, vscodeFile
and tsfmtFile
. They are corresponding to the respective
tsfmt-parameters. See tsfmt's default config settings for what is available.
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.
tsfmt 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 binary to use.
<configuration><typescript><tsfmt>
...
<npmExecutable>/usr/bin/npm</npmExecutable>
Spotless uses npm to install necessary packages locally. It runs tsfmt using J2V8 internally after that.
Applying Prettier to javascript | flow | typeScript | css | scss | less | jsx | graphQL | yaml | etc.
Prettier is a formatter that can format multiple file types.
To use prettier, you first have to specify the files that you want it to apply to. Then you specify prettier, and how you want to apply it.
<configuration>
<formats>
<format>
<includes>
<include>src/**/typescript/**/*.ts</include>
</includes>
<prettier>
<!-- Specify at most one of the following 3 configs: either 'prettierVersion' (2.0.5 is default), 'devDependencies' or 'devDependencyProperties' -->
<prettierVersion>1.19.0</prettierVersion>
<devDependencies>
<prettier>1.19.0</prettier>
</devDependencies>
<devDependencyProperties>
<property>
<name>prettier</name>
<value>2.0.5</value>
</property>
<property>
<name>@prettier/plugin-php</name> <!-- this could not be written in the simpler to write 'devDependencies' element. -->
<value>0.14.2</value>
</property>
</devDependencyProperties>
<!-- Specify config file and/or inline config -->
<configFile>${basedir}/path/to/configfile</configFile>
<config>
<useTabs>true</useTabs>
</config>
</prettier>
</format>
</formats>
</configuration>
Supported config options are documented on prettier.io. Supported config file variants are documented on prettier.io.
Please note:
- 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.
Since spotless uses the actual npm prettier package behind the scenes, it is possible to use prettier with plugins or community-plugins in order to support even more file types.
<configuration>
<formats>
<!-- prettier with java-plugin -->
<format>
<includes>
<include>src/*/java/**/*.java</include>
</includes>
<prettier>
<devDependencies>
<prettier>2.0.5</prettier>
<prettier-plugin-java>0.8.0</prettier-plugin-java>
</devDependencies>
<config>
<tabWidth>4</tabWidth>
<parser>java</parser>
</config>
</prettier>
</format>
<!-- prettier with php-plugin -->
<format>
<includes>
<include>src/**/*.php</include>
</includes>
<prettier>
<!-- use the devDependencyProperties writing style when the property-names are not well-formed such as @prettier/plugin-php -->
<devDependencyProperties>
<property>
<name>prettier</name>
<value>2.0.5</value>
</property>
<property>
<name>@prettier/plugin-php</name>
<value>0.14.2</value>
</property>
</devDependencyProperties>
<config>
<tabWidth>3</tabWidth>
<parser>php</parser>
</config>
</prettier>
</format>
</formats>
</configuration>
Prettier, like tsfmt, 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 binary to use.
<formats><format><prettier>
<npmExecutable>/usr/bin/npm</npmExecutable>
...
Spotless uses npm to install necessary packages and to run the prettier formatter after that.
By default, no Ant-Style include patterns are defined. Each element under <format>
is a step, and they will be applied in the order specified. Every step is optional, and they will be applied in the order specified. It is possible to define multiple custom formats.
<configuration>
<formats>
<!-- Define first formatter that operates on properties files -->
<format>
<includes>
<!-- Include all property files in "resource" folders under "src" -->
<include>src/**/resources/**/*.properties</include>
</includes>
<licenseHeader>
<!-- Specify either content or file, but not both -->
<content>/* Licensed under Apache-2.0 */</content>
<file>${basedir}/license-header</file>
<!-- conent until first occurrence of the delimiter regex will be interpreted as header section -->
<delimiter>#</delimiter>
</licenseHeader>
<!-- Files must end with a newline -->
<endWithNewline />
<!-- Specify whether to use tabs or spaces for indentation -->
<indent>
<!-- Specify either spaces or tabs -->
<spaces>true</spaces>
<tabs>true</tabs>
<!-- Specify how many spaces are used to convert one tab and vice versa. Defaults to 4 -->
<spacesPerTab>4</spacesPerTab>
</indent>
<!-- Trim trailing whitespaces -->
<trimTrailingWhitespace />
<!-- Specify replacements using search and replace -->
<replace>
<name>Say Hello to Mars</name>
<search>World</search>
<replacement>Mars</replacement>
</replace>
<!-- Specify replacements using regex match and replace -->
<replaceRegex>
<name>Say Hello to Mars from Regex</name>
<searchRegex>(Hello) W[a-z]{3}d</searchRegex>
<replacement>$1 Mars</replacement>
</replaceRegex>
</format>
<!-- Other formats can be defined here, they will be applied in the order specified -->
</formats>
</configuration>
Applying Eclipse WTP to css | html | etc.
The Eclipse WTP formatter can be applied as follows:
<configuration>
<formats>
<format>
<includes>
<include>src/**/resources/**/*.xml</include>
<include>src/**/resources/**/*.xsd</include>
</includes>
<eclipseWtp>
<!-- Specify the WTP formatter type (XML, JS, ...) -->
<type>XML</type>
<!-- Specify the configuration for the selected type -->
<files>
<file>${basedir}/xml.prefs</file>
<file>${basedir}/additional.properties</file>
</files>
<!-- Optional, available versions: https://github.com/diffplug/spotless/tree/master/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_wtp_formatters -->
<version>4.7.3a</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.
Spotless uses UTF-8 by default, but you can use any encoding which Java supports. You can set it globally, and you can also set it per-format.
<configuration>
<java>
<encoding>Cp1252</encoding>
<!-- ... other steps ... -->
</java>
<encoding>US-ASCII</encoding>
</configuration>
Line endings can also be set globally or per-format using the lineEndings
property. Spotless supports four line ending modes: UNIX
, WINDOWS
, PLATFORM_NATIVE
, and GIT_ATTRIBUTES
. The default value is GIT_ATTRIBUTES
, 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.
You can easily set the line endings of different files using a .gitattributes
file. Here's an example .gitattributes
which sets all files to unix newlines: * text eol=lf
.
Spotless uses Ant style patterns to define included and excluded files.
By default, most common compile and test source roots for the supported languages are included. They are src/main/java/**/*.java
, src/test/java/**/*.java
for Java and src/main/scala/**/*.scala
, src/main/scala/**/*.sc
, src/test/scala/**/*.scala
, src/test/scala/**/*.sc
for Scala.
Includes can be completely overriden using <includes>...</includes>
configuration section.
Default excludes only contain output directory (usually target/
) and various temporary and VCS-related files. Additional excludes can also be configured.
Includes and excludes can be configured the same way for all supported languages. Excample for Java:
<java>
<includes>
<!-- include all java files in "java" folders under "src" -->
<include>src/**/java/**/*.java</include>
<!-- include all java files in "java" folders under "other" -->
<include>other/java/**/*.java</include>
</includes>
<excludes>
<!-- exclude examples from formatting -->
<exclude>src/test/java/**/*Example.java</exclude>
</excludes>
</java>
By default, spotless:check
is bound to the verify
phase. You might want to disable this behavior. We recommend against this, but it's easy to do if you'd like:
- set
-Dspotless.check.skip=true
at the command line - set
spotless.check.skip
totrue
in the<properties>
section of thepom.xml
- Save your working tree with
git add -A
, thengit 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.
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.