Gradle 建置生命週期的初始化階段會使用設定檔,在您的 專案根目錄中尋找根專案和包含的子專案。

author gradle 6

然後,對於設定檔中包含的每個專案,Gradle 會建立一個 Project 實例。

接著,Gradle 會尋找對應的建置腳本檔案,該檔案會在配置階段中使用。

建置腳本

每個 Gradle 建置都包含一個或多個專案;一個專案和子專案

專案通常對應於需要建置的軟體元件,例如函式庫或應用程式。它可能代表一個函式庫 JAR、一個 Web 應用程式,或是一個從其他專案產生的 JAR 組裝而成的發佈 ZIP。

另一方面,它可能代表要完成的事項,例如將您的應用程式部署到預備或生產環境。

Gradle 腳本以 Groovy DSL 或 Kotlin DSL(領域特定語言)編寫。

建置腳本配置專案,並與 Project 類型的物件相關聯。

Build

當建置腳本執行時,它會配置 Project

建置腳本可以是 Groovy 中的 *.gradle 檔案,或是 Kotlin 中的 *.gradle.kts 檔案。

建置腳本配置 Project 物件及其子物件。

Project 物件

Project 物件是 Gradle API 的一部分

  • 在 Groovy DSL 中,Project 物件的文件位於此處

  • 在 Kotlin DSL 中,Project 物件的文件位於此處

建置腳本中的許多頂層屬性和區塊都是 Project API 的一部分。

例如,以下建置腳本使用 Project.name 屬性來印出專案的名稱

build.gradle.kts
println(name)
println(project.name)
build.gradle
println name
println project.name
$ gradle -q check
project-api
project-api

println 語句都會印出相同的屬性。

第一個語句使用對 Project 物件的 name 屬性的頂層參考。第二個語句使用任何建置腳本都可用的 project 屬性,該屬性會傳回相關聯的 Project 物件。

標準專案屬性

Project 物件在您的建置腳本中公開一組標準屬性。

下表列出了一些常用的屬性

名稱 類型 描述

name

String

專案目錄的名稱。

path

String

專案的完整名稱。

description

String

專案的描述。

dependencies

DependencyHandler

傳回專案的依賴處理器。

repositories

RepositoryHandler

傳回專案的儲存庫處理器。

layout

ProjectLayout

提供對專案幾個重要位置的存取權。

group

Object

此專案的群組。

version

Object

此專案的版本。

下表列出了一些常用的方法

名稱 描述

uri()

將檔案路徑解析為 URI,相對於此專案的專案目錄。

task()

使用給定的名稱建立一個 Task,並將其新增到此專案。

建置腳本結構

建置腳本由 { …​ } 組成,這是 Groovy 和 Kotlin 中的特殊物件。此物件在 Kotlin 中稱為lambda,在 Groovy 中稱為closure

簡而言之,plugins{ } 區塊是一個方法調用,其中 Kotlin lambda 物件或 Groovy closure 物件作為引數傳遞。它是以下簡寫形式

plugins(function() {
    id("plugin")
})

區塊會對應到 Gradle API 方法。

函數內部的程式碼會針對一個名為 receiverthis 物件(在 Kotlin lambda 中)和一個名為 delegatethis 物件(在 Groovy closure 中)執行。Gradle 決定正確的 this 物件,並調用正確的對應方法。方法調用 id("plugin") 物件的 this 類型為 PluginDependenciesSpec

建置腳本基本上是由建立在 DSL 之上的 Gradle API 調用組成。Gradle 會逐行、由上而下執行腳本。

讓我們看看一個範例並將其分解

build.gradle.kts
plugins {   (1)
    id("application")
}

repositories {  (2)
    mavenCentral()
}

dependencies {  (3)
    testImplementation("org.junit.jupiter:junit-jupiter-engine:5.9.3")
    testRuntimeOnly("org.junit.platform:junit-platform-launcher")
    implementation("com.google.guava:guava:32.1.1-jre")
}

application {   (4)
    mainClass = "com.example.Main"
}

tasks.named<Test>("test") { (5)
    useJUnitPlatform()
}

tasks.named<Javadoc>("javadoc").configure {
    exclude("app/Internal*.java")
    exclude("app/internal/*")
}

