Reputation: 2979
I'm making a task in gradle that needs to call a number of other tasks.
Here's what I have:
task ci(dependsOn: [
clean,
build,
test
])
What is strange is the output I see:
gradle ci
:compileJava
:processResources UP-TO-DATE
:classes
:jar
:assemble
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE
:check UP-TO-DATE
:clean // cleaning after the build
:build
:ci
Note, that the clean occurs after the build target, which wipes out my build.
If I change my task to:
task ci(dependsOn: [
clean,
test
])
Then it appears to execute in the correct order:
:clean UP-TO-DATE // cleaning before the build
:compileJava
:processResources UP-TO-DATE
:classes
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE
:ci UP-TO-DATE
I tried fixing the original target by adding a build.dependsOn clean, but this seems to have no affect.
Any help is appreciated.
Upvotes: 33
Views: 30091
Reputation: 752
TLDR version: Here's how I did it in one of my projects (without introducing artificial dependencies).
//--- build aliases : define a synonym here if you want a shortcut to run multiple targets
def buildAliases = [
'all' : ['clean', 'assemble', 'runProvisioner', 'stopTomcat', 'installTomcat', 'deployToTomcat', 'startTomcat'],
'rebuild' : ['clean', 'assemble']
]
def expandedTaskList = []
gradle.startParameter.taskNames.each {
expandedTaskList << (buildAliases[it] ? buildAliases[it] : it)
}
gradle.startParameter.taskNames = expandedTaskList.flatten()
println "\n\n\texpanded task list: ${gradle.startParameter.taskNames }\n\n"
In order to make use of these aliases, call them as tasks. Examples:
./gradlew all
./gradlew rebuild
or
gradle all
gradle rebuild
For further background, see :
https://caffeineinduced.wordpress.com/2015/01/25/run-a-list-of-gradle-tasks-in-specific-order/
Upvotes: 9
Reputation: 4923
Using some Groovy/Gradle goodness the solution can be further improved with the following:
def taskNames = [...] // list of task names
task('lastTask', dependsOn: taskNames)
taskNames.inject(null) { acc, val ->
if (acc != null) tasks[val].mustRunAfter acc
tasks[val]
}
this way, you can have one place with a list of tasks.
Upvotes: 0
Reputation: 607
I would prefer not to add wrapper task just to make sure an order.
In this case, my solution is as follows -
run.dependsOn 'clean'
compileJava.mustRunAfter 'clean'
This makes sure that, clean
task executes before gradle executes compileJava
. So effectively, you will create a fresh build all the time.
Hope this helps.
Upvotes: 4
Reputation: 2979
It seems I've stumbled upon the issue being debated in GRADLE-427 in which gradle determines the best order to execute the tasks. I resolved my problem by following the advice therein which is also documented in the Gradle User Guide - Section 15.5 to establish ordering between disparate tasks. My final ci target thus appears as:
task ci(dependsOn: ['clean', 'build', 'uploadArchives'])
build.mustRunAfter clean
uploadArchives.mustRunAfter build
And everything now works as expected.
Upvotes: 43