Gradle第十三章:編寫構建腳本

本文來源於:http://blog.csdn.net/maosidiaoxian/article/details/40976325

第十三章 編寫構建腳本

這一章着眼於一些編寫構建腳本的詳細信息。

13.1. Gradle 構建語言

Gradle 提供一種領域特定語言或者說是 DSL,來描述構建。這種構建語言基於 Groovy 中,並進行了一些補充,使其易於描述構建。

13.2. Project API

第 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屬性。

13.2.1. 標準project屬性

Project對象提供了一些在構建腳本中可用的標準的屬性。下表列出了常用的幾個屬性。

表 13.1. Project屬性

名稱 類型 默認值
project Project Project實例
name String 項目目錄的名稱。
path String 項目的絕對路徑。
description String 項目的描述。
projectDir File 包含生成腳本的目錄。
buildDir File projectDir/build
group Object 未指定
version Object 未指定
ant AntBuilder AntBuilder實例

13.3.  Script API

當 Gradle 執行一個腳本時,它將腳本編譯爲一個實現了Script接口的類。這意味着所有由該Script接口聲明的屬性和方法在您的腳本中是可用的。

13.4. 聲明變量

有兩類可以在生成腳本中聲明的變量: 局部變量和額外屬性。

13.4.1. 局部變量局部

局部變量是用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
}

13.4.2. 額外屬性

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設置爲nullnull是一個允許的值),一個名爲purpose的屬性被添加到每個源碼集(source set)。一旦屬性被添加,他們就可以像預定的屬性一樣被讀取和設置。

通過添加屬性所要求特殊的語法,Gradle 可以在你試圖設置 (預定義的或額外的) 的屬性,但該屬性拼寫錯誤或不存在時 fail fast。[5]額外屬性在任何能夠訪問它們所屬的對象的地方都可以被訪問,這使它們有着比局部變量更廣泛的作用域。父項目上的額外屬性,在子項目中也可以訪問。

有關額外屬性和它們的 API 的詳細信息,請參閱ExtraPropertiesExtension

13.5.一些 Groovy 的基礎知識

Groovy 提供了用於創建 DSL 的大量特點,並且 Gradle 構建語言利用了這些特點。瞭解構建語言是如何工作的,將有助於你編寫構建腳本,特別是當你開始寫自定義插件和任務的時候。

13.5.1. Groovy JDK

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/,瞭解更多詳細信息。

13.5.2. 屬性訪問器

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.5.3 括號可選的方法調用

調用方法時括號是可選的。

示例 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>)

13.5.4. List 和 Map

Groovy 提供了一些定義ListMap實例的快捷寫法。

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)

13.5.5.作爲方法最後一個參數的閉包

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> })

13.5.6. 閉包委託(delegate)

每個閉包都有一個委託對象,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>)
}


[5截至 Gradle 1.0-milestone-9版本,我們鼓勵但不強制要求使用 ext 來添加額外屬性因此,當未知的屬性被設置時,Gradle不會構建失敗。然而,它將打印一個警告。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章