Gradle - 任務
Gradle 構建指令碼描述了一個或多個專案。每個專案都由不同的任務組成,而任務是構建執行的一項工作。
任務可能是編譯一些類,將類檔案儲存到單獨的目標資料夾中,建立 JAR,生成 Javadoc 或將一些存檔釋出到儲存庫。
本章解釋了什麼是任務以及如何生成和執行任務。
定義任務
Task 是一個關鍵字,用於在構建指令碼中定義任務。
請檢視以下示例,它表示一個名為 hello 的任務,該任務列印 tutorialspoint。將以下指令碼複製並儲存到名為 build.gradle 的檔案中。
此構建指令碼定義了一個名為 hello 的任務,用於列印 tutorialspoint 字串。
task hello {
doLast {
println 'tutorialspoint'
}
}
在命令提示符中執行以下命令。它執行上述指令碼。您應該在儲存 build.gradle 檔案的位置執行此操作。
C:\> gradle –q hello
輸出
\以下是程式碼的輸出:
tutorialspoint
您可以透過為 doLast 語句指定一個快捷方式(表示符號 <<)來簡化此 hello 任務。如果您將此快捷方式新增到上面的 hello 任務,它將如下所示:
task hello << {
println 'tutorialspoint'
}
您可以使用 gradle –q hello 命令執行上述指令碼。
以下示例定義了一個名為 hello 的任務。
將以下程式碼複製並儲存到 build.gradle 檔案中。
task (hello) << {
println "tutorialspoint"
}
在命令提示符中執行以下命令。它執行上面給出的指令碼。您應該在儲存 build.gradle 檔案的位置執行此操作。
C:\> gradle –q hello
輸出
輸出如下所示:
tutorialspoint
您還可以使用字串作為任務名稱。請檢視相同的 hello 示例。在這裡,我們將使用 String 作為任務。
將以下程式碼複製並儲存到 build.gradle 檔案中。
task('hello') << {
println "tutorialspoint"
}
在命令提示符中執行以下命令。它執行上面提到的指令碼。您應該在儲存 build.gradle 檔案的位置執行此操作。
C:\> gradle –q hello
輸出
執行上述程式碼後,您應該會看到以下輸出:
tutorialspoint
您還可以使用另一種語法來定義任務。即,使用 create() 方法來定義任務。請檢視下面給出的相同的 hello 示例。
將下面給出的程式碼複製並儲存到 build.gradle 檔案中。
tasks.create(name: 'hello') << {
println "tutorialspoint"
}
在命令提示符中執行以下命令。它執行上面陳述的指令碼。您應該在儲存 build.gradle 檔案的位置執行此操作。
C:\> gradle –q hello
輸出
執行後,您將收到以下輸出:
tutorialspoint
查詢任務
如果您想查詢在構建檔案中定義的任務,則必須使用相應的標準專案屬性。這意味著每個任務都作為專案的屬性可用,其中任務名稱用作屬性名稱。
請檢視以下程式碼,該程式碼將任務作為屬性訪問。
將下面給出的程式碼複製並儲存到 build.gradle 檔案中。
task hello println hello.name println project.hello.name
在命令提示符中執行以下命令。它執行上面給出的指令碼。您應該在儲存 build.gradle 檔案的位置執行此操作。
C:\> gradle –q hello
輸出
輸出如下所示:
hello hello
您還可以透過 tasks 集合使用所有屬性。
將以下程式碼複製並儲存到 build.gradle 檔案中。
task hello println tasks.hello.name println tasks['hello'].name
在命令提示符中執行以下命令。它執行上面提到的指令碼。您應該在儲存 build.gradle 檔案的位置執行此操作。
C:\> gradle –q hello
輸出
這將產生以下輸出:
hello hello
您還可以透過 tasks 訪問任務的路徑。為此,您可以使用任務名稱、相對路徑或絕對路徑呼叫 getByPath() 方法。
將下面給出的程式碼複製並儲存到 build.gradle 檔案中。
project(':projectA') {
task hello
}
task hello
println tasks.getByPath('hello').path
println tasks.getByPath(':hello').path
println tasks.getByPath('projectA:hello').path
println tasks.getByPath(':projectA:hello').path
在命令提示符中執行以下命令。它執行上面給出的指令碼。您應該在儲存 build.gradle 檔案的位置執行此操作。
C:\> gradle –q hello
輸出
輸出如下所示:
:hello :hello :projectA:hello :projectA:hello
向任務新增依賴項
您可以使一個任務依賴於另一個任務,這意味著,當一個任務完成後,另一個任務才會開始。
每個任務都透過任務名稱進行區分。任務名稱的集合由其 tasks 集合引用。要引用另一個專案中的任務,您應該使用專案的路徑作為相應任務名稱的字首。
以下示例將 taskX 的依賴項新增到 taskY。
將下面給出的程式碼複製並儲存到 build.gradle 檔案中。請檢視以下程式碼。
task taskX << {
println 'taskX'
}
task taskY(dependsOn: 'taskX') << {
println "taskY"
}
在命令提示符中執行以下命令。它執行上面陳述的指令碼。您應該在儲存 build.gradle 檔案的位置執行此操作。
C:\> gradle –q taskY
輸出
輸出如下所示:
taskX taskY
上面的示例是使用任務名稱新增任務依賴項。還有另一種方法可以實現任務依賴項,即使用 Task 物件定義依賴項。
讓我們以 taskY 依賴於 taskX 為例,但在這裡,我們使用的是任務物件而不是任務引用名稱。
將以下程式碼複製並儲存到 build.gradle 檔案中。
task taskY << {
println 'taskY'
}
task taskX << {
println 'taskX'
}
taskY.dependsOn taskX
在命令提示符中執行以下命令。您應該在儲存 build.gradle 檔案的位置執行此操作。
C:\> gradle –q taskY
輸出
輸出如下所示:
taskX taskY
上面的示例是使用任務名稱新增任務依賴項。
還有另一種方法可以實現任務依賴項,即使用 Task 物件定義依賴項。
在這裡,我們以 taskY 依賴於 taskX 為例,但是,我們使用的是任務物件而不是任務引用名稱。
將下面給出的程式碼複製並儲存到 build.gradle 檔案中。請檢視以下程式碼。
task taskX << {
println 'taskX'
}
taskX.dependsOn {
tasks.findAll {
task → task.name.startsWith('lib')
}
}
task lib1 << {
println 'lib1'
}
task lib2 << {
println 'lib2'
}
task notALib << {
println 'notALib'
}
在命令提示符中執行以下命令。它執行上面給出的指令碼。您應該在儲存 build.gradle 檔案的位置執行此操作。
C:\> gradle –q taskX
輸出
輸出如下所示:
lib1 lib2 taskX
新增描述
您可以向任務新增描述。執行 Gradle tasks 時會顯示此描述,這可以透過使用 description 關鍵字來實現。
將以下程式碼複製並儲存到 build.gradle 檔案中。請檢視以下程式碼。
task copy(type: Copy) {
description 'Copies the resource directory to the target directory.'
from 'resources'
into 'target'
include('**/*.txt', '**/*.xml', '**/*.properties')
println("description applied")
}
在命令提示符中執行以下命令。您應該在儲存 build.gradle 檔案的位置執行此操作。
C:\> gradle –q copy
如果命令成功執行,您將獲得以下輸出
description applied
跳過任務
可以透過傳遞一個謂詞閉包來跳過任務。只有在任務的方法或閉包在執行任務的實際工作之前丟擲 StopExecutionException 時,這才有可能。
將以下程式碼複製並儲存到 build.gradle 檔案中。
task eclipse << {
println 'Hello Eclipse'
}
// #1st approach - closure returning true, if the task should be executed, false if not.
eclipse.onlyIf {
project.hasProperty('usingEclipse')
}
// #2nd approach - alternatively throw an StopExecutionException() like this
eclipse.doFirst {
if(!usingEclipse) {
throw new StopExecutionException()
}
}
在命令提示符中執行以下命令。您應該在儲存 build.gradle 檔案的位置執行此操作。
C:\> gradle –q eclipse
任務結構
在處理任務時,Gradle 有不同的階段。首先,有一個 配置階段,其中直接在任務的閉包中指定的程式碼將被執行。配置塊將為每個可用的任務執行,而不僅僅是為了那些稍後實際執行的任務。
在配置階段之後,執行階段將執行那些實際執行的任務的 doFirst 或 doLast 閉包內的程式碼。