Understanding tasks

satya - 10/30/2019, 10:31:12 AM

Understand, with example, the following topics

1. Create a task

2. Locate a task

3. Configure a task

4. Create a typed task

5. Configure a typed task

6. Show some sample code to understand printing etc

7. Create task dependencies

8. List all tasks

9. List task tree with dependencies

satya - 10/30/2019, 10:34:08 AM

1. Creating tasks

1. Creating tasks

satya - 10/30/2019, 10:35:05 AM

Basics of tasks and working with tasks is documented at Gradel site here

Basics of tasks and working with tasks is documented at Gradel site here

satya - 10/30/2019, 10:36:31 AM

Next up is the "Authoring Tasks" document at gradle

Next up is the "Authoring Tasks" document at gradle

This is the primary resource I am hoping to use for this document

satya - 10/30/2019, 10:37:19 AM

This was my previous first contact document with gradle

This was my previous first contact document with gradle

satya - 10/30/2019, 10:39:53 AM

My High level conceptual understanding of Gradle is here

My High level conceptual understanding of Gradle is here

satya - 10/30/2019, 10:40:23 AM

Readme for this knowledge folder is here

Readme for this knowledge folder is here

satya - 10/30/2019, 10:40:58 AM

Problem with creating tasks is, there are MANY MANY syntactical ways of creating tasks!!

Problem with creating tasks is, there are MANY MANY syntactical ways of creating tasks!!

satya - 10/30/2019, 10:49:25 AM

Few ways to start with


//Simple task: Calls a method project.task()
//you can see the API for project
task('hello') {}


//Copy is a java class
task('copy', type: Copy) {}


//tasks is a property of the project object
//of type TaskContainer
tasks.create('hello') {}

//Apparently this is the same

task(hello) {}

satya - 10/30/2019, 10:50:17 AM

That kind of boils down to 3 ways


task('hello') {}
task(hello) {}
tasks.create('hello'){}

satya - 10/30/2019, 10:51:07 AM

One common pattern is ...

All 3 ways have a "function" call syntax with "()" with braces to enclose the task name

satya - 10/30/2019, 10:52:45 AM

To be complete


task(hello) {
   doLast {
      println 'this is from hello task'
   }
}

satya - 10/30/2019, 4:04:21 PM

Actually there are 4 ways


task('hello') {}
task(hello) {}

task hello {} //No braces or quotes

tasks.create('hello'){}

satya - 10/30/2019, 4:04:46 PM

Creating custom tasks is documented here

Creating custom tasks is documented here

satya - 10/30/2019, 4:05:00 PM

I will cover that later

I will cover that later

satya - 10/30/2019, 4:33:32 PM

Task API Javadoc is documented here

Task API Javadoc is documented here

satya - 10/30/2019, 4:34:16 PM

TaskContainer API is documented here

TaskContainer API is documented here

satya - 10/31/2019, 2:20:58 PM

Sample code for creating various tasks


/*
 * Understand Gradle tasks: Creating tasks
 */

//***************************************************************
//Project.getBuildscript(): ScriptHandler is the closure delegate
//So look for the method signatures on ScriptHanlder class
//***************************************************************
buildscript {
  //This line appears first
   println "1. in buildscript"
}

//Rest of the execution 
println "2. Rest of the script begins"

//**************************************************
//Many ways of creating tasks in gradle
//**************************************************

//Creating without a formality
//**************************************************
task hello {
  println 'Creating a task called hello'
  doLast {
    println 'Executing hello'
  }
}

//Creating with a function call
//**************************************************
task ("hello2") {
  println 'Creating a task called hello2 as a function call'
  doLast {
    println 'Executing hello2'
  }
}

//Strange syntax. Creatin without string quotes
//**************************************************
task (hello3) {
  println 'Creating a task called hello3 as a function call'
  doLast {
    println 'Executing hello3'
  }
}

