Gradle implicity run another task - gradle

I have two task
task Hello {
println 'Hello'
}
task World {
println 'Hello1'
}
If I run World task Hellowill run also. If I modify my tasks in this way
task Hello {
doLast {
println 'Hello'
}
}
task World {
println 'Hello1'
}
then task Hellowon't run. How do doLast{} or doFirst{} sections affect running tasks in gradle?
I can't find information in gradle docs about that. Thx.

The task Hello doesn't run. It's configured.
The code inside the curly braces is the code that configures the task. This code is always executed, whatever the task you tell gradle to run. It must run so that gradle knows what the task does, on which other task it depends, which other task it finalizes, etc.
Once the configuration phase has finished, the execution phase starts. And in that phase, the task that you asked to execute is executed/ In that phase, the code passed to doLast is being executed.
Here's the documentation.

Related

Is it possible to execute a task from within doLast?

I have the following:
task copyToLib(type: Copy) {
from configurations.runtime
into "$buildDir/output/lib"
doLast { copyOpcThirdParty() } // this doesnt get executed
}
task copyOpcThirdParty(type: Copy) {
from "$projectDir/libs/opc/thirdparty"
into "$buildDir/output/lib/thirdparty/"
}
How can I call copyOpcThirdParty from copyToLib.doLast?
I tried .execute(), tasks.copyOpcThirdParty, etc, nothing worked..
Is it unsupported?
In Gradle tasks are not executed directly. Instead you can register dependencies and Gradle then decides which tasks to execute in which order to achieve the execution of the tasks you specified (generally via command line). In older versions of Gradle you can call execute() directly on a task, but it should never be used.
When executing the tasks, the execution of one task must always be completely finished until another task can be executed. The execution of a task always covers running all doFirst closures, all internal task actions and all doLast closures.
For your specific example you can use the finalizedBy method. It tells Gradle that whenever a specific task runs, at some point after that another specific task also has to run:
copyToLib.finalizedBy copyOpcThirdParty

Depend on multiple gradle tasks in multi project build

Currently I have task which starts Google Cloud server, runs tests and stops server. It is defined at root project:
buildscript {...}
allprojects {...}
task startServer (dependsOn: "backend:appengineStart") {}
task testPaid (dependsOn: "app:connectedPaidDebugAndroidTest") {}
task stopServer (dependsOn: "backend:appengineStop") {}
task GCEtesting {
dependsOn = ["startServer",
"testPaid",
"stopServer"]
group = 'custom'
description 'Starts GCE server, runs tests and stops server.'
testPaid.mustRunAfter 'startServer'
stopServer.mustRunAfter 'testPaid'
}
I tried multiple ways to write it something like this, short with only one task. I didn't get how to refer to task from another project and call mustRunAfter on it. This doesn't work (I also tried to refer from Project.tasks.getByPath, root.tasks, etc):
task GCEtesting {
dependsOn = ["backend:appengineStart",
"app:connectedPaidDebugAndroidTest",
"backend:appengineStop"]
group = 'custom'
description 'Starts GCE server, runs tests and stops server.'
"app:connectedPaidDebugAndroidTest".mustRunAfter "backend:appengineStart"
"backend:appengineStop".mustRunAfter "app:connectedPaidDebugAndroidTest"
}
Is it possible? What is correct syntax to make this work?
It looks like your problem is that you're treating dependsOn as meaning "invoke this task". It actually means "ensure the result of the depended on task is available before the dependent task starts". That's why your first solution didn't work: statements like testPaid.mustRunAfter only affect the actions of the testPaid task itself, not its dependencies.
Anyway, you can get the behaviour you want using dependsOn and finalizedBy, but they have to be declared in the build file of the app subproject.
app/build.gradle:
task connectedPaidDebugAndroidTest {
//
//...
//
dependsOn 'backend:appengineStart' // Ensure appengineStart is run at some point before this task
finalizedBy 'backend:appendginStop' // Ensure appengineStop is run at some point after this task
}
Then, you can run your tests simply with gradle app:connectedPaidDebugAndroidTest. If you really want to define a task in the root project to run the tests, then that's easy too:
build.gradle:
task GCEtesting {
dependsOn = "app:connectedPaidDebugAndroidTest"
}

Why does gradle run every task in gradle.build