tasks.register<Zip>("zip-reports") {
    from("Reports/")
    include("*")
    archiveFileName.set("Reports.zip")
    destinationDirectory.set(file("/dir"))
}
build.gradle
plugins {   (1)
    id 'application'
}

repositories {  (2)
    mavenCentral()
}

dependencies {  (3)
    testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.9.3'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
    implementation 'com.google.guava:guava:32.1.1-jre'
}

application {   (4)
    mainClass = 'com.example.Main'
}

tasks.named('test', Test) { (5)
    useJUnitPlatform()
}

tasks.named('javadoc', Javadoc).configure {
    exclude 'app/Internal*.java'
    exclude 'app/internal/*'
}

tasks.register('zip-reports', Zip) {
    from 'Reports/'
    include '*'
    archiveFileName = 'Reports.zip'
    destinationDirectory = file('/dir')
}
1 將外掛套用至建置。
2 定義可以找到依賴關係的位置。
3 新增依賴關係。
4 設定屬性。
5 註冊和配置任務。

1. 將外掛套用至建置

外掛用於擴展 Gradle。它們也用於模組化和重複使用專案配置。

可以使用 PluginDependenciesSpec plugins 腳本區塊套用外掛。

plugins 區塊是首選方法

build.gradle.kts
plugins {   (1)
    id("application")
}
build.gradle
plugins {   (1)
    id 'application'
}

在範例中,已套用 Gradle 內含的 application 外掛,將我們的專案描述為 Java 應用程式。

2. 定義可以找到依賴關係的位置

專案通常有許多工作所需的依賴關係。依賴關係包括外掛、函式庫或組件,Gradle 必須下載這些依賴關係才能成功建置。

建置腳本讓 Gradle 知道在哪裡尋找依賴關係的二進制檔案。可以提供多個位置

build.gradle.kts
repositories {  (2)
    mavenCentral()
}
build.gradle
repositories {  (2)
    mavenCentral()
}

在範例中,guava 函式庫和 JetBrains Kotlin 外掛 (org.jetbrains.kotlin.jvm) 將從 Maven Central Repository 下載。

3. 新增依賴關係

專案通常有許多工作所需的依賴關係。這些依賴關係通常是預編譯類別的函式庫,這些類別會匯入專案的原始碼中。

依賴關係透過配置進行管理,並從儲存庫中檢索。

使用 Project.getDependencies() 方法傳回的 DependencyHandler 來管理依賴關係。使用 Project.getRepositories() 方法傳回的 RepositoryHandler 來管理儲存庫。

build.gradle.kts
dependencies {  (3)
    testImplementation("org.junit.jupiter:junit-jupiter-engine:5.9.3")
    testRuntimeOnly("org.junit.platform:junit-platform-launcher")
    implementation("com.google.guava:guava:32.1.1-jre")
}
build.gradle
dependencies {  (3)
    testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.9.3'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
    implementation 'com.google.guava:guava:32.1.1-jre'
}

在範例中,應用程式程式碼使用 Google 的 guava 函式庫。Guava 提供用於集合、快取、原始類型支援、並行、通用註解、字串處理、I/O 和驗證的實用方法。

4. 設定屬性

外掛可以使用擴展將屬性和方法新增至專案。

Project 物件具有相關聯的 ExtensionContainer 物件,其中包含已套用至專案的外掛的所有設定和屬性。

在範例中,application 外掛新增了一個 application 屬性,用於詳細說明我們 Java 應用程式的主要類別

build.gradle.kts
application {   (4)
    mainClass = "com.example.Main"
}
build.gradle
application {   (4)
    mainClass = 'com.example.Main'
}

5. 註冊和配置任務

任務執行一些基本的工作,例如編譯類別、執行單元測試或壓縮 WAR 檔案。

雖然任務通常在外掛中定義,但您可能需要在建置腳本中註冊或配置任務。

註冊任務會將任務新增至您的專案。

您可以使用 TaskContainer.register(java.lang.String) 方法在專案中註冊任務

build.gradle.kts
tasks.register<Zip>("zip-reports") {
    from("Reports/")
    include("*")
    archiveFileName.set("Reports.zip")
    destinationDirectory.set(file("/dir"))
}
build.gradle
tasks.register('zip-reports', Zip) {
    from 'Reports/'
    include '*'
    archiveFileName = 'Reports.zip'
    destinationDirectory = file('/dir')
}

