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
- 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%7Cgav%7C1%7Cg%3A%22com.google.googlejavaformat%22%20AND%20a%3A%22google-java-format%22 -->
<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.
<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>
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.
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.