Gradle support the definition of so called live collections. These collections are mostly created based on criteria like with a filter() or matching() method. The collection content can change if the content of the source collection changes. For example the org.gradle.api.DomainObjectCollection interface has a matching method that returns a live collection. The list of tasks in a project implements this interface so we can have a live collection of tasks that match a certain criteria.

The nice thing about the live collection of tasks is that we can add tasks to the project after we have defined the task collection and they will be included in the collection. Normally if we would access the list of tasks in a project and use for example a findAll method than the returned list of tasks will not change. So if we add a new task to the project it will not be added to the list of task that apply to the condition of the findAll method.

Now if we use the matching() method on a list of tasks the result will be a live list of tasks. Even if we add tasks to the project after the definition of the list of tasks, they will be added to the collection.

Let's see the following Gradle build file that defines the tasks allCompile and allCopy. Each task has dependencies on other tasks. We use the dependsOn() method of a task to set those dependencies. The dependsOn() method accepts a collection of other tasks. For the allCompile task we don't use a live collection and for the allCopy task we use a live collection.

00.task allCompile << {
01.println 'All is compiled.'
02.}
03.allCompile.dependsOn project.tasks.findAll {
04.it.name.startsWith('compile')
05.}
06. 
07.task allCopy << {
08.println 'Everything is copied.'
09.}
10.// Set dependencies with live collection of tasks.
11.allCopy.dependsOn project.tasks.matching {
12.it.name.startsWith('copy')
13.}
14. 
15.// Add dependency tasks.
16.5.times {
17.// Dependencies for compileAll task.
18.task "compile${it}" << { println 'Compile the code.' }
19. 
20.// Dependencies for copyAll task.
21.task "copy${it}" << { println 'Copy something.' }
22.}

If we run the build script we get the following output:

$ gradle allCompile allCopy
:allCompile
All is compiled.
:copy0
Copy something.
:copy1
Copy something.
:copy2
Copy something.
:copy3
Copy something.
:copy4
Copy something.
:allCopy
Everything is copied.
 
BUILD SUCCESSFUL
 
Total time: 2.232 secs

We notice the allCompile tasks doesn't have any dependencies, because those task dependencies didn't exist when we used the dependsOn() method. The allCopy task has all task dependencies even though we created them later in the build script.

Bonus: we can use the findAll method to look for task dependencies, but we have to let Gradle evaluate this condition in a closure. So we can change our build script and use a closure with the dependsOn() method. Gradle will invoke the closure at execution time and not a configuration time. The dependencies tasks are then available and assigned as dependencies to the allCompile task:

00.task allCompile << {
01.println 'All is compiled.'
02.}
03.// Use closure for resolving task dependencies.
04.allCompile.dependsOn {
05.project.tasks.findAll {
06.it.name.startsWith('compile')
07.}
08.}
09. 
10.task allCopy << {
11.println 'Everything is copied.'
12.}
13.// Set dependencies with live collection of tasks.
14.allCopy.dependsOn project.tasks.matching {
15.it.name.startsWith('copy')
16.}
17. 
18.// Add dependency tasks.
19.5.times {
20.// Dependencies for compileAll task.
21.task "compile${it}" << { println 'Compile the code.' }
22. 
23.// Dependencies for copyAll task.
24.task "copy${it}" << { println 'Copy something.' }
25.}

If we invoke both tasks with Gradle we get the following output:

:compile0
Compile the code.
:compile1
Compile the code.
:compile2
Compile the code.
:compile3
Compile the code.
:compile4
Compile the code.
:allCompile
All is compiled.
:copy0
Copy something.
:copy1
Copy something.
:copy2
Copy something.
:copy3
Copy something.
:copy4
Copy something.
:allCopy
Everything is copied.
 
BUILD SUCCESSFUL
 
Total time: 2.258 secs

This blog post is based on Gradle version 1.0-rc-3

Gradle Goodness: Working with Live Task Collection的更多相关文章

  1. Gradle Goodness: Task Output Annotations Create Directory Automatically

    Gradle Goodness: Task Output Annotations Create Directory Automatically One of the great features of ...

  2. Gradle Goodness: Copy Files with Filtering

    Gradle Goodness: Copy Files with Filtering Gradle's copy task is very powerful and includes filterin ...

  3. Gradle Goodness: Init Script for Adding Extra Plugins to Existing Projects

    Gradle Goodness: Init Script for Adding Extra Plugins to Existing Projects Gradle is very flexible. ...

  4. Gradle Goodness: Group Similar Tasks

    In Gradle we can assign a task to a group. Gradle uses the group for example in the output of $ grad ...

  5. Gradle Goodness: Add Incremental Build Support to Tasks

    Gradle has a very powerful incremental build feature. This means Gradle will not execute a task unle ...

  6. Gradle Goodness: Rename Ant Task Names When Importing Ant Build File

    Migrating from Ant to Gradle is very easy with the importBuild method from AntBuilder. We only have ...

  7. Gradle Goodness: Parse Files with SimpleTemplateEngine in Copy Task

    With the copy task of Gradle we can copy files that are parsed by Groovy's SimpleTemplateEngine. Thi ...

  8. Gradle Goodness: Check Task Dependencies With a Dry Run

    We can run a Gradle build without any of the task actions being executed. This is a so-called dry ru ...

  9. Gradle Goodness: Using and Working with Gradle Version

    To get the current Gradle version we can use the gradleVersion property of the Gradle object. This r ...

随机推荐

  1. openMP编程(上篇)之并行程序设计

    openMP简介 openMP是一个编译器指令和库函数的集合,主要是为共享式存储计算机上的并行程序设计使用的. 当计算机升级到多核时,程序中创建的线程数量需要随CPU核数变化,如在CPU核数超过线程数 ...

  2. jQuery extend方法详解

    先说个概念的东西: jQuery为开发插件提拱了两个方法,分别是: $.fn.extend(item):为每一个实例添加一个实例方法item.($("#btn1") 会生成一个 j ...

  3. Algorithm——两数之和

    题目: 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复利用这个数组中 ...

  4. JS小案例(基础好烦恼少)----持续更新

    *************************************************** <!DOCTYPE html> <html lang="en&quo ...

  5. Common in Hardware & Software

    A lot of common in Hardware programming & Software Programming

  6. CFileDialog 多文件选择

    CString pathName = _T(""); CString fileName = _T(""); CString strMulfilepath = _ ...

  7. 【OBJC】数字转中文大写

    博客园都不知道怎么外链图片…… - (void)numToString:(double)num{ ; NSMutableString *szChMoney = [[NSMutableString al ...

  8. 红黑树(R-B Tree)

    R-B Tree简介 R-B Tree,全称是Red-Black Tree,又称为“红黑树”,它一种特殊的二叉查找树.红黑树的每个节点上都有存储位表示节点的颜色,可以是红(Red)或黑(Black). ...

  9. POI读取xls和xlsx

    import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import  ...

  10. VMWARE里安装时出现'SMBus Host Controller not enabled'

    在虚拟机上运行Linux内核版本为4.7或以上的系统都在安装过程中或在启动时会因为加载intel_powerclamp驱动而导致崩溃.解决办法:1.在启动Ubuntu的时候按住左Shift键:2.Ub ...