gradle - Gradle 任务语法:如何从 Groovy 的角度进行解释?
问题描述
我很难理解 Gradle 的 Groovy DSL 是如何工作的。
不幸的是,Gradle 是我在日常工作中遇到的 Groovy 的主要用例,而且我注意到对于许多开发人员来说,他们完全通过 Gradle 接触到 Groovy。因此,大多数 Gradle 用户对 Groovy 的掌握非常有限。
在我对 Groovy 的有限理解中,以下tokenA tokenB { tokenC }
所有标记都不是语言关键字的 sintaxtokenA
将是我们使用参数调用的方法,tokenB
最后一个参数是闭包。我想我是正确的,但我知道我错了,因为在 tokenB 之后可能需要一个逗号才能使分析正确。
正如您已经知道的那样,我绝不是 Groovy 开发人员,而且我认为在不学习 Groovy 基础知识的情况下使用 Gradle 是一件坏事,因为它限制了我充分利用其功能。但我唯一可行的选择是通过示例学习而不不幸地学习理论。
我确实检查了一些类似的问题,例如这个问题,但没有对我来说足够清晰或完整的答案。
TL;博士
task myTask { doLast {} }
Groovy 中如何解释标记?- Gradle 是否使用标准的 Groovy 解释器?
myTask
当有task
和没有def
或后面有类型时,如何将其解释为标识符?- 如果稍后在文件中我添加
myTask { dependsOn myOtherTask }
了如何解释?
解决方案
我相信这一切都很时髦,没有什么特别的。这是您需要了解的常规概念。
- 如果方法的最后一个参数是闭包,则可以将闭包放在方法参数的右括号之后。
class MyClass {
void doStuff(String name, Closure c) {
c.call()
}
}
def o = new MyClass()
o.doStuff('x') {
println "hello"
}
- 您可以在您的对象上实现缺少的方法。如果有人试图调用一个不存在的方法,你可以做一些事情
class MyClass {
def methodMissing(String name, args) {
println "You invoked ${name}(${args})"
}
}
def o = new MyClass() {
o.thisMethodDoesNotExist('foo')
}
- 您可以在闭包上设置委托
class MyBean {
void include(String pattern) {...}
void exclude(String pattern) {...}
}
class MyClass {
private MyBean myBean = new MyBean()
void doStuff(Closure c) {
c.setDelegate(myBean)
c.call()
}
}
def o = new MyClass()
o.doStuff {
include 'foo'
exclude 'bar'
}
这 3 个 groovy 特性几乎解释了 gradle 脚本中发生的让 Java 开发人员摸不着头脑的“神奇”行为。
所以,让我们分解你的片段
task myTask(type:Foo) {
doLast {...}
}
让我们添加一些括号并添加隐式项目引用。让我们也将闭包提取到一个变量中
Closure c = {
doLast {...}
}
project.task(project.myTask([type: Foo.class], c))
该project.myTask(...)
方法不存在,行为最终通过methodMissing
功能实现。Gradle 会将闭包上的委托设置为任务实例。因此闭包中的任何方法都将委托给新创建的任务。
最终,这就是逻辑上所说的
Action<? extends Task> action = { task ->
task.doLast {...}
}
project.tasks.create('myTask', Foo.class, action)