Gradle详解-Chapter17. More about Tasks

构建脚本所指就是build.gradle文件

Chapter 14 基础脚本构建

Chapter 16. Writing Build Scripts 写脚本

Chapter17. More about Tasks

Chapter 17. More about Tasks

  17.1. Defining tasks
  脚本基础知识里面讲了一些简单的定义task的方法

// 第一种
task hello {
    doLast {
        println 'Hello world!'
    }
}
// 第二种  << 相当于 doLast
task hello << {
    println 'Hello world!'
}
// 第三种
task(hello) << {
    println "hello"
}
// 第四种  通过字符串创建
task('hello') <<{
    println "hello"
}
// 第五种  通过tasks命令创建task。将单个task添加到tasks集合中
tasks.create(name: 'hello') << {
    println "hello"
}

关于tasks.create()方法可以参考 TaskContainer ,该类有详细的说明,create()方法有多个重构方法。
这里写图片描述

  17.2. Locating tasks 定位task(task调用)
  1,访问task属性

println hello.name
println project.hello.name

  2,通过tasks集合访问task

println tasks.hello.name
println tasks['hello'].name

  3,通过路径path访问task
  可以是task名称,相对路径,绝对路径 

println tasks.getByPath('hello').path
println tasks.getByPath(':project1:hello').path
// 这两种写法错误,不能执行,提示路径path找不到
println tasks.getByPath(':hello').path
println tasks.getByPath('project1:hello').path

结果: .path 属性得到的是绝对路径

D:\GradleTest\project1>gradle -q hello
:project1:hello
:project1:hello

这里写图片描述

* 17.3. Configuring tasks 配置任务(现有类型) *
第一种:创建一个Copy task(没有任何配置)
eg:task myCopy(type: Copy)

这是一个copy task,没有默认行为(方法体)。我们可以用Copy API来配置 copy task

说明一下,该task名称为myCopy,但是是Copy类型。
所以我们可以定义不同名称的 task,但是他们的Type Calss 可以是相同的。

第二种: 局部对象,每次获得对象都必须得”创建”。

Copy myCopy = task(myCopy, type: Copy)
myCopy.from 'resources'
myCopy.into 'target'
myCopy.include('**/*.txt', '**/*.xml', '**/*.properties')

这种就类似于java给属性赋值一样,but,每次配置属性都必须带着名称为 myCopy 的上下文。task(myCopy, type: Copy) 每次都必须得这么写!!!!!所以我们更倾向于第三种配置方式。

第三种:成员对象。声明一次,多出调用。常用

task myCopy(type: Copy)
myCopy {
   from 'resources'
   into 'target'
   include('**/*.txt', '**/*.xml', '**/*.properties')
}

第四种: 通过闭包,也就是大括号{}

task copy(type: Copy) {
   from 'resources'
   into 'target'
   include('**/*.txt', '**/*.xml', '**/*.properties')
}

17.4. Adding dependencies to a task 任务依赖

任务依赖是通过task名称来进行操作,task名称可以来自本project也可以来自其他的project。如果task名称来自其他的project,那个task名称需要指定完整的路径。

依赖
eg:路径统一使用相对路径: :project名称:task名称 不要直接使用 project名称

project(':project1') {
    task taskX(dependsOn: ':project2:taskY') << {
        println 'taskX'
    }
}
project(':project2') {
    task taskY << {
        println 'taskY'
    }
}

结果:

D:\GradleTest\project1>gradle -q taskX
taskY
taskX

Adding dependency using task object

task taskX << {
    println 'taskX'
}
task taskY << {
    println 'taskY'
}
// 单独进行操作
taskX.dependsOn taskY
/*
task taskX(dependsOn: 'taskY') << {
    println 'taskX'
}
*/

更高级的使用 and Adding dependency using closure

