Ktlint Gradle
Provides a convenient wrapper plugin over the ktlint project.
Latest plugin version: 9.2.1
This plugin creates convenient tasks in your Gradle project that run ktlint checks or do code auto format.
Plugin can be applied to any project, but only activates if that project has the kotlin plugin applied. The assumption being that you would not want to lint code you weren't compiling.
Table of content
Supported Kotlin plugins
This plugin supports following kotlin plugins:
- "kotlin"
- "kotlin-android"
- "kotlin2js"
- "kotlin-platform-common"
- "kotlin-platform-js"
- "kotlin-platform-jvm"
- "kotlin-multiplatform"
- project kotlin script files
- "org.jetbrains.kotlin.js"
If you know any new Kotlin plugin that are not in this list - please, open a new issue.
How to use
Minimal supported versions
This plugin was written using the new API available for gradle script kotlin builds. This API is available in new versions of gradle.
Minimal supported Gradle version: 5.4.1
Minimal supported ktlint version: 0.22.0
Ktlint plugin
Simple setup
Build script snippet for use in all Gradle versions:
Groovy
buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "org.jlleitschuh.gradle:ktlint-gradle:<current_version>"
}
}
apply plugin: "org.jlleitschuh.gradle.ktlint"
Kotlin
buildscript {
repositories {
maven("https://plugins.gradle.org/m2/")
}
dependencies {
classpath("org.jlleitschuh.gradle:ktlint-gradle:<current_version>")
}
}
apply(plugin = "org.jlleitschuh.gradle.ktlint")
Using new plugin API
Build script snippet for new, incubating, plugin mechanism introduced in Gradle 2.1:
plugins {
id "org.jlleitschuh.gradle.ktlint" version "<current_version>"
}
Applying to subprojects
Optionally apply plugin to all project modules:
Groovy
subprojects {
apply plugin: "org.jlleitschuh.gradle.ktlint" // Version should be inherited from parent
// Optionally configure plugin
ktlint {
debug = true
}
}
Kotlin
subprojects {
apply(plugin = "org.jlleitschuh.gradle.ktlint") // Version should be inherited from parent
// Optionally configure plugin
ktlint {
debug.set(true)
}
}
IntelliJ Idea Only Plugin
Note: This plugin is automatically applied by the main ktlint
plugin.
This plugin just adds special tasks that can generate IntelliJ IDEA codestyle rules using ktlint.
Idea plugin simple setup
For all gradle versions:
Use the same buildscript
logic as above, but with this instead of the above suggested apply
line.
apply plugin: "org.jlleitschuh.gradle.ktlint-idea"
Idea plugin setup using new plugin API
Build script snippet for new, incubating, plugin mechanism introduced in Gradle 2.1:
plugins {
id("org.jlleitschuh.gradle.ktlint-idea") version "<current_version>"
}
Configuration
The following configuration block is optional.
If you don't configure this the defaults defined in the KtlintExtension object will be used.
The version of ktlint used by default may change between patch versions of this plugin. If you don't want to inherit these changes then make sure you lock your version here.
Groovy
import org.jlleitschuh.gradle.ktlint.reporter.ReporterType
ktlint {
version = "0.22.0"
debug = true
verbose = true
android = false
outputToConsole = true
outputColorName = "RED"
ignoreFailures = true
enableExperimentalRules = true
additionalEditorconfigFile = file("/some/additional/.editorconfig")
disabledRules = ["final-newline"]
reporters {
reporter "plain"
reporter "checkstyle"
customReporters {
"csv" {
fileExtension = "csv"
dependency = project(":project-reporters:csv-reporter")
}
"yaml" {
fileExtension = "yml"
dependency = "com.example:ktlint-yaml-reporter:1.0.0"
}
}
}
kotlinScriptAdditionalPaths {
include fileTree("scripts/")
}
filter {
exclude("**/generated/**")
include("**/kotlin/**")
}
}
dependencies {
ktlintRuleset "com.github.username:rulseset:master-SNAPSHOT"
ktlintRuleset files("/path/to/custom/rulseset.jar")
ktlintRuleset project(":chore:project-ruleset")
}
or in kotlin script:
Kotlin
import org.jlleitschuh.gradle.ktlint.reporter.ReporterType
ktlint {
version.set("0.22.0")
debug.set(true)
verbose.set(true)
android.set(false)
outputToConsole.set(true)
outputColorName.set("RED")
ignoreFailures.set(true)
enableExperimentalRules.set(true)
additionalEditorconfigFile.set(file("/some/additional/.editorconfig"))
disabledRules.set(setOf("final-newline"))
reporters {
reporter(ReporterType.PLAIN)
reporter(ReporterType.CHECKSTYLE)
customReporters {
register("csv") {
fileExtension = "csv"
dependency = project(":project-reporters:csv-reporter")
}
register("yaml") {
fileExtension = "yml"
dependency = "com.example:ktlint-yaml-reporter:1.0.0"
}
}
}
kotlinScriptAdditionalPaths {
include(fileTree("scripts/"))
}
filter {
exclude("**/generated/**")
include("**/kotlin/**")
}
}
dependencies {
ktlintRuleset("com.github.username:rulseset:master-SNAPSHOT")
ktlintRuleset(files("/path/to/custom/rulseset.jar"))
ktlintRuleset(project(":chore:project-ruleset"))
}
Custom reporters
Note: If Ktlint custom reporter creates report output file internally, for example:
class CsvReporter(
private val out: PrintStream
) : Reporter {
override fun onLintError(file: String, err: LintError, corrected: Boolean) {
val line = "$file;${err.line};${err.col};${err.ruleId};${err.detail};$corrected"
out.println(line)
File("some_other_file.txt").write(line) // <-- Here!!!
}
}
"some_other_file.txt" won't be captured as task output. This may lead to the problem, that task will always be not "UP_TO_DATE" and caching will not work.
Samples
This repository provides following examples how to setup this plugin:
- android-app - applies plugin to android application project
- kotlin-gradle - applies plugin to plain Kotlin project that uses groovy in
build.gradle
files - kotlin-js - applies plugin to kotlin js project
- kotlin-ks - applies plugin to plain Kotlin project that uses Kotlin DSL in
build.gradle.kts
files - kotlin-multiplatform-common - applies plugin to Kotlin common multiplatform module
- kotlin-multiplatform-js - applies plugin to Kotlin JavaScript multiplatform module
- kotlin-multiplatform-jvm - applies plugin to Kotlin JVM multiplatform module
- kotlin-rulesets-using - adds custom example ruleset
- kotlin-reporter-using - adds custom example reporter
Tasks Added
Main tasks
This plugin adds two maintasks to every source set: ktlint[source set name]SourceSetCheck
and ktlint[source set name]SourceSetFormat
.
Additionally, a simple ktlintCheck
task has also been added that checks all of the source sets for that project.
Similarly, a ktlintFormat
task has been added that formats all of the source sets.
Android projects, additionally, will have meta tasks for Android variants, that will process all source sets in variant.
For example, if app has foo
flavor, following meta tasks will be added:
ktlintFooDebugCheck
, ktlintFooReleaseCheck
, ktlintFooDebugFormat
, ktlintFooReleaseFormat
.
Additionally plugin adds two task for project kotlin script files: ktlintKotlinScriptCheck
and ktlintKotlinScriptFormat
.
Additional helper tasks
Following additional tasks are added:
ktlintApplyToIdea
- The task generates IntelliJ IDEA (or Android Studio) Kotlin style files in the project.idea/
folder. Note that this tasks will overwrite the existing style file.ktlintApplyToIdeaGlobally
- The task generates IntelliJ IDEA (or Android Studio) Kotlin style files in the user home IDEA (or Android Studio) settings folder. Note that this task will overwrite the existing style file.addKtlintCheckGitPreCommitHook
- adds Gitpre-commit
hook, that runs ktlint check over staged files.addKtlintFormatGitPreCommitHook
- adds Gitpre-commit
hook, that runs ktlint format over staged files and adds fixed files back to commit.
All this additional tasks are always added only to the root project.
FAQ
- Is it possible to not stop tasks execution if some of subprojects tasks failed?
Yes. Just use gradle --continue
option:
$ ./gradlew --continue ktlintCheck
- Can I mix old plugin and new plugin API setup in my project (see simple-setup and using new plugin API setup)?
No. This approaches are not equivalent how they work. The problem that plugin may not find some of kotlin plugins if both approaches are used in the project configuration. Especially it is related to Android plugin.
- Does plugin check changed files incrementally?
Yes, check tasks support it. On first run task will check all files in the source set, on subsequent runs it will check only added/modified files.
Format tasks does not check file incrementally.
- I could not filter dynamically attached sources that are located outside of the project dir.
Gradle based filtering are only working for files located inside project (subproject) folder, see gradle/gradle#3417 To filter files outside project dir, use:
exclude { element -> element.file.path.contains("generated/") }
Developers
Importing
Import the settings.gradle.kts file into your IDE.
To enable the Android sample either define the ANDROID_HOME
environmental variable or
add a local.properties
file to the project root folder with the following content:
sdk.dir=<android-sdk-location>
Building
Building the plugin: ./plugin/gradlew build
On how to run the current plugin snapshot check on sample projects: ./gradlew ktlintCheck
IDEA IDE
Running tests fromTo run tests in IDEA IDE, firstly you need to run following gradle task (or after any dependency change):
$ ./plugin/gradlew pluginUnderTestMetadata
Optionally you can add this step test run configuration.