1

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 ?

tkruse
  • 10,222
  • 7
  • 53
  • 80
soupybionics
  • 4,200
  • 6
  • 31
  • 43
  • Possible duplicate of [Understanding the groovy syntax in a gradle task definition](https://stackoverflow.com/questions/27584463/understanding-the-groovy-syntax-in-a-gradle-task-definition) – tkruse Jan 29 '18 at 05:47

1 Answers1

4

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'])})
})
Jérémie B
  • 10,611
  • 1
  • 26
  • 43