如何在插件中使用 Gradle Kotlin DSL?

How do I use the Gradle Kotlin DSL inside a plugin?

我正在编写一个 Gradle 插件。

我正在编写调用 Groovy/Java Gradle API 的代码:

package com.example

import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.tasks.Exec

class HelloPlugin : Plugin<Project> {

    override fun apply(project: Project) {
        project.afterEvaluate {
            project.tasks.register("hello", Exec::class.java) { task ->
                task.commandLine = listOf(
                    "echo",
                    "Hello, world!"
                )
            }
        }
    }
}

我更喜欢这样写代码:

package com.example

import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.tasks.Exec

class HelloPlugin : Plugin<Project> {

    override fun apply(project: Project) {
        project.afterEvaluate {
            project.tasks.register<Exec>("hello") { task ->
                task.commandLine = listOf(
                    "echo",
                    "Hello, world!"
                )
            }
        }
    }
}

build.gradle.kts 中启用 kotlin-dsl 插件后,我在原始文件中得到编译器错误 HelloPlugin.kt:

e: /home/example/Documents/gradle-com.example.hello-plugin/src/main/kotlin/com/example/HelloPlugin.kt: (11, 27): None of the following functions can be called with the arguments supplied:
public abstract fun register(p0: String, p1: Class, vararg p2: Any!): TaskProvider defined in org.gradle.api.tasks.TaskContainer
public abstract fun register(p0: String, p1: Class, p2: Action): TaskProvider defined in org.gradle.api.tasks.TaskContainer
e: /home/example/Documents/gradle-com.example.hello-plugin/src/main/kotlin/com/example/HelloPlugin.kt: (12, 22): Unresolved reference: commandLine
e: /home/example/Documents/gradle-com.example.hello-plugin/src/main/kotlin/com/verafin/aws/lambda/AbstractLambdaPlugin.kt: (76, 53): None of the following functions can be called with the arguments supplied:
public abstract fun register(p0: String, p1: Class, vararg p2: Any!): TaskProvider defined in org.gradle.api.tasks.TaskContainer
public abstract fun register(p0: String, p1: Class, p2: Action): TaskProvider defined in org.gradle.api.tasks.TaskContainer

完整的可运行项目位于: https://github.com/AlainODea/gradle-com.example.hello-plugin

如何在插件中使用 Gradle Kotlin DSL?

在build.gradle.kts中,Gradle Kotlin DSL 加载了插件。在您的插件实现中的 Kotlin classes 中,您需要显式导入 Gradle Kotlin DSL:

import org.gradle.kotlin.dsl.*

这是一个完整的工作示例 Gradle 插件 Kotlin class 使用 Kotlin Gradle DSL:

package com.example

import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.tasks.Exec
import org.gradle.kotlin.dsl.*

class HelloPlugin : Plugin<Project> {

    override fun apply(project: Project) {
        project.afterEvaluate {
            project.tasks.register<Exec>("hello") { task ->
                task.commandLine = listOf(
                    "echo",
                    "Hello, world!"
                )
            }
        }
    }
}

使用 Kotlin Gradle DSL,您可以省略显式命名的闭包参数并使其更加简洁:

package com.example

import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.tasks.Exec
import org.gradle.kotlin.dsl.*

class HelloPlugin : Plugin<Project> {

    override fun apply(project: Project) {
        project.afterEvaluate {
            tasks.register<Exec>("hello") {
                commandLine = listOf(
                    "echo",
                    "Hello, world!"
                )
            }
        }
    }
}