//Using the taskContainer (collection) to create
//**************************************************
tasks.create('hello4') {
  println 'Creating a task called hello4 using task container'
  doLast {
    println 'Executing hello4'
  }
}

//**************************************************
//Define a task called build 
//so that it can be made a default task
//later, so we have an anchor point to call tasks
//**************************************************
task build {
  //we can define dependencies here during creation
  // Or locate this task by name and define the dependencies there

  //Uncomment the following if you want to define them
  //dependsOn hello, hello2, hello3
}

//**************************************************
// Examine what happens to a task.
// API can be found at org.gradle.api.task;
//
// You will see following printed
// *********************************
// Name of the build task is:(build)
// Path of the build task is:(:build)
// build task object itself:(task ':build')
//**************************************************
println ("Name of the build task is:(" + build.name + ")")
println ("Path of the build task is:(" + build.path+ ")")
println ("build task object itself:(" + build+ ")")

//**************************************************
// Define a default task to execute by running
// gradle (with out any args)
//**************************************************
defaultTasks 'build'

/*
* Invalid Block
**********************************************
* The name build is now allocated to an object
* it points to a task object called build
* defaultTasks is a method that takes a list of strings
**********************************************
defaultTasks build
***********************************************
*/

//**************************************************
// Goal: Define dependencies for the tasks
//
// Locate build task
// Define a dependency on another task
// This is seen as a way to locate the task named build
//**************************************************
build {
  dependsOn hello, hello2, hello3, hello4

  doLast {
    println 'All dependent tasks completed'
    println 'build finished'
  }
}

satya - 10/31/2019, 2:23:12 PM

You can locate this code in github as well

You can locate this code in github as well

satya - 10/31/2019, 2:29:55 PM

2 Moving on to locating tasks

2 Moving on to locating tasks

satya - 10/31/2019, 2:37:45 PM

When a task is created

1. It becomes a member of the task collection (taskContainer) in the project object

2. it is also added with the same name as a property of the project object

3. Because of 2 the task name is available as a direct variable in the script. This is facility in gradle is called dynamic properties where properties are added during run time to a compiled class

satya - 10/31/2019, 2:40:15 PM

Example


//create a task 
task hello {}

//access and configure it now
hello.configure {}

//access it and print it
println "name of hello is: ${hello.name}"

//Or via the project
//access it and print it
println "name of hello is: ${project.hello.name}"

satya - 10/31/2019, 2:41:54 PM

You can locate it from tasks as well


def helloTaskObject = tasks.getByName('hello')
println "From tasks: ${helloTaskObject.name}"

//This will not work to configure it
helloTaskObject {}

//Because it is an object and not a method
//Closures syntax work on methods

//So use the correct method to configure
helloTaskObject.configure {
  doLast {
    println 'hello task explict configuration'
  }
}

satya - 10/31/2019, 2:42:52 PM

Locate and configure at the same time using tasks


//Whereas this works because getByName can take 2 args.
//the second arg is config closure.

//internally the getByName does both
//1. locate the task
//2. Run the configure on it :)

tasks.getByName('hello') {
  doLast {
    println 'hello task implicit configuration'
  }
}

satya - 10/31/2019, 2:56:04 PM

Look at the methods available on a project object

Look at the methods available on a project object

satya - 10/31/2019, 2:56:52 PM

Method project(path, configureAction)

Locates a project by path and configures it using the given action. If the path is relative, it is interpreted relative to this project.

satya - 10/31/2019, 3:00:12 PM

Now the code below makes sense


//Locate a project
*****************************
project(':projectA') {
    //Create a task there
    task hello
}

//Local hello task
*****************************
task hello


//There are 2 tasks now named the same
***************************************
println tasks.getByPath('hello').path
println tasks.getByPath(':hello').path
println tasks.getByPath('projectA:hello').path
println tasks.getByPath(':projectA:hello').path

//will print
***************************************
:hello
:hello
:projectA:hello
:projectA:hello