我正在编写一个自定义 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()
的情况下调用它,它可以工作,但它也在配置阶段运行。
对于第一个问题,您无法在
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 团队不急于这样做。