35

我正在尝试学习 Gradle。我喜欢的学习方式是在低层次上了解正在发生的事情。为此,我试图解释文档的示例 6.1中关于DSL 参考的情况:

task hello {
    doLast {
        println 'Hello world!'
    }
}

我知道这个脚本是在Project. 所以我可以从Project 文档中看到有很多重载的task(...)方法。查看签名,我需要选择一个具有闭包作为最终参数的签名。由于我们没有在Map这里传递 a ,我假设被调用的方法是task(String name, Closure closure).

但是,我正在努力解决的部分是,在此脚本中,文字字符串如何hello映射到String.

另一个示例是示例 6.7

task taskX(dependsOn: 'taskY') << {
    println 'taskX'
}

task taskY << {
    println 'taskY'
}

在这里,我假设我们正在调用task(Map<String, ?> args, String name)方法的形式。但,

  1. 同样,文字字符串如何taskXString?
  2. 鉴于括号不用于构造Map文字,括号中的部分如何最终成为 a Map
  3. 如果我正确地找出了正在调用的方法,那么与 DSL 文档相比,脚本中给出的参数顺序是否错误?
  4. 使用括号的语法像方法调用一样查找整个世界。这可能表明委托给Project对象以解析taskX为未知方法。task但是,AFAIK,鉴于方法调用紧接在它之前,方法调用此时在语法上无效。

正如您所看到的,对于示例语法如何映射到 DSL 参考指南,我有点困惑,这让我很难真正理解基层发生的事情。

谢谢!

4

2 回答 2

23

任务声明语法的task foo变化是特殊的,因为它是使用 Groovy 编译器插件实现的。据我所知,这是唯一使用编译器插件来支持特殊语法的情况。

于 2012-09-07T22:56:19.727 回答
2

这是一个很好的文档: https ://ouyi.github.io/post/2017/12/09/groovy-gradle.html

最后写在这里:

“自定义任务的语法很棘手。例如:

task myTask(type:Tar, dependsOn anotherTask) {
    // clousre
}

我可以弄清楚这可能是在调用Task task(Map<String,?> args, String name, Closure configureClosure)项目对象上定义的方法,但我不知道如何将myTask()构造与 name 参数匹配。而且我并不孤单,类似的讨论在这里和这里。

事实证明,Gradle 使用了 Groovy 的一些高级元编程特性(编译时元编程)来将myTask()构造转换为名称参数。老实说,这是 Gradle 中我不喜欢的部分,因为实现那些语法糖似乎太棘手了(而且过多的糖可能不健康)。毕竟,Gradle 只是一个构建工具,应该易于理解、使用和扩展。”

于 2021-06-24T09:00:31.213 回答