前回の基本編に続けて、さらにGradleタスクについて理解を深める。
今日の教材はこちら。
[委譲プロパティによるタスク定義]
前回学んだ方法では、tasks.named()のAPIを利用して、別で定義されたタスクにアクションを追加したり、依存関係を追加したりした。
tasks.register("taskX") {
doLast {
println("Hello Earth")
}
}
tasks.named("taskX") {
doFirst {
println("Hello Venus")
}
}
tasks.register("taskY") {
doLast {
println("taskY")
}
}
tasks.named("taskX") {
dependsOn("taskY")
}
別のやり方として、Kotlinの委譲プロパティ(Delegated property)を利用してタスクを定義したり変更したりすることもできる。
val hello by tasks.registering {
doLast {
println("hello")
}
}
この場合、プロパティ名がタスク名になるので、gradle -q helloでタスクを呼び出せる。
$ gradle -q hello hello
GradleのCopyタスククラスを利用してmyCopyタスクを設定する場合、以下のようになる。
// 通常のタスク定義
tasks.register<Copy>("myCopy") {
from(file("srcDir"))
into(buildDir)
}
// 委譲プロパティによるタスク定義
val myCopy by tasks.registering(Copy::class) {
from(file("srcDir"))
into(buildDir)
}
委譲プロパティを利用して定義したタスクについても、依存関係を後から定義することができる。
val taskX by tasks.registering {
doLast {
println("taskX")
}
}
val taskY by tasks.registering {
doLast {
println("taskY")
}
}
taskX {
dependsOn(taskY)
}
上記のtaskXを実行すると、以下のように出力される。
$ gradle -q taskX taskY taskX
tasks.named()を利用するより多少コードがスッキリする気がする。
厳密には、named()に該当するexisting()というメソッドがあり、既存タスクを委譲プロパティにとることができる。
// タスク定義
tasks.register<Copy>("myCopy")
// 既存タスクを委譲プロパティで設定変更
val myCopy by tasks.existing(Copy::class) {
from("resources")
into("target")
}
// さらに設定変更
myCopy {
include("**/*.txt", "**/*.xml", "**/*.properties")
}
[タスクのコンストラクタ]
タスクはKotlinのクラスとしても実装できる。
abstract class CustomTask @Inject constructor(
private val message: String,
private val number: Int
) : DefaultTask()
tasks.register<CustomTask>("myTask", "hello", 42)
Gradleプラグインを自作したときに似たような記法をしたのを思い出した。
これだけだとタスクを実行しても何も起きないので、以下のようにカスタムタスクの挙動を追加した。
abstract class CustomTask @Inject constructor(
private val message: String,
private val number: Int
): DefaultTask() {
@TaskAction
fun doSomething() {
println("$message: $number")
}
}
ここでmyTaskを実行すると、予想通り以下のようになった。
$ gradle -q myTask hello: 42