项目与资源

Gradle 构建脚本基础

每个 Gradle 构建都包括三个基本的构建块:项目(projects)、任务(tasks)和属性(properties),每个构建至少包括一个项目,项目包括一个或者多个任务,项目和任务都有很多个属性来控制构建过程。Gradle 运用了领域驱动的设计理念(DDD)来给自己的领域构建软件建模,因此 Gradle 的项目和任务都在 Gradle 的 API 中有一个直接的 class 来表示。

$ cat build.gradle
task hello {
    doLast {
        println 'Hello world!'
    }
}

文件中定义了一个 task:hello,task 的内容是 “println ‘Hello world!’“,我们来执行一下:

$ gradle -q hello
Hello world!

Projects

在 Gradle 术语里项目表示你想构建的一个组件(比如一个 JAR 文件),或者你想完成的一个目标(比如打包 App),如果你以前使用过 Maven,你应该听过类似的概念。与 Maven pom.xml 相对应的是 build.gradle 文件,每个 Gradle 脚本至少定义了一个项目。当开始构建过程后,Gradle 基于你的配置实例化 org.gradle.api.Project 这个类以及让这个项目通过 project 变量来隐式的获得。下图列出了 API 接口和最重要的方法。

Gradle Project Api

一个项目可以创建新任务、添加依赖和配置、应用插件和其他脚本,许多属性比如 name 和 description 都是可以通过 getter 和 setter 方法来访问。Project 实例允许你访问你项目所有的 Gradle 特性,比如任务的创建和依赖了管理,记住一点当访问你项目的属性和方法时你并不需要显式的使用 project 变量–Gradle 假定你的意思是 Project 实例,看看下面这个例子:

// 没有使用project变量来设置项目的描述
setDescription("myProject")

// 使用Grovvy语法来访问名字和描述
println "Description of project $name: " + project.description

Properties

每个 Project 和 Task 实例都提供了 setter 和 getter 方法来访问属性,属性可以是任务的描述或者项目的版本号,在后续的章节,你会在具体 例子中读取和修改这些属性值,有时候你要定义你自己的属性,比如,你想定义一个变量来引用你在构建脚本中多次使用的一个文件,Gradle 允许你通过外部 属性来定义自己的变量,一些内置的常用属性为:

Name Type Default Value
project Project The Project instance
name String The name of the project directory.
path String The absolute path of the project.
description String A description for the project.
projectDir File The directory containing the build script.
buildDir File *projectDir*/build
group Object unspecified
version Object unspecified
ant AntBuilder An AntBuilder instance

内置属性

在默认情况下,Gradle 已经为 Project 添加了很多 Property,我们可以调用以下命令进行查看:

gradle properties

输出如下:

:properties

------------------------------------------------------------
Root project
------------------------------------------------------------

allprojects: [root project 'gradle-blog']
ant: org.gradle.api.internal.project.DefaultAntBuilder@1342097

buildDir: /home/davenkin/Desktop/gradle-blog/build
buildFile: /home/davenkin/Desktop/gradle-blog/build.gradle
...
configurations: []
convention: org.gradle.api.internal.plugins.DefaultConvention@11492ed
copyFile: task ':copyFile'
...
ext: org.gradle.api.internal.plugins.DefaultExtraPropertiesExtension@1b5d53a
extensions: org.gradle.api.internal.plugins.DefaultConvention@11492ed
...
helloWorld: task ':helloWorld'
...
plugins: [org.gradle.api.plugins.HelpTasksPlugin@7359f7]
project: root project 'gradle-blog'
...
properties: {...}
repositories: []

tasks: [task ':copyFile', task ':helloWorld']
version: unspecified

BUILD SUCCESSFUL

Total time: 2.667 secs

外部属性

外部属性一般存储在键值对中,要添加一个属性,你需要使用 ext 命名空间,看一个例子:

//Only initial declaration of extra property requires you to use ext namespace
project.ext.myProp = 'myValue'
ext {
    someOtherProp = 123
}
//Using ext namespace to access extra property is optional
assert myProp == 'myValue'
println project.someOtherProp
ext.someOtherProp = 567

相似的,外部属性可以定义在一个属性文件中: 通过在/.gradle 路径或者项目根目录下的 gradle.properties 文件来定义属性可以直接注入到你的项目中,他们可以通过 project 实例来访问,注意/.gradle 目录下只能有一个 Gradle 属性文件即使你有多个项目,在属性文件中定义的属性可以被所有的项目访问,假设你在你的 gradle.properties 文件中定义了下面的属性:

exampleProp = myValue
someOtherProp = 455

你可以在项目中访问这两个变量:

assert project.exampleProp == 'myValue'

task printGradleProperty << {
   println "Second property: $someOtherProp"
}

其他定义方法

你也可以通过下面的方法来定义属性:

  • 通过-P 命令行选项来定义项目属性
  • 通过-D 命令行选项来定义系统属性
  • 环境属性遵循这个模式: ORG_GRADLE_PROJECT_propertyName=someValue

Resource | 资源

Resource Filtering(资源过滤)

有时候我们希望能够在编译的时候动态替换配置文件中的部分值,譬如我们希望能够在打包的时候动态替换应用的版本号,那么可以在类似于 Manifest 的文件中使用变量占位符来表示某个即将被替换的变量:

application.version=${application.version}

在 Gradle 中要引入变量过滤插件的方式如下:

import org.apache.tools.ant.filters.*

processResources {
    filter ReplaceTokens, tokens: [
        "application.version": project.property("application.version")
    ]
}

然后在资源中设置:

application.version=@application.version@

注意,在 Gradle 中默认使用的是 @@ 来替换 ${} 作为变量替换,这是因为 Gradle 是基于 Ant 的,这货默认用的是这个。

Links

上一页