Build a module with a task - gradle

I wanted to build a particular module from my project via a task, which will in turn run its tests. Basically I want to execute, "gradle :module:build" from a task.
task thatBuildsTheModule() << {
.....
}
task A() << {
......
tasks.thatBuidsTheModule.execute()
......
}
How can I do this ?

You're close. It's not recommended to call execute on a task. Instead use the task graph and make your builder task a dependant of your A task, labeled anotherTask in this example
// create builder task
task thatBuildsTheModule << {
println "Hello $it.name"
}
// create our other task
task anotherTask << {
println "Hello $it.name"
}
// make `anotherTask`'s execution depend on the execution of our builder task
anotherTask.dependsOn thatBuildsTheModule
Now we can see that executing just the anotherTask task we also execute the thatBuildsTheModule task
$ ./gradlew -q anotherTask
Hello thatBuildsTheModule
Hello anotherTask

Related

Creating a task that runs before all other tasks in gradle

I need to create an initialize task that will run before all other task when I execute it.
task A {
println "Task A"
}
task initializer {
println "initialized"
}
If I execute gradle -q A, the output will be:
>initialized
>Task A
Now if i'll add:
task B {
println "Task B"
}
Execute gradle -q B, and I get:
>initialized
>Task B
So it doesn't matter which task I execute, it always get "initialized" first.
You can make every Task who's name is NOT 'initializer' depend on the 'initializer' task. Eg:
task initializer {
doLast { println "initializer" }
}
task task1() {
doLast { println "task1" }
}
// make every other task depend on 'initializer'
// matching() and all() are "live" so any tasks declared after this line will also depend on 'initializer'
tasks.matching { it.name != 'initializer' }.all { Task task ->
task.dependsOn initializer
}
task task2() {
doLast { println "task2" }
}
Or you could add a BuildListener (or use one of the convenience methods eg: Gradle.buildStarted(...))
Seems like you aim execution phase, and you want a task precursing each task or just run as a first task in the execution phase?
If you want a task to always execute in every project before each other task after its being evaluated you can add a closure to he main build.gradle:
allprojects {
afterEvaluate {
for(def task in it.tasks)
if(task != rootProject.tasks.YourTask)
task.dependsOn rootProject.tasks.YourTask
}
}
or
tasks.matching {it != YourTask}.all {it.dependsOn YourTask}
You can also use the Task Execution Graph to define the lifecycle. There are few ways of achieving your goal, depending on your needs and a project structure.
The previously suggested solution with dependsOn works fine, but I don't like about it that it changes and clutters the task dependencies. The first solution coming to my mind is using Gradle Initialization Scripts. They are really cool. But, the usage is a bit tedious: currently there is no way to have a default project-local Gradle init script. You have to either explicitly specify the script(s) on command line, or place them in USER_HOME/GRADLE_HOME.
So another solution (already briefliy mentioned by #lance-java) which can be used to run some initialization, like a init task/script, is "build listeners". Depending on how early/late the initialization code should run, I use one of these two:
gradle.afterProject {
println '=== initialized in afterProject'
}
or
gradle.taskGraph.whenReady {
println '=== initialized in taskGraph.whenReady'
}
Here the docs of the Gradle interface and of BuildListener.
Note that some of the events occur very early, and you probably can't use them because of that, like e.g. beforeProject and buildStarted (explanations here and there).

How to execute 'clean' task in the end of my custom task?

I've create my own simple task so I want to clean before test
task cleanTest (group: 'test setup', description: 'clean then test.'){
dependsOn 'clean'
dependsOn 'test'
tasks.findByName('test').mustRunAfter 'clean'
}
After my task is finished I want to run clean task
Iv'e tried
configure(subprojects) {
task clean << {
println "Do clean " + project.name
}
task test(dependsOn: clean)<<{
println 'test ' + project.name
}
task cleanTest(dependsOn: cleanTest)<<{
parent.cleanTest.execute()
}
}
All I want is to run 'clean task in the end of my custom task
This is not possible. You cannot run a task multiple times in one Gradle run. So if you want to do the same actions before and after your task, define a method that you run before and after the task. Using Task.execute() is not cleanly possible. Never ever do or even try this. It is a purely internal method that should never-ever-ever be called directly by any build ever. It is prone to produce strange and unpredictible results.
What you want is probably something around the lines of
subprojects {
def cleanIt = {
println "Do clean " + project.name
}
clean.doLast {
cleanIt()
}
task test(dependsOn: clean) {
doLast {
println 'test ' + project.name
}
}
task cleanTest(dependsOn: cleanTest) {
doLast {
cleanIt()
}
}
}
If you want to clean before test then simply make test depend on clean. That makes sure that before every test, clean is executed. This is how gradle does stuff.
task clean() {}
task test(dependsOn: clean) {}
There is also question how to run clean after mytask.. To run clean task after mytask you can use thirdtask depending on both and specify forced order between clean and mytask
task clean() {}
task mytask() {}
task thirdtask(dependsOn: [clean, mytask]){}
clean.mustRunAfter mytask
If the question was whether you can run clean task multiple times in a single build then that is not possible and see answer from Vampire to share the code.

Gradle - How to set dependency tasks for Exec-type tasks?

Say, you have following task:
task commandA() {
doLast {
project.ext.ping = 'PING'
}
}
This will work:
task commandB() {
dependsOn commandA
doLast {
println ping
}
}
This will fail:
task commandC(type: Exec) {
dependsOn commandA
commandLine "echo", ping
}
With Could not find property 'ping' on task 'commandC'. error message.
So, how one can declare dependency for an exec-type task and set some variable in that dependency?
Just don't initialize the variable within the doLast block, since it's getting initialized at the execution phase, but commandLine "echo", ping is trying to get it at the configuration phase of the build.
So, you need something like that:
task commandA() {
project.ext.ping = 'PING'
}
Or even without task, as follows:
project.ext.ping = 'PING'
Because configuration of any task is always executed, even if the task's action won't be executed.
Another solution is to use exec-action, not exec-task, something like this:
task commandA() {
doLast {
project.ext.ping = 'PING'
}
}
task commandC {
dependsOn commandA
doLast {
exec {
commandLine ping, "192.168.100.1"
}
}
}
In this case, exec-closure will be done during execution phase wuth the ping variable already available.
You can read about build lifecycle in the official Gradle user guide

Running the same task multiple times during execution in gradle

Is it possible to have some like the following in gradle
task enableMe() << {
println "Enable"
}
task disableMe() << {
shouldRunAfter 'taskAwork'
println "Disable"
}
task taskAwork(){
shouldRunAfter 'enableMe'
println "do work in A while disabled"
}
task taskA(dependsOn: disableMe, taskAwork, enableMe){
}
task taskBwork(){
shouldRunAfter 'enableMe'
println "do work in B while disabled"
}
task taskB(dependsOn: disableMe, taskBwork, enableMe){
}
task taskC(dependsOn: taskA, taskB){
}
So that when it runs the tasks are executed in the order
disableMe
taskAwork
enableMe
disableMe
taskBwork
enableMe
but currently, disableMe and enableMe only run once.. is there anyway to set there status so that they can run again.
The only way I can think to do this is to duplicate the tasks;
task enableMeA() << {
println "Enable"
}
task disableMeA() << {
shouldRunAfter 'taskAwork'
println "Disable"
}
task enableMeB() << {
println "Enable"
}
task disableMeB() << {
shouldRunAfter 'taskBwork'
println "Disable"
}
task taskAwork(){
shouldRunAfter 'enableMeA'
println "do work in A while disabled"
}
task taskA(dependsOn: disableMeA, taskAwork, enableMeA){
}
task taskBwork(){
shouldRunAfter 'enableMeB'
println "do work in B while disabled"
}
task taskB(dependsOn: disableMeB, taskBwork, enableMeB){
}
task taskC(dependsOn: taskA, taskB){
}
Seems, in your case, you have to implement TaskExecutionListener for your task and use it's beforeExecute and afterExecute methods to implement your logic.
This could look something like:
task taskAwork() << {
println "do work in A while disabled"
}
task taskBwork() << {
println "do work in B while disabled"
}
task doAllWorkTask(dependsOn: [taskAwork, taskBwork]){
}
gradle.taskGraph.addTaskExecutionListener new WorkTasksExecutionListener()
class WorkTasksExecutionListener implements TaskExecutionListener {
#Override
void afterExecute(final Task task, final TaskState state) {
if (task.name.contains('work')) {
println('Enabling smth before execution of work task')
}
}
#Override
void beforeExecute(final Task task) {
if (task.name.contains('work')) {
println('Disabling smth after execution of work task')
}
}
}
Here is specified 2 tasks, which do something and requires some common loigic to be run before and after each one. To implement this common logic, used WorkTasksExecutionListener implementing TaskExecutionListener interface and registered as a listener in the taskGraph.
WorkTasksExecutionListener implenets 2 methods of the TaskExecutionListener: beforeExecute and afterExecute. This methods are getting called before and after each tsk execution, so in it's implementation was added the condition to check whether the task do some work and if yes, then some additional logic executed.
Output in this case will be:
:taskAwork
Enabling smth after execution of work task
do work in A while disabled
Disabling smth before execution of work task
:taskBwork
Enabling smth after execution of work task
do work in B while disabled
Disabling smth before execution of work task
:doAllWorkTask
Gradle, by default, will not run a task which is up-to-date.
Task is considered up-to-date if it's TaskOutputs property hasn't been changed.
If you want to run a task several times during the same execution, you can use upToDateWhen property to define a predicate that will return false whenever you want the task to run again:
task myTask() {
outputs.upToDateWhen {some_condition}
// Do some stuff
}

Gradle: run a clean up task at every execution (test, build, etc.)

I have a simple custom task that cleans up some local properties files to work for the given dev environment. I'd like Gradle to run this task every time I run any command, e.g., test, build, clean, etc.
Is there a way to do so?
The standard way is to declare the dependency on every task such as:
task myclean() << {
println "myclean"
}
task mytask1(dependsOn: myclean) << {
println "mytask1"
}
task mytask2(dependsOn: myclean) << {
println "mytask2"
}
Alternatively you can add a dependency to every task after they have been declared:
task myclean() << {
println "myclean"
}
task mytask1() << {
println "mytask1"
}
task mytask2() << {
println "mytask2"
}
projects.tasks.findAll { it != myclean }.each { it.dependsOn << myclean }

Resources