form: Gradle学习系列
扩展task属性/自定义task属性
task extTaskDemo {
//自定义属性myProperty
ext.myProperty = "myExtProperty"
}
task printTaskProperty << {
println extTaskDemo.myProperty
}
使用DAG(有向非循环图)进行配置
gradle分** 配置阶段 ** 和** 执行阶段 **,配置阶段完成后,gradle就知道所有需要被执行的任务。这样我们就可以利用这些信息了解哪些任务被执行了。下面的例子来判断任务执行完成后,release任务是否被执行
task distribution <<{
println "We build the zip with version = $version"
}
task release (dependsOn :'distribution')<<{
println 'We release now'
}
gradle.taskGraph.whenReady {
taskGraph->
if(taskGraph.hasTask(release)){ //如果执行的任务包含release任务
version = '1.0'
}else {
version = '1.0-SNAPSHOT'
}
}
输出
gradle -q distribution
We build the zip with version = 1.0-SNAPSHOT
说明上面的DAG中不存在release任务,所以release不会被执行。
gradle -q release
We build the zip with version = 1.0We release now
说明上面的DAG中存在release任务,说明release会被执行。
*上面的代码中需要注意的一点是whenReady,它会在(任何一个)任务执行前起作用。 *
执行多个任务
在命令行下,要想执行多个任务,可以在gradle关键字后面跟多个任务名,之间要用** 空格 隔开,执行的顺序按照你的输入的顺序执行。例如我们要执行编译和测试的任务。可以在命令行下输入:
gradle compile test
依赖任务
执行任务的时候,它的依赖任务会先被执行,然后才执行该任务,而且被依赖的任务只会被执行一次(存在多重依赖的时候,也只会执行一次)。
task compile1 <<{
println 'compiling source'
}
task compileTest1(dependsOn:compile1) <<{
println 'compiling unit tests'
}
task test1(dependsOn:[compile1,compileTest1])<<{
println 'running unit tests'
}
task dist1(dependsOn:[compile1,test1])<<{
println 'build the distribution'
}
看上面的例子,dist1依赖compile1和test1。然后test1又依赖compile1和compileTest1。疏导一下关系
dist1依赖:compile1、compileTest1
test1依赖:compile1、compileTest1
依据执行的顺序与命令行的列举顺序有关,且被依赖的任务只会被执行一次的这两个原则,思考一下输出应该是什么样子。
gradle -q dist1 test1
compiling source
compiling unit tests
running unit tests
build the distribution
排除任务
gradle提供了排除某个特定任务的语法,不执行所依赖的任务中的某个任务,来看一下命令
gradle task1 -x task2
在执行task1任务时不执行task1所依赖的task2任务。而且** 只删除task2有依赖,而task1没有依赖的任务(即:删除task2及其所有依赖任务,但是不包括task1中有的依赖任务) **。
同样我们来看看执行下面的命令
gradle -q dist1 -x test1
compiling source
build the distribution
分析:执行dist1,排除test1任务,所以test1不执行,而dist1由于依赖compile1,所以要先执行compile1,然后才执行自己。
选择特定的文件去执行
比如我们去执行同目录下sob目录下的的user.gradle构建文件。sob/user.gradle文件内容如下
task hello<<{
println "using build file '$buildFile.name' in '$buildFile.parentFile.name'"
}
执行该文件
gradle -q -b sob/user.gradle hello
using build file 'user.gradle' in 'sob'
可以看出要在命令行上用-b 后面跟目录来表示指定的文件。任务在前或在后效果都是一样的。
gradle -q hello -b sob/user.gradle
using build file 'user.gradle' in 'sob'
自定义变量
你可以在你自己写的脚本中定义本地变量。
运用groovy基础语法,可以使用def定义一个本地变量。
def dest = "this is myself"
task check<<{
println dest
}
gradle -q check
this is myself
自定义属性
ext块可以一次性添加多个属性
apply plugin: "java"
ext {
springVersion = "3.1.0.RELEASE"
emailNotification = "[email protected]"
}
sourceSets.all{
ext.purpose = null
}
sourceSets{
main{
purpose = "production"
}
test{
purpose = "test"
}
plugin{
purpose = "plugin"
}
}
task printProperties << {
println springVersion
println emailNotification
sourceSets.matching{
it.purpose=="production"}.each{
println it.name
}
}
执行该任务会打印上面定义的属性
gradle -q printProperties
3.1.0.RELEASE
[email protected]
main
groovy一些基础语法
1.setter和getter语法
println project.buildDir
println getProject().getBuildDir()
project.buildDir = 'target'
getProject().setBuildDir('target')
task hello<<{
println 'Hello world'
println project.buildDir
}
执行gradle命令
/Users/qianhui/Documents/Developer/gradle_project/0110_1/build/Users/qianhui/Documents/Developer/gradle_project/0110_1/buildHello world/Users/qianhui/Documents/Developer/gradle_project/0110_1/target
2.方法的调用
方法的调用可以带括号也可以不带。
test.systemProperty 'some.prop','value'
test.systemProperty('some.prop','value')
用脚本创建目录
通常情况下,创建目录使用mkdir来创建目录,但是有一种更好的方式来做到,避免每次都手动创建。定义一个任务来创建目录,然后用dependsOn来依赖该任务,这有可以在需要的时候创建目录。
def classesDir = new File('build/classes')
task resources << {
classesDir.mkdirs()
}
task compile(dependsOn:'resources')<<{
if(classesDir.isDirectory()){
println 'The class directory exists.I canoperate'
}
}
执行compile任务
gradle -q compile
The class directory exists.I canoperate
然后就会在该目录下生成build/classes目录
此处的File是时java.io中的类库,采用java的方式定义脚本或许更加让java程序员青睐
task makeDir << {
def File target = new File('target')
if(!target.exists())
{
target.mkdir();
println 'mkdir done'
}
else
{
println 'already has dir'
}
}
在执行一个task后,执行另一个操作
task taskA << {
println 'this is task a'
}
tasks.findByName('taskA').doLast {
println 'detected taskA has done'
}
gradle -q taskA
this is task a
detected taskA has done
从上面的操作中,可以引申出其他更有用的操作功能,比如,运行生成debug_apk后,为其加上系统签名,可以如下操作:
tasks.findByName('assembleDebug').doLast {
println 'apply system signature to apk'
//TODO::implement the real signature
}
以后,在每次生成apk时,就会为其签上系统签名
gradle -q assembleDebug
终结者任务
在实际情况中,你可能需要在一个任务执行之后进行一些清理工作,一个典型的例子就是Web容器在部署应用之后要进行集成测试,Gradle提供了一个finalizer任务来实现这个功能,你可以用finalizedBy方法来结束一个指定的任务:
task first << { println "first" }
task second << { println "second" }
//声明first结束后执行second任务
first.finalizedBy second
你会发现任务first结束后自动触发任务second:
$ gradle -q first
first
second