型安全なアクセサーとは?
build.gradle
をKotlin DSLで記述するとき
- プラグインやビルドスクリプト(buildSrc)内での定義を、型チェック&IDEA補完付きで呼べる
- 依存関係の
implementation
やapi
もその一つ - build時にgradle内部で自動生成される
build.gradle.kts
plugins {
id("myplugin")
}
// myExtensionのとこ
myExtension {
propHoge.set("hoge")
propFuga.set("fuga")
}
dependencies {
// CustomConfigのとこ
customConfig("org.example:foo")
}
tasks {
// mytaskのとこ
mytask {
inputHoge.set("fuga")
}
}
なぜやりたい?
型安全アクセサーなしだと...
build.gradle.kts
plugins {
id("myplugin")
}
// 記述が増える...
configure<MyExtension> {
propHoge.set("hoge")
propFuga.set("fuga")
}
dependencies {
// 文字列なの...?
"customConfig"("org.example:foo")
}
tasks {
// 記述が増える...
tasks {
named<MyTest>("myTask") {
inputHoge.set("fuga")
}
}
}
Kotlin DSLの意味がない
-
customConfig
が文字列になってしまうのは、保管が効かなかったり型安全でない - タスク設定などの型宣言が必要になって記述量が増える
「せっかくのKotlin DSL!もっとシンプルにしたい!」
やり方
手順1.buildSrcなどでプラグインを用意
今回はbuildSrc/src/main/kotlin/myplugin.gradle.kts
にビルドスクリプトを追加し、それを読み込みます。
myplugin.gradle.kts
// myExtension {...}の部分
abstract class MyExtension {
abstract val propHoge: Property<String>
abstract val propFuga: Property<String>
}
val myExtension: MyExtension = extensions.create("myExtension", MyExtension::class.java)
// customConfig("org.example:foo")の部分
val customConfig: Configuration = configurations.create("customConfig")
// tasks { myTask {...} } のとこ
abstract class MyTask : DefaultTask() {
@get:Input
abstract val input: Property<String>
@TaskAction
fun run() {
println("Hello World!")
}
}
tasks.register("myTask", MyTask::class)
手順2.【重要】プロジェクトでプラグインをロード
プロジェクトのビルドスクリプトbuild.gradle.kts
にプラグインを追加します。
「plugins {...}
内じゃないと型安全アクセサーは動きません!!」
- OK:
plugins {...}
- NG:
apply
※プラグイン自体は動きます
build.gradle.kts
// OK
plugins {
// ファイル名がmyplugin.gradle.ktsなら
// gradle.ktsを抜いた、mypluginの部分
id("myplugin")
}
// NG
apply(plugin = "myplugin")
最後に
「手順2」はよく見ないと引っかかります。
みなさんも気を付けてください。
また、外部プラグインを追加する際もapply
ではなくplugins {...}
でないとうまく型安全アクセサーは動きません。ただKotlin Gradle
プラグインはapply
でもいいらしい...。なぜでしょうか?
参考
Gradle Kotlin DSL
Gradleプラグイン
StackOverFlow
宣伝
X(旧Twitter)
技術に関する投稿をしています。