提问者:小点点

gradle脚本是用groovy写的吗?


我很难理解gradle中的groovy语法。

如果命名参数(在groovy中)使用后缀,那么我假设代码应用插件:'java'意味着调用函数应用(plugin='java')。这很奇怪,因为函数应用甚至没有定义。下面在我的gradle脚本中给我一个错误:

println apply.getClass()
> Could not get unknown property 'apply' for root project 'Simple' of type 
org.gradle.api.Project.

那么什么是应用,它是在哪里定义的呢?为什么上面的代码不只是打印应用元素的类呢?

另外一件让我感到奇怪的事情是:

dependencies {
    compile 'org.slf4j:slf4j-api:1.7.12'
    testCompile 'junit:junit:4.12'
}

语法暗示{}包装的代码是一个闭包,但是compiletestCompile元素是什么?如果是闭包,那么上面的代码只会返回'junit: junit:4.12'作为字符串,其余的应该无法编译。看起来它更像是一个映射的定义。但是同样,如果上面的代码是数据,那么我应该能够在groovyshshell处输入它。

groovy:000> dependencies {
        compile 'org.slf4j:slf4j-api:1.7.12'
        testCompile 'junit:junit:4.12'
    }
groovy:001> groovy:002> groovy:003> ERROR groovy.lang.MissingMethodException:
No signature of method: groovysh_evaluate.dependencies() is applicable for argument types: (groovysh_evaluate$_run_closure1) values: [groovysh_evaluate$_run_closure1@b7c4869]

这让我感到困惑。我以为gradle脚本只是groovy脚本,但似乎gradleDSL为groovy语言添加了元素。groovy Clojure变成了映射,带有命名参数的函数调用变得不同。

有人能启发我这个时髦的DSL;)


共2个答案

匿名用户

plugin: 'java' 

是一个groovy映射。请参阅project. application()留档和groovy留档中对此语法的解释。

关于依赖项,请参阅DependencyHandler。

Groovy是一种非常动态的语言,您可以在其中调用非声明的方法,并让处理程序根据被调用的方法名执行某些操作。AFAIK,这就是这里使用的技巧。请参阅源代码。

我不是一个时髦的开发人员,虽然我发现DSL优雅,但我有时也会感到困惑,因为我发现很难将DSL的某些部分与留档中的具体方法联系起来。但是你最终会理解并习惯它。

匿名用户

compile'org. slf4j:slf4j-api:1.7.12'不是映射,而是方法调用。在Groovy中,您可以省略括号,因此调用等效于

compile( 'org.slf4j:slf4j-api:1.7.12' ) 

Gradle中的此类方法也可以采用第二个参数:

compile( 'org.slf4j:slf4j-api:1.7.12' ){ exclude module:'log4j' }

在这种情况下,module:'log4j'是一个省略方括号的映射,调用可以重写为

compile( 'org.slf4j:slf4j-api:1.7.12' ){ exclude( [module:'log4j'] ) }