您可能已經看過 TaskContainer.create(java.lang.String) 方法的用法,應避免使用此方法

tasks.create<Zip>("zip-reports") { }
register() 啟用了任務配置避免,因此優先於 create()

您可以使用 TaskCollection.named(java.lang.String) 方法找到要配置的任務

build.gradle.kts
tasks.named<Test>("test") { (5)
    useJUnitPlatform()
}
build.gradle
tasks.named('test', Test) { (5)
    useJUnitPlatform()
}

以下範例配置 Javadoc 任務,以自動從 Java 程式碼產生 HTML 文件

build.gradle.kts
tasks.named<Javadoc>("javadoc").configure {
    exclude("app/Internal*.java")
    exclude("app/internal/*")
}
build.gradle
tasks.named('javadoc', Javadoc).configure {
    exclude 'app/Internal*.java'
    exclude 'app/internal/*'
}

建置腳本編寫

建置腳本由零個或多個語句和腳本區塊組成

println(project.layout.projectDirectory);

語句可以包括方法調用、屬性賦值和本機變數定義

version = '1.0.0.GA'

腳本區塊是一個方法調用,它將 closure/lambda 作為參數

configurations {
}

closure/lambda 在執行時配置某些委派物件

repositories {
    google()
}

建置腳本也是 Groovy 或 Kotlin 腳本

build.gradle.kts
tasks.register("upper") {
    doLast {
        val someString = "mY_nAmE"
        println("Original: $someString")
        println("Upper case: ${someString.toUpperCase()}")
    }
}
build.gradle
tasks.register('upper') {
    doLast {
        String someString = 'mY_nAmE'
        println "Original: $someString"
        println "Upper case: ${someString.toUpperCase()}"
    }
}
$ gradle -q upper
Original: mY_nAmE
Upper case: MY_NAME

它可以包含 Groovy 或 Kotlin 腳本中允許的元素,例如方法定義和類別定義

build.gradle.kts
tasks.register("count") {
    doLast {
        repeat(4) { print("$it ") }
    }
}
build.gradle
tasks.register('count') {
    doLast {
        4.times { print "$it " }
    }
}
$ gradle -q count
0 1 2 3 

彈性任務註冊

使用 Groovy 或 Kotlin 語言的功能,您可以在迴圈中註冊多個任務

build.gradle.kts
repeat(4) { counter ->
    tasks.register("task$counter") {
        doLast {
            println("I'm task number $counter")
        }
    }
}
build.gradle
4.times { counter ->
    tasks.register("task$counter") {
        doLast {
            println "I'm task number $counter"
        }
    }
}
$ gradle -q task1
I'm task number 1

Gradle 類型

在 Gradle 中,類型屬性提供器是管理和配置建置邏輯的基礎

  • 類型:Gradle 定義類型(例如 TaskConfigurationFile 等)來表示建置組件。您可以擴展這些類型以建立自訂任務或網域物件。

  • 屬性:Gradle 屬性(例如 Property<T>ListProperty<T>SetProperty<T>)用於建置配置。它們允許延遲評估,這表示它們的值僅在需要時才計算,從而增強彈性和效能。

  • 提供器Provider<T> 表示延遲計算或檢索的值。提供器通常與屬性一起使用,以將值計算延遲到必要時。這對於將動態、執行階段值整合到您的建置中特別有用。

您可以在了解 Gradle 類型中了解更多資訊。

宣告變數

建置腳本可以宣告兩種變數:本機變數額外屬性

本機變數

使用 val 關鍵字宣告本機變數。本機變數僅在宣告它們的範圍內可見。它們是底層 Kotlin 語言的功能。

使用 def 關鍵字宣告本機變數。本機變數僅在宣告它們的範圍內可見。它們是底層 Groovy 語言的功能。

build.gradle.kts
val dest = "dest"

tasks.register<Copy>("copy") {
    from("source")
    into(dest)
}
build.gradle
def dest = 'dest'

tasks.register('copy', Copy) {
    from 'source'
    into dest
}

額外屬性

Gradle 的增強物件,包括專案、任務和原始碼集,可以保留使用者定義的屬性。

透過擁有物件的 extra 屬性新增、讀取和設定額外屬性。或者,您可以使用 Kotlin 委派屬性透過 by extra 存取額外屬性。

