Gradle学习小记

安装

环境支持: java1.7+

自动安装

brew install gradle

手动安装

参考官网

构建脚本的基本

简单尝试

build.gradle

task hello{
    doLast{
        println 'Hello world!'
    }
}
$./gradlew -q hello
Hello world
  • -q : 安静模式,不输出日志

快捷方式写法

task hello << {
    println 'Hello world'
}
$./gradlew -q hello
Hello world

<< 是doLast的别名

简单groovy语法

变量

task hello << {
    String h = 'hello world!'
    println h.toUpperCase()
}
$./gradlew -q hello
HELLO WORLD

循环

task hello << {
    4.times {print "$it"}
}

$./gradlew -q hello
0123

"$it"是双引号,表示当前计数器的值

依赖

task getGF << {
    println 'I have a girlfriend'
}

task getWife(dependsOn: getGF) << {
    println 'I have a wife'
}
$./gradlew -q getWife
I have a girlfriend
I have a wife

被添加的依赖可以不存在

动态task

4.times { counter ->
    task "task$counter" << {
        println "I'm task number $counter"
    }
}
./gradlew -q task1
I'm task number 1

./gradlew -q task2
I'm task number 2

动态依赖

主要任务存在,就能被添加

4.times { counter ->
    task "task$counter" << {
        println "I'm task number $counter"
    }
}
task0.dependsOn task1,task2,task3
./gradlew -q task0
I'm task number 1
I'm task number 2
I'm task number 3
I'm task number 0

行为添加

task hello << {
    println 'Hello'
}
hello.doLast {
    println 'Hello last'
}
hello.doFirst {
    println 'Hello first'
}
hello << {
    println 'Hello again'
}
./gradlew -q hello
Hello first
Hello
Hello last
Hello again

额外的task属性

task task1 {
    ext.username = 'sb'
}
task task2 << {
    println task1.username
    println 'i am task2'
}

ext设置额外属性,只要代码执行到赋值属性,那么其他后面的task都能引用

检查运行的任务

task distribution << {
    println "We build the version:$version"
}

task release(dependsOn:distribution){
    println "We release now"
}

gradle.taskGraph.whenReady{ t->
    if(t.hasTask(release)){
        version = '1.0'
    }else{
        version = '1.0-SNAPSHOT'
    }
}
./gradle -q distribution
We release now
We build the version:1.0-SNAPSHOT

./gradle -q release
We release now
We build the version:1.0

构建Java项目

使用Java插件

apply plugin: 'java'

构建项目

Java插件内置许多任务

 > gradle build
    :compileJava
    :processResources
    :classes
    :jar
    :assemble
    :compileTestJava
    :processTestResources
    :testClasses
    :test
    :check
    :build

    BUILD SUCCESSFUL

    Total time: 1 secs

一些有用的任务

  • clean : 删除 build 目录,移除所有构建的文件
  • assemble : 编译打包代码,但不运行单元测试。其他插件带给这个 task 更多特性,比如如果你使用 War 插件,task 将给 project 构建 WAR 文件
  • check : 编译测试你的代码。其他插件带给这个 task 提供更多检查类型。比如,你使用 checkstyle 插件, 这个 task 建辉在你的代码中 执行 Checkstyle

外部依赖

Java的一些依赖,引用时则需要同步仓库.

添加仓库

repositories {
    mavenCentral()
}

添加依赖

dependencies {
    compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
    testCompile group: 'junit', name: 'junit', version: '4.+'
}

自定义项目

    sourceCompatibility = 1.5
    version = '1.0'
    jar {
        manifest {
            attributes 'Implementation-Title': 'Gradle Quickstart','Implementation-         Version': version
        }
    }

设置project的属性

test {
    systemProperties 'property': 'value'
}

执行gradle properties 可以列出project的属性,你可以看到 Java 插件添加的属性和他们的默认值*

发布Jar文件

Jar文件可以发布到本地和远程仓库

uploadArchives {
    repositories {
        flatDir {
            dirs 'repos'
        }
    }
}

创建eclipse项目

apply plugin: 'eclipse'

多项目构建

    multiproject/
        api/
        services/webservice/
        shared/
        services/shared/

settings.gradle

include "shared", "api", "services:webservice", "services:shared"

配置注入

subprojects {
    apply plugin: 'java'
    apply plugin: 'eclipse-wtp'

    repositories {
        mavenCentral()
    }

    dependencies {
        testCompile 'junit:junit:4.11'
    }

    version = '1.0'

    jar {
        manifest.attributes provider: 'gradle'
    }
}

项目间的依赖

dependencies {
    compile project(':shared')
}

创建发布包

api/build.gradle

task dist(type: Zip) {
    dependsOn spiJar
    from 'src/dist'
    into('libs') {
        from spiJar.archivePath
        from configurations.runtime
    }
}

artifacts {
    archives dist
}

项目配置

Java标准配置

  • compile : 编译项目的生产源所需的依赖。
  • runtime : 生产类在运行时所需的依赖。默认情况下,还包括编译时的依赖。
  • testCompile : 编译项目的测试源所需的依赖。默认情况下,还包括产品编译类和编译时的依赖。
  • testRuntime : 运行测试所需的依赖。默认情况下,还包括 编译,运行时和测试编译的依赖。

Groovy插件

使用 Groovy 插件来构建 Groovy 项目。这个插件继承自 Java 插件,使你的应用具备了编译能力。

使用插件

apply plugin: 'groovy'

Java插件同时被应用到项目

示例

