项目与资源
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 接口和最重要的方法。
一个项目可以创建新任务、添加依赖和配置、应用插件和其他脚本,许多属性比如 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 的,这货默认用的是这个。