Gradle构建
projectstasks- 利用AntBuilder执行ant.loadfile
构建基础
- projects和tasks是Gradle中最重要的两个概念
projects
- 任何一个Gradle构建都是由一个或多个project组成
- 每个project包括许多可构建组成部分,这完全取决于要构建些什么
- 示例:
- 每个project可能是一个jar包或者一个web应用
- 也可以是一个由许多其他项目中产生的jar构成的zip压缩包
- 一个project不仅仅只能进行构建操作,也可以部署应用或搭建环境
- 通过Gradle的build-by-convention来具体定义一个project的操作
tasks
- 每个project都由多个task组成
- 每个task都代表了构建执行过程中的一个原子性操作:
构建
- 可以通过在命令行运行gradle命令来执行构建
- gradle命令会从当前目录下寻找build.gradle文件来执行构建
- build.gradle文件为构建脚本
- 这是一个构建配置脚本
- 这个构建脚本定义了一个project和一些默认的task
脚本
task me {
doLast {
println 'chova'
}
}
gradle -q me
- -q : 该参数用来控制gradle的日志级别,可以保证只输出需要的日志内容
- 该脚本定义了一个task, 并且添加了一个动作
- 当执行gradle me时 ,Gralde便会去调用me这个任务来执行给定操作,这些操作就是一个用groovy书写的闭包
- Gradle的tasks类似于Ant中的targets, 但是功能更加强大
任务
task upper << {
String someString = 'mY_nAmE'
println "Original: " + someString
println "Upper case: " + someString.toUpperCase()
}
gradle -q upper
Original: mY_nAmE
Upper case: MY_NAME
task count << {
4.times { print "$it " }
}
gradle -q count
0 1 2 3
任务依赖
- 在两个任务之间指明依赖关系: 添加依赖task也可以不必首先声明被依赖的task
task me << {
println 'me'
}
task intro(dependsOn: me) << {
println "chova"
}
gradle -q intro
me
chova
延迟依赖
task taskX(dependsOn: 'taskY') << {
println 'taskX'
}
task taskY << {
println 'taskY'
}
gradle -q taskX
taskY
taskX
- 这里的taskX是在taskY之前定义的,这在多项目构建中非常有用
- 注意: 当引用的任务尚未定义的时候不可使用短标记法来运行任务
动态任务
- Groovy不仅可以定义简单任务,还可以动态定义任务
- 创建动态任务:
4.times { counter ->
task "task$counter" << {
println "I'm task number $counter"
}
}
gradle -q task1
I'm task number 1
任务控制
增加依赖
4.times { counter ->
task "task$counter" << {
println "I'm task number $counter"
}
}
task0.dependsOn task2, task3
gradle -q task0
I'm task number 2
I'm task number 3
I'm task number 0
增加任务行为
task hello << {
println 'Hello Earth'
}
hello.doFirst {
println 'Hello Venus'
}
hello.doLast {
println 'Hello Mars'
}
hello << {
println 'Hello Jupiter'
}
gradle -q hello
Hello Venus
Hello Earth
Hello Mars
Hello Jupiter
- doFirst和doLast可以进行多次调用,分别被添加在任务的开头和结尾
- 当任务开始执行时这些动作会按照既定顺序进行
- << 操作符是doLast的简写形式
短标记法
以属性的方式访问任务
task hello << {
println 'Hello world!'
}
hello.doLast {
println "Greetings from the $hello.name task."
}
gradle -q hello
Hello world!
Greetings from the hello task.
增加自定义属性
- 可以为一个任务添加额外的属性
- 比如新增一个叫做myProperty的属性,用ext.myProperty的方式给赋初始值
- 这样就增加了一个自定义属性
为任务增加自定义属性
task myTask {
ext.myProperty = "myValue"
}
task printTaskProperties << {
println myTask.myProperty
}
gradle -q printTaskProperties
myValue
- 自定义属性不仅仅可以用在任务上,还可以用于其余操作
调用Ant任务
- Ant任务是Gradle中的一等公民
- Gradle借助Groovy对Ant任务进行了整合
- Gradle自带了一个AntBuilder, 在Gradle中调用Ant任务比在build.xml中调用更加的方便和强大
- 在Gradle可以调用Ant任务并且与Ant中的属性进行通信
利用AntBuilder执行ant.loadfile
task loadfile << {
def files = file('../antLoadfileResources').listFiles().sort()
files.each { File file ->
if (file.isFile()) {
ant.loadfile(srcFile: file, property: file.name)
println " *** $file.name ***"
println "${ant.properties[file.name]}"
}
}
}
gradle -q loadfile
*** agile.manifesto.txt ***
Individuals and interactions over processes and tools
Working software over comprehensive documentation
Customer collaboration over contract negotiation
Responding to change over following a plan
*** gradle.manifesto.txt ***
Make the impossible possible, make the possible easy and make the easy elegant.
(inspired by Moshe Feldenkrais)
方法抽取
- Gradle的强大体现在如何编写脚本逻辑
- 首先要做的就是要抽取方法
利用方法组织脚本逻辑
task checksum << {
fileList('../antLoadfileResources').each {File file ->
ant.checksum(file: file, property: "cs_$file.name")
println "$file.name Checksum: ${ant.properties["cs_$file.name"]}"
}
}
task loadfile << {
fileList('../antLoadfileResources').each {File file ->
ant.loadfile(srcFile: file, property: file.name)
println "I'm fond of $file.name"
}
}
File[] fileList(String dir) {
file(dir).listFiles({file -> file.isFile() } as FileFilter).sort()
}
定义默认任务
defaultTasks 'clean', 'run'
task clean << {
println 'Default Cleaning!'
}
task run << {
println 'Default Running!'
}
task other << {
println "I'm not a default task!"
}
gradle -q
Default Cleaning!
Default Running!
- 这与直接调用gradle clean run效果是一样的
- 在多项目构建中,每个子项目都可以指定单独的默认任务
- 如果子项目未进行指定将会调用父项目指定的的默认任务
DAG配置
- 配置阶段后 ,Gradle会获取所有要执行的任务
- Gradle提供了一个钩子来捕获这些信息
- 可以为一些变量赋予不同的值
- 可以用于检查已经执行的任务中有没有被释放
依赖任务的不同输出
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)) {
version = '1.0'
} else {
version = '1.0-SNAPSHOT'
}
}
gradle -q distribution
We build the zip with version=1.0-SNAPSHOT
gradle -q release
We build the zip with version=1.0
We release now
- whenReady会在已发布的任务之前影响到已发布任务的执行,即使已发布的任务不是主要任务,即这个任务不是通过命令行直接调用