透過在建置指令碼中建立一個簡單的任務,來學習撰寫 Gradle 任務的基本知識。

在本節中,您將

  • 了解任務

  • 為外掛程式建立自訂任務

步驟 0. 開始之前

  1. 您已在 第 1 部分 中初始化您的 Java 應用程式。

  2. 您從 第 2 部分 了解 Gradle 建置生命週期。

  3. 您已在 第 3 部分 中新增子專案和個別建置。

  4. 您已在 第 4 部分 中檢視設定檔。

  5. 您已在 第 5 部分 中撰寫建置指令碼。

步驟 1. 了解任務

任務是一段包含動作順序的可執行程式碼。

動作會透過 doFirst{}doLast{} 閉包新增到任務中。

任務可以依賴於其他任務。

步驟 2. 註冊並設定任務

在本教學課程的早期,我們已在 app 建置指令碼中註冊並設定 task1

app/build.gradle.kts
tasks.register("task1"){  (1)
    println("REGISTER TASK1: This is executed during the configuration phase")
}

tasks.named("task1"){  (2)
    println("NAMED TASK1: This is executed during the configuration phase")
    doFirst {
        println("NAMED TASK1 - doFirst: This is executed during the execution phase")
    }
    doLast {
        println("NAMED TASK1 - doLast: This is executed during the execution phase")
    }
}
1 您可以使用 register() 方法來建立新任務。
2 您可以使用 named() 方法來設定現有任務。
app/build.gradle
tasks.register("task1") {  (1)
    println("REGISTER TASK1: This is executed during the configuration phase")
}

tasks.named("task1") {  (2)
    println("NAMED TASK1: This is executed during the configuration phase")
    doFirst {
        println("NAMED TASK1 - doFirst: This is executed during the execution phase")
    }
    doLast {
        println("NAMED TASK1 - doLast: This is executed during the execution phase")
    }
}
1 您可以使用 register() 方法來建立新任務。
2 您可以使用 named() 方法來設定現有任務。

步驟 3. 建立自訂任務

若要建立自訂任務,您必須在 Groovy DSL 中的 DefaultTask 或 Kotlin DSL 中的 DefaultTask 中建立子類別。

使用下列程式碼建立一個名為 LicenseTask 的自訂類別,並將其新增至 gradle/license-plugin/plugin/src/main/kotlin/license/LicensePlugin.ktgradle/license-plugin/plugin/src/main/groovy/license/LicensePlugin.groovy 檔案的底部

gradle/license-plugin/plugin/src/main/kotlin/license/LicensePlugin.kt
import org.gradle.api.Project
import org.gradle.api.Plugin
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.TaskAction
import java.io.File
import java.io.InputStream
import java.nio.charset.Charset

class LicensePlugin: Plugin<Project> {
    // Don't change anything here
}

abstract class LicenseTask : DefaultTask() {
    @Input
    val fileName = project.rootDir.toString() + "/license.txt"

    @TaskAction
    fun action() {
        // Read the license text
        val licenseText = File(fileName).readText()
        // Walk the directories looking for java files
        File(project.rootDir.toString()).walk().forEach {
            if (it.extension == "java") {
                // Read the source code
                var ins: InputStream = it.inputStream()
                var content = ins.readBytes().toString(Charset.defaultCharset())
                // Write the license and the source code to the file
                it.writeText(licenseText + content)
            }
        }
    }
}
gradle/license-plugin/plugin/src/main/groovy/license/LicensePlugin.groovy
import org.gradle.api.Project
import org.gradle.api.Plugin
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.TaskAction

class LicensePlugin implements Plugin<Project> {
    // Don't change anything here
}

abstract class LicenseTask extends DefaultTask {
    @Input
    def fileName = project.rootDir.toString() + "/license.txt"

    @TaskAction
    void action() {
        // Read the license text
        def licenseText = new File(fileName).text
        // Walk the directories looking for java files
        new File(project.rootDir.toString()).eachFileRecurse { file ->
            int lastIndexOf = file.getName().lastIndexOf('.')
            if ((lastIndexOf != -1) && (file.getName().substring(lastIndexOf)) == ".java") {// Read the source code
                def content = file.getText()
                //println(licenseText + '\n' + content)
                // Write the license and the source code to the file
                file.text = licenseText + '\n' + content
            }
        }
    }
}

LicenseTask 類別封裝了任務動作邏輯,並宣告任務預期的任何輸入和輸出。

任務動作加上 @TaskAction 註解。在其中,邏輯首先尋找名為「license.txt」的檔案。此檔案包含 Apache 授權的文字

license.txt
/*
* Licensed under the Apache License
*/

然後,任務尋找副檔名為 .java 的檔案,並新增授權標頭。

任務有一個單一輸入,即授權檔案名稱,並加上 @Input 註解。

Gradle 使用 @Input 註解來判斷任務是否需要執行。如果任務之前未執行,或自上次執行後輸入值已變更,則 Gradle 會執行任務。

雖然已建立自訂類別,但尚未將其新增至 LicensePlugin。目前無法執行 LicenseTask

您現在能做的,就是確定 ./gradlew build 在執行時不會失敗

$ ./gradlew build

SETTINGS FILE: This is executed during the initialization phase

> Configure project :app
BUILD SCRIPT: This is executed during the configuration phase

BUILD SUCCESSFUL in 1s
13 actionable tasks: 6 executed, 7 up-to-date

下一步: 撰寫外掛程式 >>