首页 文章

gradle脚本是用groovy编写的吗?

提问于
浏览
5

我无法理解gradle中的groovy语法 .

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

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

那么 apply 究竟是什么?为什么上面的代码不打印 apply 元素的类?

还有一件我觉得奇怪的事情如下:

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

语法表明包含在 {} 中的代码是一个闭包,但 compiletestCompile 元素是什么?如果它是一个闭包,那么上面的代码只会返回 'junit:junit:4.12' 作为字符串,其余的应该无法编译 . 它看起来更像是 Map 的定义 . 但同样,如果上面的代码是数据,那么我应该能够在 groovysh shell中输入它 .

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脚本,但似乎gradle DSL为groovy语言添加了元素 . 一个groovy clojure成为一个map,一个带有命名参数的函数调用变得不同 .

有人可以在这个groovy DSL上启发我;)

2 回答

  • 2
    plugin: 'java'
    

    是一个时髦的 Map . 请参阅groovy documentation以及groovy documentation中此语法的说明 .

    关于依赖关系,请参阅DependencyHandler .

    Groovy是一种非常动态的语言,您可以在其中实际调用非声明的方法,并让处理程序根据被调用的方法名称执行某些操作 . AFAIK,这就是这里使用的技巧 . 见source code .

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

  • 3

    compile 'org.slf4j:slf4j-api:1.7.12' 不是 Map ,它是方法调用 . 在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'] ) }
    

相关问题