
The easiest way to reduce build times is to not do anything unnecessary.
Gradle has support for making tasks incremental. Tasks can define their own inputs and outputs. Gradle will determine whether they have changed or not. In case they have, Gradle will execute your task otherwise it won’t and you’ll see up-to-date
in the command line interface.
Example task
Let’s consider this task to let ktlint run on your project:
def outputDir = "${project.buildDir}/reports/ktlint/"
def outputFile = "${outputDir}ktlint-checkstyle-report.xml"project.task("ktlint", type: JavaExec) {
group = "verification"
description = "Runs ktlint."
main = "com.github.shyiko.ktlint.Main"
classpath = project.configurations.ktlint
args = [
"--reporter=plain",
"--reporter=checkstyle,output=${outputFile}",
"src/**/*.kt"
]
}
If we run it once, it’ll do all of the work. Running the task a second time will do the same work — again. It’s unnecessary. We haven’t changed any of the Kotlin files and hence we know that we don’t need to redo the work.
Making it incremental
In order to make this task incremental we’ll have to define inputs and outputs.
def outputDir = "${project.buildDir}/reports/ktlint/"
def inputFiles = project.fileTree(dir: "src", include: "**/*.kt")
def outputFile = "${outputDir}ktlint-checkstyle-report.xml"project.task("ktlint", type: JavaExec) {
inputs.files(inputFiles)
outputs.dir(outputDir)
// Here comes the previous configuration.
}
The Gradle task gives us inputs and outputs APIs.
- For inputs we can simply give it a file tree structure of all Kotlin files in the source folder
- Outputs is even easier as we’ll take the output directory where the report will be stored
If we run this task now, it will be executed.

Next time though, Gradle is doing it’s magic with our defined inputs and outputs and tells us…