理解 gradle 任务定义中的 groovy 语法

Posted

技术标签:

【中文标题】理解 gradle 任务定义中的 groovy 语法【英文标题】:Understanding the groovy syntax in a gradle task definition 【发布时间】:2015-02-19 11:26:09 【问题描述】:

我是 Gradle 和 Groovy 的新手,并试图了解定义 gradle 任务时在 groovy 级别发生的情况。

task hello   
   println "configuring task hello" 
   doLast 
     println "hello there" 
   

通过阅读“Gradle In Action”一书,我知道task hello 确实是对groovy Project 接口的task() 方法的调用。在第 77 页上,它显示Project 接口上有 4 个称为任务的方法

task(args: Map<String,?>, name:String)
task(args: Map<String,?>, name:String, c:Closure)
task(name: String)
task(name: String, c:Closure)

我知道 是闭包体。

我不明白的是 groovy 如何根据 https://***.com/a/25592665/438319 解释 task hello 中的 hello 有一个 groovy 编译器插件可以将 task hello 转换为 task('hello', )

我的问题:

在哪里可以找到有关进行转换的 Gradle Groovy 编译器插件的信息?

Gradle 脚本是 groovy 程序的说法在技术上是不正确的,因为 gradle 以某种方式扩展了 Groovy 编程语言?

有没有办法让gradle 命令打印出编译器插件运行后生成的基本 groovy 代码?

【问题讨论】:

【参考方案1】:

Gradle 使用AST Transformations 来扩展 Groovy 语法。您提到的任务定义语法只是 Gradle 应用的转换之一。您可以找到该转换 here 的实现。要回答您的具体问题:

我所知道的任何地方都没有专门记录 Gradle 应用的各个转换。但是,您可以查看上面链接的同一包中的其他类。

Gradle 脚本支持 Groovy 语法的超集。任何有效的 Groovy 在 Gradle 脚本中也有效,但是,Gradle 脚本不一定(通常不是)有效的“默认”Groovy。

没有办法获得等效 Groovy 代码的输出,因为它是在内存中操作的实际抽象语法树。

【讨论】:

【参考方案2】:

如果您想了解更多信息,请查看 TaskDefinitionScriptTransformer 类中的 gradle 源代码中的 transformVariableExpression function

private void transformVariableExpression(MethodCallExpression call, int index) 
        ArgumentListExpression args = (ArgumentListExpression) call.getArguments();
        VariableExpression arg = (VariableExpression) args.getExpression(index);
        if (!isDynamicVar(arg)) 
            return;
        

        // Matches: task args?, <identifier>, args? or task(args?, <identifier>, args?)
        // Map to: task(args?, '<identifier>', args?)
        String taskName = arg.getText();
        call.setMethod(new ConstantExpression("task"));
        args.getExpressions().set(index, new ConstantExpression(taskName));
    

它将task args?, &lt;identifier&gt;, args?task(args?, &lt;identifier&gt;, args?) 转换为task(args?, '&lt;identifier&gt;', args?) 它在 build.gradle 中找到任务定义并在标识符(任务名称)周围添加引号,以便 groovy 可以毫无问题地编译它。

【讨论】:

以上是关于理解 gradle 任务定义中的 groovy 语法的主要内容,如果未能解决你的问题,请参考以下文章

Android Gradle 插件将自定义 Gradle 插件上传到自建 Maven 仓库 ② ( java 和 groovy 插件自带文档任务 | 自定义文档打包任务 | 生成文档包 )

理解与配置android studio中的gradle

如何将 gradle 中的 groovy 任务转换为 Gradle Kotlin DSL 以生成 pom.xml?

gradle / groovy:从自定义类调用“全局”函数

Gradle / Groovy 语法和关键字

看懂Gradle脚本- Groovy语法之运算符重载