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. Yii2.0 新建项目通用准备工作

    1.设置 cookieValidationKey 在 config/web.php 中 config 里有 components项中request有个cookieValidationKey需要配置参数 ...

  2. linux多线程编程——读者优先、写者优先问题

    读者优先描述 如果读者来: 1) 无读者.写着,新读者可以读: 2) 无写者等待,但有其他读者正在读,新读者可以读: 3) 有写者等待,但有其他读者正在读,新读者可以读: 4) 有写者写,新读者等 如 ...

  3. RocketMQ读书笔记1——简述

    [消息队列的功能介绍] 分布式消息队列可以提供应用解耦.流量削峰.消息分发.保证最终一致性.方便动态扩容等功能. [MQ使用场景1——应用解耦] 复杂的系统如电商系统,会存在多个子系统,如订单系统.库 ...

  4. WPF&Silverlight5 常用功能差异

    一晃从Wpf转到sl也有半年多了,总想总结一下wpf和sl的差异,今天终于下笔. 首先来个整体图: 通过上图可以发现其实sl只是使用了wpf的一小部分,只是sl依赖的freamwork有很大部分都一样 ...

  5. 异步nodejs代码的同步样子写法样例

    异步nodejs代码的同步样子写法样例 js的异步嵌套太深代码将不好看.尤其在用node的时候这种情况会大量出现. 这里用node连接redis,做一个用户注册的简单例子来说明.例如用redis做存储 ...

  6. 从Linux访问Windows共享目录

    今天装备用VMWare装台Linux服务器来学习Oracle数据库,由于安装包是下载到本地的Windows系统,需要拷贝到Linux虚机里面去.搞了半天.想到虚机网络设成桥接,然后访问.百度了一下.最 ...

  7. NS Simulation Basic

    这个网站上的一系列讲解NS2的内容真的是深入浅出,看完立刻豁然开朗.所以就接连转了几篇. Scheduling Events那篇里的例子特别好,看完就懂了. http://www.mathcs.emo ...

  8. Maven学习---使用maven进行项目构建

    1. 使用maven进行项目构建 MyEclipse 自带maven 插件 Eclipse 需要单独安装maven插件 1.1. Maven 在企业中怎么用的 ? Maven : 项目构建工具 ,进行 ...

  9. Hadoop学习---Eclipse中hadoop环境的搭建

    在eclipse中建立hadoop环境的支持 1.需要下载安装eclipse 2.需要hadoop-eclipse-plugin-2.6.0.jar插件,插件的终极解决方案是https://githu ...

  10. kill -9 和kill-15的区别

    kill -9大家应该是非常熟悉的,杀死进程一般用kill -9的吧. 今天接触到kill -15,kill -15也是杀死进程的.那个kill -15和kill -9有什么区别呢? 其实kill - ...