透過擁有物件的 ext 屬性新增、讀取和設定額外屬性。或者,您可以使用 ext 區塊同時新增多個屬性。

build.gradle.kts
plugins {
    id("java-library")
}

val springVersion by extra("3.1.0.RELEASE")
val emailNotification by extra { "build@master.org" }

sourceSets.all { extra["purpose"] = null }

sourceSets {
    main {
        extra["purpose"] = "production"
    }
    test {
        extra["purpose"] = "test"
    }
    create("plugin") {
        extra["purpose"] = "production"
    }
}

tasks.register("printProperties") {
    val springVersion = springVersion
    val emailNotification = emailNotification
    val productionSourceSets = provider {
        sourceSets.matching { it.extra["purpose"] == "production" }.map { it.name }
    }
    doLast {
        println(springVersion)
        println(emailNotification)
        productionSourceSets.get().forEach { println(it) }
    }
}
build.gradle
plugins {
    id 'java-library'
}

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

tasks.register('printProperties') {
    def springVersion = springVersion
    def emailNotification = emailNotification
    def productionSourceSets = provider {
        sourceSets.matching { it.purpose == "production" }.collect { it.name }
    }
    doLast {
        println springVersion
        println emailNotification
        productionSourceSets.get().each { println it }
    }
}
$ gradle -q printProperties
3.1.0.RELEASE
build@master.org
main
plugin

此範例透過 by extra 將兩個額外屬性新增至 project 物件。此外,此範例透過將 extra["purpose"] 設定為 null,將名為 purpose 的屬性新增至每個原始碼集。新增後,您可以透過 extra 讀取和設定這些屬性。

此範例透過 ext 區塊將兩個額外屬性新增至 project 物件。此外,此範例透過將 ext.purpose 設定為 null,將名為 purpose 的屬性新增至每個原始碼集。新增後,您可以像預定義的屬性一樣讀取和設定所有這些屬性。

Gradle 需要特殊語法來新增屬性,以便它可以快速失敗。例如,這允許 Gradle 在腳本嘗試設定不存在的屬性時識別出來。您可以在可以存取其擁有物件的任何位置存取額外屬性。這使額外屬性比本機變數具有更廣泛的範圍。子專案可以存取其父專案上的額外屬性。

有關額外屬性的更多資訊,請參閱 API 文件中的 ExtraPropertiesExtension

配置任意物件

範例 greet() 任務顯示了任意物件配置的範例

build.gradle.kts
class UserInfo(
    var name: String? = null,
    var email: String? = null
)

tasks.register("greet") {
    val user = UserInfo().apply {
        name = "Isaac Newton"
        email = "isaac@newton.me"
    }
    doLast {
        println(user.name)
        println(user.email)
    }
}
build.gradle
class UserInfo {
    String name
    String email
}

tasks.register('greet') {
    def user = configure(new UserInfo()) {
        name = "Isaac Newton"
        email = "isaac@newton.me"
    }
    doLast {
        println user.name
        println user.email
    }
}
$ gradle -q greet
Isaac Newton
isaac@newton.me

Closure 委派

每個 closure 都有一個 delegate 物件。Groovy 使用此委派來查找變數和方法參考,以查找非本機變數和 closure 參數。Gradle 將其用於配置 closure,其中 delegate 物件指的是正在配置的物件。

build.gradle
dependencies {
    assert delegate == project.dependencies
    testImplementation('junit:junit:4.13')
    delegate.testImplementation('junit:junit:4.13')
}

預設匯入

為了使建置腳本更簡潔,Gradle 會自動將一組 import 語句新增至腳本。

因此,您可以寫入 throw new StopExecutionException() 而不是寫入 throw new org.gradle.api.tasks.StopExecutionException()

Gradle 隱含地將以下匯入新增至每個腳本

