Gradlegradlegradle构建

gradle构建脚本基础一

2017-07-03  本文已影响15人  浔它芉咟渡

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
    }
}
上一篇下一篇

猜你喜欢

热点阅读