Spotless is a general-purpose formatting plugin. It is completely a-la-carte, but also includes powerful "batteries-included" if you opt-in.
To people who use your build, it looks like this:
cmd> gradlew build
...
:spotlessJavaCheck FAILED
> Format violations were found. Run 'gradlew spotlessApply' to fix them.
src\test\java\com\diffplug\gradle\spotless\ResourceTest.java
cmd> gradlew spotlessApply
:spotlessApply
BUILD SUCCESSFUL
cmd> gradlew build
BUILD SUCCESSFUL
Inside your buildscript, it looks like this:
spotless {
format 'misc', {
target '**/*.gradle', '**/*.md', '**/.gitignore'
trimTrailingWhitespace()
indentWithTabs() // or spaces. Takes an integer argument if you don't like 4
endWithNewline()
}
format 'cpp', {
target '**/*.hpp', '**/*.cpp'
customReplace 'Not enough space after if', 'if(', 'if ('
customReplaceRegex 'Too much space after if', 'if +\\(', 'if ('
// Everything before the first #include or #pragma will
// be replaced with whatever is in `spotless.license.cpp`
licenseHeaderFile 'spotless.license.cpp', '#'
}
}
Spotless can check and apply formatting to any plain-text file, using simple rules (javadoc) like those above. It also supports more powerful formatters:
- Eclipse's java code formatter (including style and import ordering)
- Google's google-java-format
- FreshMark (markdown with variables)
- Any user-defined function which takes an unformatted string and outputs a formatted version.
Contributions are welcome, see the contributing guide for development info.
Spotless requires Gradle to be running on JRE 8+.See issue #7 for details.
apply plugin: 'java'
...
spotless {
java {
// By default, all Java source sets will be formatted. To change
// this, set the 'target' parameter as described in the next section.
licenseHeader '/* Licensed under Apache-2.0 */' // License header
licenseHeaderFile 'spotless.license.java' // License header file
// Obviously, you can't specify both licenseHeader and licenseHeaderFile at the same time
importOrder ['java', 'javax', 'org', 'com', 'com.diffplug', ''] // An array of package names
importOrderFile 'spotless.importorder' // An import ordering file, exported from Eclipse
// As before, you can't specify both importOrder and importOrderFile at the same time
// You probably want an empty string at the end - all of the imports you didn't specify
// explicitly will go there.
eclipseFormatFile 'spotless.eclipseformat.xml' // XML file dumped out by the Eclipse formatter
// If you have an older Eclipse properties file, you can use that too.
// You can also tweak the formatting with custom regexes or functions, such as:
// Eclipse formatter screws up long literals with underscores inside of annotations (see issue #14)
// @Max(value = 9_999_999 L) // what Eclipse does
// @Max(value = 9_999_999L) // what I wish Eclipse did
custom 'Long literal fix', { it.replaceAll('([0-9_]+) [Ll]', '$1L') }
}
}
Applying to Java source (google-java-format)
spotless {
java {
googleJavaFormat() // googleJavaFormat('1.1') to specify a specific version
// you can then layer other format steps, such as
licenseHeaderFile 'spotless.license.java'
}
}
Applying FreshMark to markdown files
To apply freshmark to all of the .md
files in your project, with all of your project's properties available for templating, just use this snippet:
spotless {
freshmark {}
}
You can also specify properties manually.
spotless {
freshmark {
target 'README.md', 'CONTRIBUTING.md'
properties([lib: 'MyLib', author: 'Me'])
trimTrailingWhitespace()
indentWithTabs()
endWithNewline()
}
}
Spotless is a generic system for specifying a sequence of steps which are applied to a set of files.
spotless {
// this will create two tasks: spotlessMiscCheck and spotlessMiscApply
format 'misc', {
// target determines which files this format will apply to
// - if you pass a string or a list of strings, they will be treated
// as 'include' parameters to a fileTree in the root directory
// - if you pass a FileCollection, it will pass through untouched
// e.g. project.files('build.gradle', 'settings.gradle')
// - if you pass anything else, it will be sent to project.files(yourArg)
target '**/*.gradle', '**/*.md', '**/.gitignore'
// spotless has built-in rules for the most basic formatting tasks
trimTrailingWhitespace()
indentWithTabs() // or spaces. Takes an integer argument if you don't like 4
endWithNewline()
// you can also call out to your own function
custom 'superFormatter', {
// when writing a custom step, it will be helpful to know
// how the formatting process works, which is as follows:
// 1) Load each target file, and convert it to unix-style line endings ('\n')
// 2) Pass its content through a series of steps, feeding the output of each step to the next
// 3) Put the correct line endings back on, then either check or apply
// each step receives a string as input, and should output
// a formatted string as output. Each step can trust that its
// input will have unix newlines, and it must promise to output
// only unix newlines. Other than that, anything is fair game!
}
}
// The default line ending mode, GIT_ATTRIBUTES, has the exact same line ending
// behavior as git, including support for the eol property of .gitattributes,
// and the core.eol configuration property.
lineEndings 'GIT_ATTRIBUTES' // can also be WINDOWS, UNIX, or PLATFORM_NATIVE
}
See JavaExtension.java
if you'd like to see how a language-specific set of custom rules is implemented. We'd love PR's which add support for other languages.
Spotless is hosted on jcenter and at plugins.gradle.org. Go here if you're not sure how to import the plugin.
- JUnit 5 (aka JUnit Lambda)
- opentest4j
- Durian (direct link to spotless section in its build.gradle)
- DurianRx (direct link to spotless section in its build.gradle)
- DurianSwt (direct link to spotless section in its build.gradle)
- MatConsoleCtl (direct link to spotless section in its build.gradle)
- MatFileRW (direct link to spotless section in its build.gradle)
- Goomph (direct link to spotless section in its build.gradle)
- FreshMark (direct link to spotless section in its build.gradle)
- JScriptBox (direct link to spotless section in its build.gradle)
- (Your project here)
- Formatting by Eclipse 4.6
- Special thanks to Mateusz Matela for huge improvements to the eclipse code formatter!
- Forked from gradle-format-plugin by Youri Bonnaff??.
- Thanks to Gabor Bernat for improvements to logging and multi-project support.
- Import ordering from EclipseCodeFormatter.
- Built by gradle.
- Tested by junit.
- Maintained by DiffPlug.
There are two files to import / export with Eclipse - one for code formatting and one for import ordering.
Eclipse formatter's off / on tags are a great feature which is often overlooked.