gradle构建脚本基础一

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的属性

image

额外的属性

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

自定义任务类型:如果你实现了一个自定义的任务作为一个类,他只需要两步就能进行构建工作:

  1. 创建属性或这个方法对你的task的输入和输出
  2. 增加合适的注解在每个属性或者get方法上

gradle主要支持3种主要的输入和输出的分类:

  1. 简单值:像String类型或者Number类型。更简单的说,就是任何一种实现了Serialiezable的类型:
  2. 文件类型。Project.file(java.lang.Object)或者Project.file(java.lang.Object[])
  3. 内置类型。

使用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
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容

  • 是什么? 在语法上是基于Groovy语言的(Groovy 是一种基于JVM的敏捷开发语言,可以简单的理解为强类型语...
    千山万水迷了鹿阅读 99,521评论 4 122
  • 参考资料:http://gold.xitu.io/post/580c85768ac247005b5472f9htt...
    zhaoyubetter阅读 10,984评论 0 6
  • 前言 学习gradle这个想法在我开始使用AndroidStudio之后就有了,基本上每个开始使用AndroidS...
    AnAppleADie阅读 3,573评论 2 19
  • 前言 从2013年Google推出Android Studio(后面以AS简称)开始,到现在已经历经3年,版本也发...
    dfqin阅读 1,830评论 1 3
  • Gradle简介 Gradle是一个构建工具,同时它也是一个编程框架。 当你把Gradle当构建工具看的时候,我们...
    Rangethan阅读 2,314评论 1 8