iT邦幫忙

2021 iThome 鐵人賽

DAY 24
0
Software Development

Gradle 通靈術系列 第 24

第二十四天:三探 Gradle Plugin

延續昨天的 Plugin 實作,今天來看一下 Extension 及 Task 類別各要怎麼實作?

Extension 類別

Extension 類別負責處理 Plugin 的設定機制,請建立 src/main/kotlin/io/kraftsman/plugins/filediff 資料夾結構,我們將在裡面放置所有相關的類別。

接著建立一個 FileDiffExtension.kt 的檔案,裡面的程式碼大至上是:

package io.kraftsman.plugins.filediff

import org.gradle.api.file.RegularFileProperty

abstract class FileDiffExtension {
    abstract fun getFile1(): RegularFileProperty
    abstract fun getFile2(): RegularFileProperty
}

我們有兩個屬性代表輸入的檔案。請注意,這些是擴充 Property 的 RegularFileProperty 類別。在 Gradle 中,屬性對象是一種在實際設置之前引用值的方法。這對於 Plugin 和 Task 很有用,因為在建構腳本中配置其實際值之前可能會引用屬性值。

Task 類別

接著來建立 Task 類別 FileDiffTask.kt,也就是實際進行比對工作的那個類別:

package io.kraftsman.plugins.filediff

import org.gradle.api.DefaultTask
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction

abstract class FileDiffTask(): DefaultTask {
    @InputFile
    abstract fun getFile1(): RegularFileProperty
    @InputFile
    abstract fun getFile2(): RegularFileProperty
    @OutputFile
    abstract fun getResultFile(): RegularFileProperty

    init {
        resultFile.convention(project.layout.buildDirectory.file('diff-result.txt'))
    }

    @TaskAction
    fun diff() {
        String diffResult
        if (size(file1) == size(file2)) {
            diffResult = "Files have the same size at ${file1.get().asFile.size()} bytes."
        } else {
            val largestFile: File = if (size(file1) > size(file2)) {
                file1.get().asFile
            } else { 
                file2.get().asFile
            }
            diffResult = "${largestFile.toString()} was the largest file at ${largestFile.size()} bytes."
        }

        resultFile.get().asFile.write diffResult

        println("File written to $resultFile")
        println(diffResult)
    }

    private fun size(regularFileProperty: RegularFileProperty): Long {
        return regularFileProperty.get().asFile.size()
    }
}

現在我們有:

  • 兩個輸入檔案的屬性:Plugin 將會從屬性取得值然後送到任務去執行
  • @InputFile Annotation:在兩個輸入檔案的屬性上,這表示 Gradle 會去監看這些檔案的變更,並在檔案變更的時候重新執行一次
  • 輸出檔案屬性:Plugin 將會把差異比對的結果輸出到 @OutputFile Annotation 屬性上。Gradle 將會監看這個檔案,並在變更的時候重新執行一次
  • 一個被 @TaskAction 標記的方法:此方法是在執行任務時運行的方法。它使用兩個檔案輸入來計算哪個更大,並產生文字輸出,然後將結果寫入 resultFile 和標準輸出

上一篇
第二十三天:再探 Gradle Plugin
系列文
Gradle 通靈術24
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言