soupybionics
soupybionics

Reputation: 4386

Understand Gradle-Groovy semantics

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

Answers (1)

Jérémie B
Jérémie B

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

Related Questions