import org.gradle.*
import org.gradle.api.*
import org.gradle.api.artifacts.*
import org.gradle.api.artifacts.capability.*
import org.gradle.api.artifacts.component.*
import org.gradle.api.artifacts.dsl.*
import org.gradle.api.artifacts.ivy.*
import org.gradle.api.artifacts.maven.*
import org.gradle.api.artifacts.query.*
import org.gradle.api.artifacts.repositories.*
import org.gradle.api.artifacts.result.*
import org.gradle.api.artifacts.transform.*
import org.gradle.api.artifacts.type.*
import org.gradle.api.artifacts.verification.*
import org.gradle.api.attributes.*
import org.gradle.api.attributes.java.*
import org.gradle.api.attributes.plugin.*
import org.gradle.api.cache.*
import org.gradle.api.capabilities.*
import org.gradle.api.component.*
import org.gradle.api.configuration.*
import org.gradle.api.credentials.*
import org.gradle.api.distribution.*
import org.gradle.api.distribution.plugins.*
import org.gradle.api.execution.*
import org.gradle.api.file.*
import org.gradle.api.flow.*
import org.gradle.api.initialization.*
import org.gradle.api.initialization.definition.*
import org.gradle.api.initialization.dsl.*
import org.gradle.api.initialization.resolve.*
import org.gradle.api.invocation.*
import org.gradle.api.java.archives.*
import org.gradle.api.jvm.*
import org.gradle.api.launcher.cli.*
import org.gradle.api.logging.*
import org.gradle.api.logging.configuration.*
import org.gradle.api.model.*
import org.gradle.api.plugins.*
import org.gradle.api.plugins.antlr.*
import org.gradle.api.plugins.catalog.*
import org.gradle.api.plugins.jvm.*
import org.gradle.api.plugins.quality.*
import org.gradle.api.plugins.scala.*
import org.gradle.api.problems.*
import org.gradle.api.project.*
import org.gradle.api.provider.*
import org.gradle.api.publish.*
import org.gradle.api.publish.ivy.*
import org.gradle.api.publish.ivy.plugins.*
import org.gradle.api.publish.ivy.tasks.*
import org.gradle.api.publish.maven.*
import org.gradle.api.publish.maven.plugins.*
import org.gradle.api.publish.maven.tasks.*
import org.gradle.api.publish.plugins.*
import org.gradle.api.publish.tasks.*
import org.gradle.api.reflect.*
import org.gradle.api.reporting.*
import org.gradle.api.reporting.components.*
import org.gradle.api.reporting.dependencies.*
import org.gradle.api.reporting.dependents.*
import org.gradle.api.reporting.model.*
import org.gradle.api.reporting.plugins.*
import org.gradle.api.resources.*
import org.gradle.api.services.*
import org.gradle.api.specs.*
import org.gradle.api.tasks.*
import org.gradle.api.tasks.ant.*
import org.gradle.api.tasks.application.*
import org.gradle.api.tasks.bundling.*
import org.gradle.api.tasks.compile.*
import org.gradle.api.tasks.diagnostics.*
import org.gradle.api.tasks.diagnostics.artifact.transforms.*
import org.gradle.api.tasks.diagnostics.configurations.*
import org.gradle.api.tasks.incremental.*
import org.gradle.api.tasks.javadoc.*
import org.gradle.api.tasks.options.*
import org.gradle.api.tasks.scala.*
import org.gradle.api.tasks.testing.*
import org.gradle.api.tasks.testing.junit.*
import org.gradle.api.tasks.testing.junitplatform.*
import org.gradle.api.tasks.testing.testng.*
import org.gradle.api.tasks.util.*
import org.gradle.api.tasks.wrapper.*
import org.gradle.api.toolchain.management.*
import org.gradle.authentication.*
import org.gradle.authentication.aws.*
import org.gradle.authentication.http.*
import org.gradle.build.event.*
import org.gradle.buildconfiguration.tasks.*
import org.gradle.buildinit.*
import org.gradle.buildinit.plugins.*
import org.gradle.buildinit.specs.*
import org.gradle.buildinit.tasks.*
import org.gradle.caching.*
import org.gradle.caching.configuration.*
import org.gradle.caching.http.*
import org.gradle.caching.local.*
import org.gradle.concurrent.*
import org.gradle.external.javadoc.*
import org.gradle.ide.visualstudio.*
import org.gradle.ide.visualstudio.plugins.*
import org.gradle.ide.visualstudio.tasks.*
import org.gradle.ide.xcode.*
import org.gradle.ide.xcode.plugins.*
import org.gradle.ide.xcode.tasks.*
import org.gradle.ivy.*
import org.gradle.jvm.*
import org.gradle.jvm.application.scripts.*
import org.gradle.jvm.application.tasks.*
import org.gradle.jvm.tasks.*
import org.gradle.jvm.toolchain.*
import org.gradle.language.*
import org.gradle.language.assembler.*
import org.gradle.language.assembler.plugins.*
import org.gradle.language.assembler.tasks.*
import org.gradle.language.base.*
import org.gradle.language.base.artifact.*
import org.gradle.language.base.compile.*
import org.gradle.language.base.plugins.*
import org.gradle.language.base.sources.*
import org.gradle.language.c.*
import org.gradle.language.c.plugins.*
import org.gradle.language.c.tasks.*
import org.gradle.language.cpp.*
import org.gradle.language.cpp.plugins.*
import org.gradle.language.cpp.tasks.*
import org.gradle.language.java.artifact.*
import org.gradle.language.jvm.tasks.*
import org.gradle.language.nativeplatform.*
import org.gradle.language.nativeplatform.tasks.*
import org.gradle.language.objectivec.*
import org.gradle.language.objectivec.plugins.*
import org.gradle.language.objectivec.tasks.*
import org.gradle.language.objectivecpp.*
import org.gradle.language.objectivecpp.plugins.*
import org.gradle.language.objectivecpp.tasks.*
import org.gradle.language.plugins.*
import org.gradle.language.rc.*
import org.gradle.language.rc.plugins.*
import org.gradle.language.rc.tasks.*
import org.gradle.language.scala.tasks.*
import org.gradle.language.swift.*
import org.gradle.language.swift.plugins.*
import org.gradle.language.swift.tasks.*
import org.gradle.maven.*
import org.gradle.model.*
import org.gradle.nativeplatform.*
import org.gradle.nativeplatform.platform.*
import org.gradle.nativeplatform.plugins.*
import org.gradle.nativeplatform.tasks.*
import org.gradle.nativeplatform.test.*
import org.gradle.nativeplatform.test.cpp.*
import org.gradle.nativeplatform.test.cpp.plugins.*
import org.gradle.nativeplatform.test.cunit.*
import org.gradle.nativeplatform.test.cunit.plugins.*
import org.gradle.nativeplatform.test.cunit.tasks.*
import org.gradle.nativeplatform.test.googletest.*
import org.gradle.nativeplatform.test.googletest.plugins.*
import org.gradle.nativeplatform.test.plugins.*
import org.gradle.nativeplatform.test.tasks.*
import org.gradle.nativeplatform.test.xctest.*
import org.gradle.nativeplatform.test.xctest.plugins.*
import org.gradle.nativeplatform.test.xctest.tasks.*
import org.gradle.nativeplatform.toolchain.*
import org.gradle.nativeplatform.toolchain.plugins.*
import org.gradle.normalization.*
import org.gradle.platform.*
import org.gradle.platform.base.*
import org.gradle.platform.base.binary.*
import org.gradle.platform.base.component.*
import org.gradle.platform.base.plugins.*
import org.gradle.plugin.devel.*
import org.gradle.plugin.devel.plugins.*
import org.gradle.plugin.devel.tasks.*
import org.gradle.plugin.management.*
import org.gradle.plugin.use.*
import org.gradle.plugins.ear.*
import org.gradle.plugins.ear.descriptor.*
import org.gradle.plugins.ide.*
import org.gradle.plugins.ide.api.*
import org.gradle.plugins.ide.eclipse.*
import org.gradle.plugins.ide.idea.*
import org.gradle.plugins.signing.*
import org.gradle.plugins.signing.signatory.*
import org.gradle.plugins.signing.signatory.pgp.*
import org.gradle.plugins.signing.type.*
import org.gradle.plugins.signing.type.pgp.*
import org.gradle.process.*
import org.gradle.swiftpm.*
import org.gradle.swiftpm.plugins.*
import org.gradle.swiftpm.tasks.*
import org.gradle.testing.base.*
import org.gradle.testing.base.plugins.*
import org.gradle.testing.jacoco.plugins.*
import org.gradle.testing.jacoco.tasks.*
import org.gradle.testing.jacoco.tasks.rules.*
import org.gradle.testkit.runner.*
import org.gradle.util.*
import org.gradle.vcs.*
import org.gradle.vcs.git.*
import org.gradle.work.*
import org.gradle.workers.*

下一步: 了解如何使用任務 >>