I'm very new to gradle and have a basic question.
When I add a custom task to my gradle.build file and call "gradlw build" or "gradle clean" or any other gradle command,
it automatically runs my custom task.
Is that how things work in gradle? run every task in the build file?
Is there way to run a task only when I want it manually?
task foo {
println 'hello'
}
That creates a task, and during the configuration of the task, it tells gradle to execute println 'hello'. Every task is configured at each build, because gradle needs to know what its configuration is to know if the task must be executed or not.
task foo << {
println 'hello'
}
That creates a task, and during the execution of the task, it tells gradle to execute println 'hello'. So the code will only be executed if you explicitly chose to run the task foo, or a task that depends on foo.
It's equivalent to
task foo {
doLast {
println 'hello'
}
}
You chose not to post your code, probably assuming that gradle was acting bizarrely, and that your code had nothing to do with the problem. So this is just a guess, but you probably used the first incorrect code rather than the second, correct one.

Why can't see all task when use 'tasks' task in Gradle?

task startSession << {
chant()
}
def chant() {
ant.echo(message: 'Repeat after me...')
}
3.times {
task "yayGradle$it" << {
println 'Gradle rocks'
}
}
yayGradle0.dependsOn startSession
yayGradle2.dependsOn yayGradle1, yayGradle0
task groupTherapy(dependsOn: yayGradle2)
In my script I have startSession task, groupTherapy task and three dynamically generated tasks yayGradle0-3. When I am executing:
gradle tasks
Part of the output is:
Other tasks
-----------
groupTherapy
Where are the other tasks? If I execute the command above with parameter --all they are visible but not as indipendant tasks but like dependent on groupTherapy. Why Gradle doesn't show task startSession as separate task for example?
gradle tasks show tasks that no other task depends on, and tasks that have task.group set. The idea is that these are the tasks that are clearly meant to be executed directly, whereas the (often many) remaining tasks aren't. gradle tasks --all shows all tasks.

Understanding Gradle task dependency (dependsOn)

Two questions:
What is the gradle way to specify that 1 task is comprised of several other tasks?
It seems like gradle's taskName.execute() method does not honor the dependsOn relationships of taskName is this true and what is the work-around?
More background:
Right now I have a build script that has no plugins (not Java in other words). I want a task called tests that will run all my test tasks. I have 3 such tasks. Call them task1, task2, and task3.
I could say tests.dependsOn ['task1', 'task2', 'task3']
This is a bit wonky because the relationship seems to be tests.isComprisedOf ['task1', 'task2', 'task3']
I could say:
task tests << {
task1.execute()
task2.execute()
task3.execute()
}
but then task3, which itself depends on taskSetup, runs without running taskSetup. In other words the execute() call does not seem to honor gradle's dependencies resolution strategy.
One last small gripe (I really do love gradle by the way), is that it is hard to search on this topic because dependency means two different things in gradle: dependsOn style dependencies and library style dependencies.
Typically, you do not invoke task.execute().
You can specify that one task is comprised of other tasks in the following manner:
task task1 << {
println "Hello"
}
task task2 << {
println "World"
}
task task3(dependsOn: 'task3dependency') << {
println "QBert"
}
task task3dependency << {
println "MR"
}
task tests(dependsOn: ['task1', 'task2', 'task3'])
This outputs:
$ gradle tests
:task1
Hello
:task2
World
:task3dependency
MR
:task3
QBert
:tests
BUILD SUCCESSFUL
Keep in mind that the order in which your dependency tasks are run is not always guaranteed, but you can mitigate this by specifying the order task2.mustRunAfter task1. Usually though, the tasks are run in the order you would expect.
Also, you should read up on Gradle's Build Lifecycle. When you use the syntax task task1 << {...}, you are specifying a closure that is run in the execution phase of the task. Before execution is run, the configuration phase evaluates your build script and determines the tasks to be run and in what order. When you manually execute tasks, as in:
task tests << {
task1.execute()
task2.execute()
task3.execute()
}
you have bypassed Gradle's ability to evaluate the task dependencies of task3, hence it runs only task3.
Gradle's task model is "flat" and doesn't have a concept of aggregation. (It's important to note that TaskInternal#execute is an internal method, and must not be called from build scripts.) Aggregation is often simulated with a lifecycle task (a task with task dependencies but without any task actions):
task allTests {
dependsOn tasks.withType(Test)
}
Besides dependsOn, the following task relationships are supported: mustRunAfter, shouldRunAfter, and finalizedBy.

Resources