task taskX << {
    println 'taskX'
}
// 关键点在这里
taskX.dependsOn {
    tasks.findAll { task -> task.name.startsWith('lib') }
}
task lib1 << {
    println 'lib1'
}
task lib2 << {
    println 'lib2'
}
task notALib << {
    println 'notALib'
}

结果:

> gradle -q taskX
lib1
lib2
taskX

关于任务依赖的更多信息, see the Task API.

 17.5. Ordering tasks
 这个特性是孵化产物,可能会在后期的版本中做修改。
 
 两种规则: “must run after” and “should run after”.

task taskX << {
    println 'taskX'
}
task taskY << {
    println 'taskY'
}
taskY.mustRunAfter taskX

结果

> gradle -q taskY taskX
taskX
taskY

taskY.shouldRunAfter taskX
结果:

> gradle -q taskY taskX
taskX
taskY

注意点:gradle -q taskY 单独执行taskY,taskX不会执行
需要他们之间有依赖关系

task taskX << {
    println 'taskX'
}
task taskY << {
    println 'taskY'
}
task taskZ << {
    println 'taskZ'
}
taskX.dependsOn taskY
taskY.dependsOn taskZ
taskZ.shouldRunAfter taskX

结果:

> gradle -q taskX
taskZ
taskY
taskX

 17.6. Adding a description to a task 添加任务描述信息
 
1,不能使用 << 否则描述信息不显示
2,依赖的task也不显示描述信息

task clean {
    description 'task description information'
        println 'Default Cleaning!'
}

什么时候显示描述信息呢:
1,gradle tasks
2,gradle help –task task名称
3,gradle tasks –all

 17.7. Replacing tasks 重写任务
 

task copy(type: Copy)

task copy(overwrite: true) << {
    println('I am the new one.')
}

重写的任务具有同样的名字,但是必须加上overwrite属性
否则Gradle就会告诉你task已经存在。

 17.8. Skipping tasks 跳过任务
 1,通过onlyIf() 方法来进行判断

task hello << {
    println 'hello world'
}
// project中是否包含skipHello任务
hello.onlyIf { !project.hasProperty('skipHello') }

 2,Using StopExecutionException
 

task compile << {
    println 'We are doing the compile.'
}

compile.doFirst {
    // Here you would put arbitrary conditions in real life.
    // But this is used in an integration test so we want defined behavior.
    if (true) { throw new StopExecutionException() }
}
task myTask(dependsOn: 'compile') << {
   println 'I am not affected'
}

结果:

gradle -q myTask
I am not affected

 3,Enabling and disabling tasks

task disableMe << {
    println 'This should not be printed if the task is disabled.'
}
disableMe.enabled = false

结果:

> gradle disableMe
:disableMe SKIPPED

BUILD SUCCESSFUL

Total time: 1 secs

 17.10. Task rules task 规则
 任务名称以ping开头

tasks.addRule("Pattern: ping<ID>") { String taskName ->
    if (taskName.startsWith("ping")) {
        task(taskName) << {
            println "Pinging: " + (taskName - 'ping')
        }
    }
}

结果:

D:\GradleTest\project1>gradle -q pingNameqq
Pinging: Nameqq

基于规则的依赖

tasks.addRule("Pattern: ping<ID>") { String taskName ->
    if (taskName.startsWith("ping")) {
        task(taskName) << {
            println "Pinging: " + (taskName - 'ping')
        }
    }
}

task groupPing {
    dependsOn pingServer1, pingServer2
}

结果;

> gradle -q groupPing
Pinging: Server1
Pinging: Server2

 17.11. Finalizer tasks 最终都要执行的task

task taskX << {
    println 'taskX'
}
task taskY << {
    println 'taskY'
}

taskX.finalizedBy taskY

结果:

> gradle -q taskX
taskX
taskY

即使task有异常,finalizedBy task也会被执行

task taskX << {
    println 'taskX'
    throw new RuntimeException()
}
task taskY << {
    println 'taskY'
}

taskX.finalizedBy taskY

结果

> gradle -q taskX
taskX
taskY
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值