Reputation: 4386
I am having a very hard time understanding the semantics of gradle scripts w.r.t how they are seen in groovy.
1) What does the following snippet mean?
task copy(type: Copy) {
into "target"
with baseSpec
}
As I understand it, it seems to me that task is instantiated with a named parameter "type" and it's value "Copy". I have no idea what is "into", "with". Are they parameters of the task class? BTW, Is task a class or interface?
2) What is a "script block"? Is it a closure? 3) What is an "Action"? Are they also closures or objects of interface instantiated with anonymous class?
Basically, I am lost how to put all of this together as a plain groovy ?
Upvotes: 1
Views: 270
Reputation: 11032
Groovy is a powerful language for building DSL (Domain Specific Language). Gradle use this as many others libraries.
It's based on several properties of Groovy
Parenthesis are optionals
fun("myparameter")
fun "myparameter"
You can have named parameters on a method
fun prop:'value', otherprop:'othervalue'
fun([prop:'value', otherprop:'othervalue'])
If the last parameters of a method is a closure, it can be written outside the method call
fun(prop:'value') {
//..closure call
}
fun([prop:'value'], { /*closure*/ })
You can get/set any property or invoke any method on a groovy object : you can add behavior dynamically, through missingMethod
, missingProperty
, getProperty
or setProperty
, ..
object.somefun "42"
object.missingMethod("somefun", ["42"])
In a closure, you have a special object, called delegate. it can be setted at runtime, and any non-local property or method invocation can be delegated to this delegate
def fun = { copy "this_file" }
def fun = { delegate.copy("this_file") }
See this documentation or the Builder pattern
with this properties, your script can be written (it's not really true because of AST transformation..) :
task(copy([type: Copy], { it ->
delegate.into("target")
delegate.with(baseSpec)
}))
delegate
is an object which implement missingMethod
, and generate objects based on the method call and the context.
a more complexe script :
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath group: 'commons-codec', name: 'commons-codec', version: '1.2'
}
}
is equivalent to :
buildscript({ it ->
delegate.repositories({delegate.mavenCentral()})
delegate.dependencies({delegate.classpath([group:'commons-codec', name:'commons-codec', version:'1.2'])})
})
Upvotes: 4