Gradle custom task which runs multiple tasks
GradleGradle Problem Overview
I wanna run multiple gradle tasks as one. So instead of
./gradlew clean build publish
I want to have a custom task
./gradlew cleanBuildPublish
that executes clean
build
and publish
in order.
How's that possible?
This does not work
task cleanBuildPublish {
dependsOn 'clean'
dependsOn 'build'
dependsOn 'publish'
}
Gradle Solutions
Solution 1 - Gradle
If you need to execute some tasks in predefined order, then you need to not only set dependsOn
, but also to set mustRunAfter
property for this tasks, like in the following code:
task cleanBuildPublish {
dependsOn 'clean'
dependsOn 'build'
dependsOn 'publish'
tasks.findByName('build').mustRunAfter 'clean'
tasks.findByName('publish').mustRunAfter 'build'
}
dependsOn
doesn't define an order of tasks execution, it just make one task dependent from another, while mustRunAfter
does.
Solution 2 - Gradle
You can also use the task base class called GradleBuild
Here how you can do that with GradleBuild
Groovy DSL:
task cleanBuildPublish(type: GradleBuild) {
tasks = ['clean', 'build', 'publish']
}
Kotlin DSL:
tasks.register<GradleBuild>("cleanBuildPublish") {
tasks = listOf("clean", "build", "publish")
}
Solution 3 - Gradle
My approach is
task cleanBuildPublish (type: GradleBuild, dependsOn: ['clean', 'build', 'publish']) {
}
This works for me.
Solution 4 - Gradle
Try below way to make cleanBuildPublish depend on other tasks
build.gradle
task clean{
println "lets clean"
}
task build {
println "lets build"
}
task publish {
println "lets publish"
}
task cleanBuildPublish{
println 'lets do all'
}
cleanBuildPublish.dependsOn clean
cleanBuildPublish.dependsOn build
cleanBuildPublish.dependsOn publish
Output
$ gradle cleanBuildPublish
lets clean
lets build
lets publish
lets do all
:build UP-TO-DATE
:clean UP-TO-DATE
:publish UP-TO-DATE
:cleanBuildPublish UP-TO-DATE
BUILD SUCCESSFUL
Total time: 2.738 secs
check https://docs.gradle.org/current/userguide/more_about_tasks.html#addDependencyUsingTask for more details
Solution 5 - Gradle
If publish task is in a sub project named subProjectName,
...
tasks.findByPath(':subProjectName:publish').mustRunAfter 'build'
...
Solution 6 - Gradle
A generic way to get it, would be the following:
task cleanBuildPublish {
def containedTasks = [clean, build, publish]
dependsOn containedTasks
placeTasksInOrder(containedTasks)
}
def placeTasksInOrder(List tasks) {
for (int i=0; i < tasks.size() -1; i++) {
def earlierTask = tasks.get(i)
def laterTask = tasks.get(i +1)
laterTask.mustRunAfter(earlierTask)
}
}
dependsOn
causes the other tasks to run when cleanBuildPublish
is run and the helper function placeTasksInOrder
place the tasks in order by calling mustRunAfter
When executing gradlew cleanBuildPublish somethingElse
the order will be clean, build, publish, somethingElse
Beware:
The following solution does NOT work if you have nested gradle calls
task cleanBuildPublish(type: GradleBuild) {
tasks = ['clean', 'build', 'publish']
}
When executing gradlew cleanBuildPublish somethingElse
, then it could happen, that somethingElse
will be called first.
So one should better use the mustRunAfter
configuration.
Solution 7 - Gradle
Here is how I did it, with Kotlin scripting, using both dependsOn and mustRunAfter. Here is an example of running two tasks, one (custom registered "importUnicodeFiles" task) that is in "this" project and one (predefined "run" task) that is in a sibling project named ":unicode":
tasks.register("rebuildUnicodeFiles") {
description = "Force the rebuild of the `./src/main/resources/text` data"
val make = project(":unicode").tasks["run"]
val copy = tasks["importUnicodeFiles"]
dependsOn(make)
dependsOn(copy)
copy.mustRunAfter(make)
}
The Gradle developers generally advise against this approach (they say that forcing ordering is bad, and that executing tasks from other projects is bad), and are working on a way to publish results between projects; see: https://docs.gradle.org/current/userguide/cross_project_publications.html
Solution 8 - Gradle
My solution is as follows and it works for me.
task cleanBuildPublish {
task _clean {
dependsOn 'clean'
}
task _build {
dependsOn '_clean'
dependsOn 'build'
}
dependsOn '_build'
dependsOn 'publish'
}
Solution 9 - Gradle
Try adding defaultTasks
in build.gradle. For eg.
defaultTasks 'clean', 'build', 'publish'