I'm having trouble figuring out how to force a task to always run after another one. I'm aware of dependsOn, but taskA.dependsOn taskB will cause taskB to execute first. I'm also aware of mustRunAfter and shouldRunAfter, but taskB.mustRunAfter taskA does not force taskB to run, it only ensures that IF both are called, taskA runs first. IF I use both, I get a circular dependency error.
I want gradle taskA to cause taskA to run, then taskB to run.
I was looking for finalizer tasks. Use the method finalizedBy():
taskA.finalizedBy taskB
Related
I want to execute a gradle build command from build.gradle file.
build.gradle file
apply plugin: 'java'
apply plugin: 'application'
task me{
//Can we perform gradle build command here.
}
Question:
Can we perform gradle build command inside task me, similarly like we do from command prompt(screenshot attached)..?
Note : I am using windows env, please assume I am providing all other statements in build.gradle file.
I am able to build from command prompt by executing
.
I want to execute this task me from command prompt and it should be responsible to call gradle build command.(attached screenshot)
Yes, if you make the task me to a task of type GradleBuild
https://docs.gradle.org/current/dsl/org.gradle.api.tasks.GradleBuild.html
E.g.
task me(type: GradleBuild){
buildFile 'mybuild.gradle' //defaults to build.gradle so not needed
dir 'someDir'
tasks 'clean', 'build'
}
You cannot "call" a Gradle task in a Gradle build.
You might stumble upon the method execute() that each Gradle task has, but this is a purely internal method that must not be used by any build script. Using it will not work properly. It will not ensure the task is run only once, it will not ensure dependency tasks are run before and so on and so on, just don't use it.
Your code snippet is too big for me wanting to interpret it right now to understand what you want to do exactly, but if you want to "call" a Gradle task from another Gradle task, your logic is bogus and should be changed. If you want to run a Gradle task before or after another Gradle task is run, the only supported way is to use dependsOn (before) or finalizedBy (after) and you can not set these properties during execution phase of a task but only during configuration phase.
Well, there is one other way to call a Gradle task from a build script, but this is by using a task of type GradleBuild which would start a complete new and separate build of the project you specify which is most often not the action you really want to do.
If taskB depends on taskA, when I execute task A and then taskB...
Question 1: Is taskA executed just once?
Question 2: Is it executed when I run taskA or when I run taskB?
Each Gradle task will only be executed once in a build (Gradle invocation).
Also, the task order you pass to Gradle will only be maintained, if there are no dependencies between them:
If you call gradle taskA taskB, but taskA.dependsOn taskB, taskB will be executed before taskA.
Whether taskB mustRunAfter taskA, or taskB dependsOn taskA, it seems that taskA runs first, then taskB runs. What's the difference?
For example:
tasks.create('a')
tasks.create('b').dependsOn('a')
tasks.create('c')
tasks.create('d').mustRunAfter('c')
dependsOn - sets task dependencies. Executing b here would require that a be executed first.
mustRunAfter - sets task ordering. Executing d does not require c. But, when both c and d are included, c will execute before d.
Where possible, declare task inputs instead of task dependencies. That said, expanding on mkobit's answer:
Ordering and dependencies involving two tasks
mustRunAfter
mustRunAfter controls the execution order of tasks explicitly specified on the command line, but doesn't create implicit dependencies on other tasks. Given taskA and taskB:
build.gradle.kts
val taskA by tasks.registering {
doLast {
println("taskA")
}
}
val taskB by tasks.registering {
doLast {
println("taskB")
}
}
taskB {
mustRunAfter(taskA)
}
then
gradle taskB taskA executes taskA followed by taskB;
gradle taskA executes taskA only;
gradle taskB executes taskB only.
dependsOn
dependsOn creates implicit dependencies on other tasks. Given the same two tasks:
taskB {
dependsOn(taskA)
}
then
gradle taskB executes taskA followed by taskB;
gradle taskB taskA executes taskA followed by taskB;
gradle taskA executes taskA only.
Ordering and dependencies involving three tasks
mustRunAfter and dependsOn accept an unordered collection of tasks. Given:
val taskC by tasks.registering {
doLast {
println("taskC")
}
}
taskC {
dependsOn(taskA, taskB)
}
then gradle taskC executes taskA and taskB in no guaranteed order, followed by taskC (assuming no other dependsOn or mustRunAfter declarations).
mustRunAfter also controls the execution order between interdependent tasks that would otherwise have no guaranteed order. Given:
taskB {
mustRunAfter(taskA)
}
then gradle taskC executes taskA followed by taskB followed by taskC, but gradle taskB only runs taskA because taskB does not dependOn(taskA).
Other types of task dependency
taskA { finalizedBy(taskB) } ensures gradle taskA executes taskA followed by taskB;
shouldRunAfter provides weaker ordering guarantees than mustRunAfter, useful for breaking cyclic dependencies and parallel task execution.
Further reading
Consult the Gradle documentation for more information on:
adding dependencies to tasks
ordering tasks
skipping tasks
Sometimes they have the same effect. For example, if taskC dependsOn taskA and taskB, then it doesn't matter whether taskB dependsOn taskA or mustRunAfter it - when you run taskC, the order will be taskA, taskB, taskC.
But if taskC dependsOn taskB only, then there's a difference. If taskB dependsOn taskA, then it's the same as above - taskA, taskB, taskC. If taskB merely mustRunAfter taskA, then taskA doesn't run, and running taskC will run taskB, then taskC.
mustRunAfter really means if taskA runs at all, then taskB must run after it.
Generally, if order is important, it appears that you need 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)
}
I have a simple project with subprojects and I want to generate aggregate report for all tests when I execute gradle test command.
I have followed the gradle documentation and added following:
task testReport(type: TestReport) {
// make sure this task is run after all subproject test tasks
mustRunAfter subprojects*.test
destinationDir = file("$buildDir/reports/allTests")
// Include the results from the `test` task in all subprojects
reportOn subprojects*.test
}
This works when I execute gradle test testReport, but when I execute gradle test or gradle build in the root project - the task testReport is not run.
How do make gradle to run the task without specifying it every time?
Add: test.finalizedBy 'testReport' to your build.gradle; just at the root level, doesn't have to be inside any closure.
taskX.finalizedBy taskY
Will run taskY everytime taskX completes execution successfully.
I have 2 gradle projects. Lets say projectA and projectB. I need to create a task in projectA, which can execute a task in projectB. I tried with many ways, but i couldn't find a way to do that. Consider following code,
//ProjectA build.gradle
task taskA(dependsOn: ProjectB.taskB) << { println "executed taskB" }
//ProjectB build.gradle
task taskB() << { println "executing taskB"}
when I run taskA output should be,
>> gradle taskA
executing taskB
executed taskB
Can I anyhow achieve this?
thanks.
task taskA(dependsOn: project(":ProjectB").taskB)
We don't say that taskA executes taskB but that it depends on taskB.