Hi
I have a few tasks defined in my build.gradle file, and some dependencies between them.
For example:
task taskA{} ,task preTaskA{…}, task taskA1{…},
task taskB{…}, task taskB1{…}
task taskC{…},(and much more…)
All these tasks have dependencies set up between them, using dependsOn
and mustRunAfter
statements. for example something like that:
taskA.dependsOn preTaskA ....
preTaskA.dependsOn taskA1
taskB.dependsOn taskA, taskB1 ...
taskC.mustRunAfter…
Now, the tasks that a user executes from the command line are only the main ones. for example:
taskA, taskB, taskC.
I want to measure the total time per the main “user executed" tasks and not per “actual” Gradle invoked tasks.
so for example, if I run this:
./gradlew taskA taskC
I want to see the total time it took to run the entire taskA and taskC (including their dependent tasks), and not the total time per executed task like preTaskA, taskA1 and so on.
What I tried to do is:
I have a listener that implements TaskExecutionListener, BuildListener
At beforeExecute
and afterExecute
for every task I sum the time until I have a map contains all the executed tasks and their time.
Then, at buildFinished
method I go over this map and grouping the sub-tasks to know the total execution per user-input “main” task.
class TimingsListener implements TaskExecutionListener, BuildListener {
private long taskStartTime
private taskTiming = [:]
private tasksTreeMap = [
"taskA":["preTaskA","taskA1", "taskA"],
"taskB":["preTaskA", "taskA1", "taskB", "taskB1"],
"taskC":["..."]
].withDefault{key -> return []}
@Override
void beforeExecute(Task task) {
taskStartTime = System.currentTimeMillis()
}
@Override
void afterExecute(Task task, TaskState taskState) {
def timePerTask = System.currentTimeMillis() - taskStartTime
taskTiming[task.getName] = timePerTask
}
@Override
void buildFinished(BuildResult result) {
def totalTimePerTaskMap = [:]
def userExecutedTasks = result.getGradle().getStartParameter().getTaskNames()
for(task in userExecutedTasks){
def totalTimePerTask = 0
for(subTask in tasksTreeMap[task]){
totalTimePerTask += taskTiming[subTask]
}
totalTimePerTaskMap[task]= totalTimePerTask
}
}
My Questions:
- is there an easier and simpler way of doing this?
- If not, can I programmatically get the dependent tasks per Task? for example, when a user performs
gradle taskA
I’ll get a list of “taskA, preTaskA, taskA1”? it will save me the need to define and maintain thetasksTreeMap
static map. - if I’ll go with a different approach and will use a custom task (logTime that gets the task name as a parameter) that will be invoked before & after “user-input” tasks, for example:
taskA.dependsOn logTimeStart, preTaskA...
logTimeEnd.mustRunAfter taskA
how can I pass the custom tasks - logTimeStart & logTimeEnd the task name parameter?
taskA.dependsOn logTimeStart("taskA"), preTaskA...
logTimeEnd("taskA").mustRunAfter taskA
I tried to add as many details as possible, as I think other ppl might benefit from this answer as well.
Thank you!