Projects 和 tasks
每一个gradle脚本都是由两个部分组成的,projects和tasks
每一个gradle的构建都由一个或者多个projects构成。project表示什么完全取决于他依赖的gradle是干什么的。比如,一个project可能表示一个jar包或者一个web程序。
每一个project都由一个或者几个task组成。一个task表示一些自动的构建公做。这可能是一个compile任务来构建一个jar包,或者产生一个javadoc文件。
动态task
4.times { counter ->
task "task$counter" {
doLast {
println "I'm task number $counter"
}
}
}
操作已经存在task
4.times { counter ->
task "task$counter" {
doLast {
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的行为
task hello {
doLast {
println 'Hello Earth'
}
}
hello.doFirst {
println 'Hello Venus'
}
hello.doLast {
println 'Hello Mars'
}
hello {
doLast {
println 'Hello Jupiter'
}
}
结果
> gradle -q hello
Hello Venus
Hello Earth
Hello Mars
Hello Jupiter
task的属性
task myTask {
ext.myProperty = "myValue"
}
task printTaskProperties {
doLast {
println myTask.myProperty
}
}
结果:
> gradle -q printTaskProperties
myValue
使用ant task
task loadfile {
doLast {
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)
通过hook来配置task
task distribution {
doLast {
println "We build the zip with version=$version"
}
}
task release(dependsOn: 'distribution') {
doLast {
println 'We release now'
}
}
gradle.taskGraph.whenReady {taskGraph ->
if (taskGraph.hasTask(release)) {
version = '1.0'
} else {
version = '1.0-SNAPSHOT'
}
}
结果:
> gradle -q release
We build the zip with version=1.0
We release now
标准的project的属性
额外的属性
apply plugin: "java"
ext {
springVersion = "3.1.0.RELEASE"
emailNotification = "build@master.org"
}
sourceSets.all { ext.purpose = null }
sourceSets {
main {
purpose = "production"
}
test {
purpose = "test"
}
plugin {
purpose = "production"
}
}
task printProperties {
doLast {
println springVersion
println emailNotification
sourceSets.matching { it.purpose == "production" }.each { println it.name }
}
}
结果:
> gradle -q printProperties
3.1.0.RELEASE
build@master.org
main
plugin
配置任意的对象
task configure {
doLast {
def pos = configure(new java.text.FieldPosition(10)) {
beginIndex = 1
endIndex = 5
}
println pos.beginIndex
println pos.endIndex
}
}
结果:
> gradle -q configure
1
5
使用外部的脚本配置对象
task configure {
doLast {
def pos = new java.text.FieldPosition(10)
// Apply the script
apply from: 'other.gradle', to: pos
println pos.beginIndex
println pos.endIndex
}
}
结果
> gradle -q configure
1
5
闭包在方法中作为最后的一个参数
在gradle中,很多地方都使用到了闭包,你能在很多地方看到,当闭包作为最后一个一个方法参数的时候,你能够把他放在方法的后面。
repositories {
println "in a closure"
}
repositories() { println "in a closure" }
repositories({ println "in a closure" })
闭包代理
dependencies {
assert delegate == project.dependencies
testCompile('junit:junit:4.12')
delegate.testCompile('junit:junit:4.12')
}
定义task
task(hello) {
doLast {
println "hello"
}
}
task(copy, type: Copy) { //这个type是一个类型提示,可以为同样的类型但是不同的名字的task进行配置
from(file('srcDir'))
into(buildDir)
}
task依赖
project('projectA') {
task taskX(dependsOn: ':projectB:taskY') {
doLast {
println 'taskX'
}
}
}
project('projectB') {
task taskY {
doLast {
println 'taskY'
}
}
}
结果
> gradle -q taskX
taskY
taskX
task taskX {
doLast {
println 'taskX'
}
}
task taskY {
doLast {
println 'taskY'
}
}
taskX.dependsOn taskY
结果:
> gradle -q taskX
taskY
taskX
使用闭包进行依赖
task taskX {
doLast {
println 'taskX'
}
}
taskX.dependsOn {
tasks.findAll { task -> task.name.startsWith('lib') }
}
task lib1 {
doLast {
println 'lib1'
}
}
task lib2 {
doLast {
println 'lib2'
}
}
task notALib {
doLast {
println 'notALib'
}
}
结果:
> gradle -q taskX
lib1
lib2
taskX
task的执行顺序
mustRunAfter
task taskX {
doLast {
println 'taskX'
}
}
task taskY {
doLast {
println 'taskY'
}
}
taskY.mustRunAfter taskX
结果:
> gradle -q taskY taskX
taskX
taskY
shouldRunAfter
task taskX {
doLast {
println 'taskX'
}
}
task taskY {
doLast {
println 'taskY'
}
}
taskY.shouldRunAfter taskX
结果:
> gradle -q taskY taskX
taskX
taskY
如果有task的相关依赖的话,shouldRunAfter不起作用。
task taskX {
doLast {
println 'taskX'
}
}
task taskY {
doLast {
println 'taskY'
}
}
task taskZ {
doLast {
println 'taskZ'
}
}
taskX.dependsOn taskY
taskY.dependsOn taskZ
taskZ.shouldRunAfter taskX
结果:
> gradle -q taskX
taskZ
taskY
taskX
重写tasks
task copy(type: Copy)
task copy(overwrite: true) {
doLast {
println('I am the new one.')
}
}
结果:
> gradle -q copy
I am the new one.
使用谓词
可以使用onlyIf()方法来作为task的一个动作。task的功能只有在此动作返回为true时才会执行,不然不会执行。
task hello {
doLast {
println 'hello world'
}
}
hello.onlyIf { !project.hasProperty('skipHello') }
结果:
> gradle hello -PskipHello
:hello world
BUILD SUCCESSFUL
Total time: 1 secs
使用StopExecutionException
如果这个throw new StopExecutionException()异常被抛出,那么task的逻辑将不会执行。
task compile {
doLast {
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') {
doLast {
println 'I am not affected'
}
}
Enabling and disabling tasks
task disableMe {
doLast {
println 'This should not be printed if the task is disabled.'
}
}
disableMe.enabled = false
结果:
:disableMe SKIPPED
BUILD SUCCESSFUL
Total time: 1 secs
更新到最新的检查 Up-to-date checks
自定义任务类型:如果你实现了一个自定义的任务作为一个类,他只需要两步就能进行构建工作:
- 创建属性或这个方法对你的task的输入和输出
- 增加合适的注解在每个属性或者get方法上
gradle主要支持3种主要的输入和输出的分类:
- 简单值:像String类型或者Number类型。更简单的说,就是任何一种实现了Serialiezable的类型:
- 文件类型。Project.file(java.lang.Object)或者Project.file(java.lang.Object[])
- 内置类型。
使用gradle.properties文件
gradle.properties:
gradlePropertiesProp=gradlePropertiesValue
sysProp=shouldBeOverWrittenBySysProp
envProjectProp=shouldBeOverWrittenByEnvProp
systemProp.system=systemValue
systemProp.https.proxyHost=www.somehost.org
build.gradle:
task printProps {
doLast {
println (gradlePropertiesProp)
println envProjectProp
println System.properties['system']
println System.properties['https.proxyHost']
//println systemProp.https.proxyHost
}
}