任务中的自定义 Gradle 插件 doLast()

问题描述 投票:0回答:1

我正在编写一个自定义 Gradle 插件,并试图弄清楚如何在我的 Gradle 插件中调用

doLast()
函数,然后在其中提供一些逻辑,但不幸的是没有取得太大成功。

这是语法错误,位于

it.delete(
Unresolved reference: delete
:

project.tasks.create("cleanMendix", Delete::class.java) {task ->
    task.doLast{
        it.delete(
            "${project.projectDir}/target",
            "${project.projectDir}/.mendix-cache",
            "${project.projectDir}/userlib",
            "${project.projectDir}/deployment"
        )
    }
}.apply {
    group = "mendix"
}

这不是删除文件:

        project.tasks.create("cleanMendix", Delete::class.java) {task ->
        task.doLast{
            task.delete(
                "${project.projectDir}/target",
                "${project.projectDir}/.mendix-cache",
                "${project.projectDir}/userlib",
                "${project.projectDir}/deployment"
            )
        }
    }.apply {
        group = "mendix"
    }

如果我在没有

doLast()
的情况下调用它,它可以工作,但它也在配置阶段运行。

gradle gradle-plugin gradle-kotlin-dsl
1个回答
0
投票

对于第一个问题,您无法在

delete
的 lambda 参数上调用
doLast
,因为
doLast
不知道其所执行的
Task
对象的类型1:其
Action
的参数是一个普通的
Task

对于第二个问题,您从外部 lambda 作用域中获取

task
,它必须在某种程度上与
Task
本身提供的
doLast
参数不同,这是您要使用的参数。

要解决这些问题,您可以转换 lambda 参数:

project.tasks.create("cleanMendix", Delete::class.java) {task ->
    task.doLast{
        (it as Delete).delete(
            "${project.projectDir}/target",
            "${project.projectDir}/.mendix-cache",
            "${project.projectDir}/userlib",
            "${project.projectDir}/deployment"
        )
    }
    task.group = "mendix"
}

我还将您的

apply
调用放在原来的大括号内。

额外评论

您似乎在应用了 Kotlin JVM 插件的代码中编写此插件,而不是推荐的 Kotlin DSL 插件。这样做并不能解决您的问题,但它确实使用 Kotlin 的

SAM-with-receiver 插件
将 Gradle
Action
中的 lambda 参数转换为上下文接收器 (this),它模仿了此类
Action
的方式在 Kotlin DSL 构建脚本中配置。

换句话说,在上下文接收器上遇到这个问题比在 lambda 参数上更常见;并且您可能还更喜欢 Kotlin DSL 插件提供的 API(例如,您将在上面调用

group = "mendix"
)。


1要实现这一点,可能需要

Task
类具有递归泛型参数,因此您可以明白为什么 Gradle 团队不急于这样做。

© www.soinside.com 2019 - 2024. All rights reserved.