构建脚本所指就是build.gradle文件
Chapter 16. Writing Build Scripts 写脚本
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