apply plugin: 'eclipse'
apply plugin: 'groovy'

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.codehaus.groovy:groovy-all:2.3.6'
    testCompile 'junit:junit:4.11'
}
./gradle build
:compileJava UP-TO-DATE
:compileGroovy UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:jar
:assemble
:compileTestJava UP-TO-DATE
:compileTestGroovy UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE
:check UP-TO-DATE
:build

BUILD SUCCESSFUL

Total time: 1.161 secs

Gradle命令行

task compile << {
    println 'compiling source'
}

task compileTest(dependsOn: compile) << {
    println 'compiling unit tests'
}

task test(dependsOn: [compile, compileTest]) << {
    println 'running unit tests'
}

task dist(dependsOn: [compile, test]) << {
    println 'building the distribution'
}

执行顺序

gradle dist test
    :compile
    compiling source
    :compileTest
    compiling unit tests
    :test
    running unit tests
    :dist
    building the distribution

    BUILD SUCCESSFUL

    Total time: 1 secs

每个task执行一次,所以gradle test dist和gradle dist test一样

排除task

gradle dist -x test
    :compile
    compiling source
    :dist
    building the distribution

    BUILD SUCCESSFUL

Total time: 1 secs

使用-x排除task执行

发生故障处理

默认情况task失败->gradle停止,使用--continue参数可以继续构建,但是失败task所依赖的task都不会执行

任务名称缩写

当运行任务时,指定任务时只要前缀能唯一识别任务名称即可,支持驼峰写法

指定gradle文件

默认从工作目录寻找build.gradlesettings.gradle里寻找子项目,可以使用-b选项指定gradle文件.

指定多项目

-p参数代替-b

获取构建信息

项目列表

projects

任务列表

tasks

详细信息

--all

task细节

./gradle help --task build
:help
Detailed task information for build

Path
     :build

Type
     Task (org.gradle.api.Task)

Description
     Assembles and tests this project.

Group
     build

BUILD SUCCESSFUL

依赖列表

  • 所有依赖 : dependencies
  • 指定项目 : dependencies api:dependencies

使用特定配置

gradle -q api:dependencies --configuration testCompile

查看特定依赖

./gradle dependencyInsight --dependency groovy
:dependencyInsight
org.codehaus.groovy:groovy-all:2.3.6
\--- compile

BUILD SUCCESSFUL

Total time: 0.919 secs

项目属性

./gradle properties

查看执行顺序

gradle -m clean compile

编写构建脚本

  • 在构建脚本中,你所调用的任何一个方法,如果在构建脚本中未定义,它将被委托给 Project 对象。
  • 在构建脚本中,你所访问的任何一个属性,如果在构建脚本里未定义,它也会被委托给 Project 对象。

标准属性

名称类型说明
projectProjectThe Project实例
nameString项目目录的名称
pathString项目的绝对路径
descriptionString项目的描述
projectDirFile包含生成脚本的目录
buildDirFileprojectDir/build
groupObject未指定
versionObject未指定
antAntBuilderAn AntBuilder实例

脚本API

当 Gradle 执行一个脚本时,它将脚本编译为一个实现了 Script 接口的类。这意味着所有由该 Script 接口声明的属性和方法在您的脚本中是可用的。

声明变量

有两类可以在生成脚本中声明的变量: 局部变量和额外属性。

局部变量

局部变量是用 def 关键字声明的。它们只在定义它们的范围内可以被访问。局部变量是 Groovy 语言底层的一个特征。

额外属性

Gradle 的域模型中,所有增强的对象都可以容纳用户定义的额外的属性。这包括但并不限于 project、task 和源码集。额外的属性可以通过所属对象的 ext 属性进行添加,读取和设置。或者,可以使用 ext块同时添加多个属性。

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 << {
    println springVersion
    println emailNotification
    sourceSets.matching { it.purpose == "production" }.each { println it.name }
}

一些 Groovy 的基础

Groovy JDK

Groovy 对 Java 的标准类增加了很多有用的方法。例如, Iterable 新增的each方法,会对Iterable 的元素进行遍历:

configurations.runtime.each { File f -> println f }

参考

属性访问器

Groovy 会自动地把一个属性的引用转换为对适当的 getter 或 setter 方法的调用。

// Using a getter method
println project.buildDir
println getProject().getBuildDir()

// Using a setter method
project.buildDir = 'target'
getProject().setBuildDir('target')

括号可选的方法调用

调用方法时括号是可选的。

test.systemProperty 'some.prop', 'value'
test.systemProperty('some.prop', 'value')

集合

Groovy 提供了一些定义 List 和 Map 实例的快捷写法。两种类型都是简单的 literal,但 map literal 有一些有趣的曲折。

// List literal
test.includes = ['org/gradle/api/**', 'org/gradle/internal/**']

List<String> list = new ArrayList<String>()
list.add('org/gradle/api/**')
list.add('org/gradle/internal/**')
test.includes = list

// Map literal.
Map<String, String> map = [key1:'value1', key2: 'value2']

作为方法最后一个参数的闭包

repositories {
    println "in a closure"
}
repositories() { println "in a closure" }
repositories({ println "in a closure" })

闭包委托

每个闭包都有一个委托对象,Groovy 使用它来查找变量和方法的引用,而不是作为闭包的局部变量或参数。Gradle 在配置闭包中使用到它,把委托对象设置为被配置的对象。

dependencies {
    assert delegate == project.dependencies
    testCompile('junit:junit:4.11')
    delegate.testCompile('junit:junit:4.11')
}
点赞