Skip to content

diffplug/spotless

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Spotless: Keep your code spotless with Gradle

Gradle plugin Maven central Javadoc

Changelog Travis CI Live chat License Apache

Spotless is a general-purpose formatting plugin. 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:

cmd> gradlew build
...
:spotlessJavaCheck FAILED
> The following files had format violations:
	src\main\java\com\diffplug\gradle\spotless\FormatExtension.java
		@@ -109,7 +109,7 @@
		...
		-\t\t····if·(targets.length·==·0)·{
		+\t\tif·(targets.length·==·0)·{
		...
	Run 'gradlew spotlessApply' to fix these violations.

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.

Applying to Java source

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()
	}
}

Custom rules

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!
		}
	}
}

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.

Line endings and encodings (invisible stuff)

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.

spotless {
	java {
		...
		encoding 'Cp1252' // java will have Cp1252
	}
	encoding 'US-ASCII'   // but all other formats will be interpreted as US-ASCII
}

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.

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.

Example configurations (from real-world projects)

Spotless is hosted on jcenter and at plugins.gradle.org. Go here if you're not sure how to import the plugin.

Acknowledgements

Exporting from & importing into Eclipse

There are two files to import/export with Eclipse - one for code formatting and one for import ordering.

Opening the preferences

Eclipse preferences

Creating spotless.eclipseformat.xml

Eclipse formatter Eclipse formatter edit

The Eclipse formatter's off/on tags are a great feature which is often overlooked. Eclipse formatter off/on tags

Creating spotless.importorder

Eclipse imports