Search code examples
gradleconditional-statementstaskexecute

Calling a Gradle Task conditionally


Assume I have 2 tasks:

tasks.register('taskA') {
  // do something
}

tasks.register('taskB') {
  // do something else
}

for my gradle build, I only want to call task "build" and depending on a condition, it should decide which other task to call:

tasks.register('build') {
    doLast {
        if (condition == true) {
            // tasks.named('taskA').execute {}
        } else {
            // tasks.named('taskB').execute {}
        }
    }
}

there is no such function as "execute", but whats the best practice in Gradle to archive that behaviour ? I also read that one should avoid "dependsOn" if possible.


Solution

  • You sample shows that the build task is being created. Generally, this task is already created for you when you apply one of the provided Gradle plugins such as the Java Plugin. The Base Plugin is generally applied when applying a plugin Gradle provides. Some use cases you may apply the plugin manually. This answer assumes the Java plugin is applied, uses the Kotlin DSL, and Gradle 8.


    You can use a task predicate to conditionally execute tasks. The recommendation to avoid using dependsOn is because usually there is an idiomatic way to express your intent in Gradle. In this case, a task predicate is exactly what you need here. For example:

    tasks {
        val taskA by registering {
            onlyIf("condition A is satisfied") {
                1 + 1 == 2
            }
            doLast {
                // task execution logic
            }
        }
        val taskB by registering {
            onlyIf("condition A is satisfied") {
                1 + 1 == 2
            }
            doLast {
                // ...
            }
        }
        build {
            dependsOn(taskA, taskB)
        }
    }
    

    Breaking this down:

    1. Register the task as you did, but make use of the onlyIf predicate. Task will only execute if the predicate is satisfied.
    2. Use doLast { } for your task execution logic. For more complex uses, consider creating a custom task type.
    3. The built-in build task does not carry any meaningful semantics in Gradle, it is a "catch all" build everything task. So, it is fine to use dependsOn in this case.