13.1. The Gradle build language构建语言
Gradle提供了一种“领域专用语言”(domain specific language) 或者 DSL对构建进行描述。这种语言基于Groovy,并加入了其他特性使得描述更简单。
13.2. The Project API
在第七章Chapter 7, Java Quickstart 我们以apply() 方法为例做了描述。咦,这个方法哪来的?当时我们说脚本定义了工程,对于每一个工程Gradle会创建一个 Project 型的实例并将该对象实例和构建脚本进行关联。当构建脚本执行时会配置这个对象:
Getting help writing build scripts
嗨嗨别忘了构建脚本是Groovy代码,用的是Gradle API。而Project 接口就是你最先要了解的访问Gradle API的工具。所以要了解什么标签可用,就得去看Project 接口的文档.
- 脚本中调用的任何方法如果在基本中无定义,都委托给Project对象。
- 属性的访问同上。
咱们试着访问name属性看看 。
Example 13.1. Accessing property of the Project object
build.gradle
println name
println project.name
Output of gradle -q check
> gradle -q check
projectApi
projectApi
哇唔,俩println 语句都打出了同一个属性。前者是自动委托了Project对象,对于没在脚本里定义的属性施行。后者使用了工程命来关联Project对象。 如果你定义的属性和Project的成员一样了,那就必须使用工程名进行界定了。
13.2.1. Standard project properties标准属性
Project对象提供了几个标准属性,下面列出了一些常用的:
Table 13.1. Project Properties
Name | Type | Default Value |
| Project | The |
|
| The name of the project directory. |
|
| The absolute path of the project. |
|
| A description for the project. |
|
| The directory containing the build script. |
|
|
|
|
|
|
|
|
|
| AntBuilder | An |
13.3. The Script API
脚本执行的时候Gradle会把它编译进实现了 Script接口的一个类中,这样接口中的属性和方法都能直接使用了。
13.4. Declaring variables声明变量
可是声明两种变量:局部变量和额外属性。
13.4.1. Local variables局部变量
使用 def 关键字声明局部变量,它们只能在声明域中访问。局部变量在Groovy中就有。
Example 13.2. Using local variables
build.gradle
def dest = "dest"
task copy(type: Copy) {
from "source"
into dest
}
13.4.2. Extra properties额外属性
Gradle域模型中的增强对象都有额外的用户定义属性。这包括但不限于工程、任务、资源集等。通过ext属性可以增加、读取、改变额外属性。也可以使用ext块增加多个额外属性。
Example 13.3. Using extra properties
build.gradle
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 }
}
Output of gradle -q printProperties
> gradle -q printProperties 3.1.0.RELEASE build@master.org main plugin
上例中用 ext 块增加了两个额外属性。另外通过设置ext.purpose为null为每个资源集增加了purpose属性。一旦属性被增加就可以像预定义属性一样访问。
通过要求严格语法,Gradle会在尝试访问不存在是属性命时立即失败。额外属性可以从任何域访问,父工程的额外属性也能被子工程访问。
更多关于额外属性访问: ExtraPropertiesExtension.
13.5. Some Groovy basics 基本Groovy入门
Groovy提供了大量特性来创建DSL,Gradle就利用了这一点。
13.5.1. Groovy JDK
Groovy给JVM类增加了大量好用的方法。比如 Iterable 有一个 each 方法,可以迭代访问元素:
Example 13.4. Groovy JDK methods
build.gradle
// Iterable gets an each() method
configurations.runtime.each { File f -> println f }
详细请看 http://groovy.codehaus.org/groovy-jdk/
13.5.2. Property accessors属性访问符
Groovy会自动给属性增加 getter或 setter 方法.
Example 13.5. Property accessors
build.gradle
// Using a getter method
println project.buildDir
println getProject().getBuildDir()
// Using a setter method
project.buildDir = 'target'
getProject().setBuildDir('target')
13.5.3. Optional parentheses on method calls括号可有可无
方法的括号在调用时不需要写
Example 13.6. Method call without parentheses
build.gradle
test.systemProperty 'some.prop', 'value'
test.systemProperty('some.prop', 'value')
13.5.4. List and map literals迭代
Groovy提供了定义 List 和Map的快捷方法:
Example 13.7. List and map literals
build.gradle
// 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
apply plugin: 'java'
Map<String, String> map = new HashMap<String, String>()
map.put('plugin', 'java')
apply(map)
13.5.5. Closures as the last parameter in a method闭包作末参数
Gradle DSL随处使用闭包,闭包的概念见here。如果方法的最后一个参数是闭包,则可以把闭包后置 :
Example 13.8. Closure as method parameter
build.gradle
repositories {
println "in a closure"
}
repositories() { println "in a closure" }
repositories({ println "in a closure" })
13.5.6. Closure delegate闭包委托
每个闭包都有一个delegate 对象,Groovy使用它来查找闭包的非局部变量和引用。Gradle以此来配置闭包,给闭包添加delegate对象。
Example 13.9. Closure delegates
build.gradle
dependencies {
assert delegate == project.dependencies
compile('junit:junit:4.11')
delegate.compile('junit:junit:4.11')
}