本文來源於:http://blog.csdn.net/maosidiaoxian/article/details/40976325
第十三章 編寫構建腳本
這一章着眼於一些編寫構建腳本的詳細信息。
在第
7 章, Java 快速入門的教程中,我們使用了 apply
()
方法。這方法從何而來?我們之前說在 Gradle 中構建腳本定義了一個項目(project)。在構建的每一個項目中,Gradle 創建了一個Project
類型的實例,並在構建腳本中關聯此Project
對象。當構建腳本執行時,它會配置此Project
對象:
獲取有關編寫構建腳本幫助
不要忘記您的構建腳本是簡單的 Groovy 代碼,並驅動着 Gradle API。並且Project
接口是您在
Gradle API 中訪問一切 的入點。所以,如果你想知道什麼 '標籤(tag)' 在構建腳本中可用,您可以去看項目
接口的文檔。
-
在構建腳本中,你所調用的任何一個方法,如果在構建腳本中未定義,它將被委託給
Project
對象。 -
在構建腳本中,你所訪問的任何一個屬性,如果在構建腳本里未定義,它也會被委託給
Project
對象。
下面我們來試試這個,試試訪問Project
對象的name
屬性。
Example 13.1. 訪問 Project 對象的屬性
build.gradle
println name println project.name
gradle
-q check
的輸出結果
> gradle -q check projectApi projectApi
這兩個println
語句打印出相同的屬性。在生成腳本中未定義的屬性,第一次使用時自動委託到Project
對象。其他語句使用了在任何構建腳本中可以訪問的project
屬性,則返回關聯的Project
對象。只有當您定義的屬性或方法Project
對象的一個成員相同名字時,你才需要使用project
屬性。
Project
對象提供了一些在構建腳本中可用的標準的屬性。下表列出了常用的幾個屬性。
表 13.1. Project屬性
名稱 | 類型 | 默認值 |
project |
Project |
Project 實例 |
name |
String |
項目目錄的名稱。 |
path |
String |
項目的絕對路徑。 |
description |
String |
項目的描述。 |
projectDir |
File |
包含生成腳本的目錄。 |
buildDir |
File |
|
group |
Object |
未指定 |
version |
Object |
未指定 |
ant |
AntBuilder |
AntBuilder 實例 |
當 Gradle 執行一個腳本時,它將腳本編譯爲一個實現了Script
接口的類。這意味着所有由該Script
接口聲明的屬性和方法在您的腳本中是可用的。
有兩類可以在生成腳本中聲明的變量: 局部變量和額外屬性。
局部變量是用def
關鍵字聲明的。它們只在定義它們的範圍內可以被訪問。局部變量是Groovy
語言底層的一個特徵。
示例 13.2. 使用局部變量
build.gradle
def dest = <span class="hl-string" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(131, 194, 131);">"dest"</span> task copy(type: Copy) { from <span class="hl-string" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(131, 194, 131);">"source"</span> into dest }
Gradle 的域模型中,所有增強的對象都可以容納用戶定義的額外的屬性。這包括但並不限於項目(project)、任務(task)和源碼集(source set)。額外的屬性可以通過所屬對象的ext
屬性進行添加,讀取和設置。或者,可以使用ext
塊同時添加多個屬性。
13.3 例子. 使用額外屬性
build.gradle
apply plugin: <span class="hl-string" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(131, 194, 131);">"java"</span> ext { springVersion = <span class="hl-string" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(131, 194, 131);">"3.1.0.RELEASE"</span> emailNotification = <span class="hl-string" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(131, 194, 131);">"[email protected]"</span> } sourceSets.all { ext.purpose = null } sourceSets { main { purpose = <span class="hl-string" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(131, 194, 131);">"production"</span> } test { purpose = <span class="hl-string" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(131, 194, 131);">"test"</span> } plugin { purpose = <span class="hl-string" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(131, 194, 131);">"production"</span> } } task printProperties << { println springVersion println emailNotification sourceSets.matching { it.purpose == <span class="hl-string" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(131, 194, 131);">"production"</span> }.each { println it.name } }
gradle
-q printProperties
的輸出結果
> gradle -q printProperties 3.1.0.RELEASE [email protected] main plugin
在此示例中, 一個ext
代碼塊將兩個額外屬性添加到project
對象中。此外,通過將ext.purpose
設置爲null
(null
是一個允許的值),一個名爲purpose
的屬性被添加到每個源碼集(source
set)。一旦屬性被添加,他們就可以像預定的屬性一樣被讀取和設置。
通過添加屬性所要求特殊的語法,Gradle 可以在你試圖設置 (預定義的或額外的) 的屬性,但該屬性拼寫錯誤或不存在時 fail fast。[5]額外屬性在任何能夠訪問它們所屬的對象的地方都可以被訪問,這使它們有着比局部變量更廣泛的作用域。父項目上的額外屬性,在子項目中也可以訪問。
有關額外屬性和它們的 API 的詳細信息,請參閱ExtraPropertiesExtension
。
Groovy 提供了用於創建 DSL 的大量特點,並且 Gradle 構建語言利用了這些特點。瞭解構建語言是如何工作的,將有助於你編寫構建腳本,特別是當你開始寫自定義插件和任務的時候。
Groovy 對 JVM 的類增加了很多有用的方法。例如, iterable
新增的each
方法,會對iterable
的元素進行遍歷:
示例 13.4. Groovy JDK 的方法
build.gradle
<span class="hl-comment" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(175, 175, 175);">// Iterable gets an each() method</span> configurations.runtime.each { File f -> println f }
可以看看http://groovy.codehaus.org/groovy-jdk/,瞭解更多詳細信息。
Groovy 會自動地把一個屬性的引用轉換爲對適當的 getter 或 setter 方法的調用。
例子 13.5. 屬性訪問器
build.gradle
<span class="hl-comment" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(175, 175, 175);">// Using a getter method</span> println project.buildDir println getProject().getBuildDir() <span class="hl-comment" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(175, 175, 175);">// Using a setter method</span> project.buildDir = <span class="hl-string" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(131, 194, 131);">'target'</span> getProject().setBuildDir(<span class="hl-string" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(131, 194, 131);">'target'</span>)
調用方法時括號是可選的。
示例 13.6. 不帶括號的方法調用
build.gradle
test.systemProperty <span class="hl-string" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(131, 194, 131);">'some.prop'</span>, <span class="hl-string" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(131, 194, 131);">'value'</span> test.systemProperty(<span class="hl-string" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(131, 194, 131);">'some.prop'</span>, <span class="hl-string" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(131, 194, 131);">'value'</span>)
Groovy 提供了一些定義List
和Map
實例的快捷寫法。
Example 13.7. List and map
build.gradle
<span class="hl-comment" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(175, 175, 175);">// List literal</span> test.includes = [<span class="hl-string" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(131, 194, 131);">'org/gradle/api/**'</span>, <span class="hl-string" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(131, 194, 131);">'org/gradle/internal/**'</span>] List<String> list = <span class="hl-keyword" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(221, 196, 152);">new</span> ArrayList<String>() list.add(<span class="hl-string" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(131, 194, 131);">'org/gradle/api/**'</span>) list.add(<span class="hl-string" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(131, 194, 131);">'org/gradle/internal/**'</span>) test.includes = list <span class="hl-comment" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(175, 175, 175);">// Map literal</span> apply plugin: <span class="hl-string" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(131, 194, 131);">'java'</span> Map<String, String> map = <span class="hl-keyword" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(221, 196, 152);">new</span> HashMap<String, String>() map.put(<span class="hl-string" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(131, 194, 131);">'plugin'</span>, <span class="hl-string" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(131, 194, 131);">'java'</span>) apply(map)
Gradle DSL 在很多地方使用閉包。你可以在這裏查看更多有關閉包的資料。當方法的最後一個參數是一個閉包時,你可以把閉包放在方法調用之後:
Example 13.8. 作爲方法參數的閉包
build.gradle
repositories { println <span class="hl-string" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(131, 194, 131);">"in a closure"</span> } repositories() { println <span class="hl-string" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(131, 194, 131);">"in a closure"</span> } repositories({ println <span class="hl-string" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(131, 194, 131);">"in a closure"</span> })
每個閉包都有一個委託
對象,Groovy
使用它來查找變量和方法的引用,而不是作爲閉包的局部變量或參數。Gradle 在配置閉包中使用到它,把委託
對象設置爲被配置的對象。
Example 13.9. 閉包委託
build.gradle
dependencies { assert delegate == project.dependencies compile(<span class="hl-string" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(131, 194, 131);">'junit:junit:4.11'</span>) delegate.compile(<span class="hl-string" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; vertical-align: baseline; color: rgb(131, 194, 131);">'junit:junit:4.11'</span>) }