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

时间:2014-12-20 21:23:40

标签: groovy gradle

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

task hello  { 
   println "configuring task hello" 
   doLast {
     println "hello there" 
   }
}

阅读" Gradle In Action"我知道task hello {}实际上是对groovy task()接口的Project方法的调用。在页77上,它显示在Project接口

上有4个称为task的方法
task(args: Map<String,?>, name:String)
task(args: Map<String,?>, name:String, c:Closure)
task(name: String)
task(name: String, c:Closure)

我理解{}是封闭体。

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

我的问题:

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

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

  • 有没有办法让task('hello', { })命令打印出编译器插件运行后生成的基本groovy代码?

2 个答案:

答案 0 :(得分:81)

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

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

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

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

答案 1 :(得分:0)

如果您想了解更多信息,请查看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?, <identifier>, args?task(args?, <identifier>, args?)转换为task(args?, '<identifier>', args?) 它会在build.gradle中找到任务定义,并在标识符(任务名称)周围加上引号,从而使Groovy可以毫无问题地对其进行编译。