Confused by Gradle syntax: what's a method call, what's a variable, etc?

I’m deeply confused by Gradle’s highly abbreviated syntax. I’m used to programming languages like Python, Java, JavaScript, etc. where it is immediately obvious that

foo()

is a function call,

thing.foo()

is a method call,

foo = 42

is a variable assignment, etc.

But the relative lack of syntax in Gradle is strange and unfamiliar. For example, in

sourceSets {
    common { ... }
    app1 { ... }
    app2 { ... }
}

… what is ‘sourceSets’? Am I calling a function? Using a language keyword? Assigning a variable? Setting an instance variable of some object?

Similarly, what are ‘common’, ‘app1’, and ‘app2’? Feel free to point me at the documentation that explains this, because I have clearly not found it myself. From the DSL reference, I think that I am creating three instances of org.gradle.api.tasks.SourceSet, but what are those user-specified names like ‘common’ – local variables? global variables? Instance variables of some hidden object that I cannot see?

It gets more confusing in the definition of one of those source sets:

common {
    output.classesDir = file('classes/common')
    java {
         srcDirs = ['dir1', 'dir2', 'dir3']
        exclude 'dir1/**/Test*'
        exclude 'dir2/**/Mock*'
        compileClasspath = files(['lib1.jar', 'lib2.jar'])
    }
}

About the only thing I’m sure of here are the strings and lists of strings. :wink:

What is ‘java’ and what does it mean to follow it with what looks like a block of code? And why are some of those lines of code apparently variable assignments (“srcDirs = …”), whereas some are … something else? What is ‘exclude’ here, anyways?

Again: please point me to the right documentation. Despite spending a week or two with Gradle on-and-off over the last couple of months, I still feel like I’m wallowing around in a very odd programming language that just doesn’t fit my preconceived notions of variables, methods, instance variables, etc. What am I missing?

Thanks!

‘foo = bar’ is a property assignment. Everything else is a method call. In particular, ‘foo { … }’ is syntactic sugar for ‘foo({ … })’ (parens in method calls are optional), and ‘foo(bar) { … }’ is syntactic sugar for ‘foo(bar, { … })’. This is just how Groovy works, and it’s documented in 13.4. Some Groovy basics. Expect this chapter to grow over time.

Since we are on the subject of method call vs property assignment. Assume I have a class A:

class A {
  String width
  String length
}

and that I want to configure it using something like:

def z = configure(new A()) {
  width = 'Hello'
  length = 'World!'
}

this works fine in gradle as it stands. However, I’m finding that I often prefer the less verbose method call syntax for my DSLs:

def z = configure(new A()) {
  width 'Hello'
  length 'World!'
}

so I usually end up creating methods:

class A {
  String width
  String length
    def width(String s) {
    this.width = s
  }
    def length(String s) {
    this.length = s
  }
}

are there any convenience classes used by gradle somewhere to eliminate this boilerplate adding of “methods with the same name as the property”? I realize this might not always be desirable, but I ended up doing it enough times to start to wonder if it’s worth generalizing.

Recent milestones add these methods automatically. However, this only holds for objects created via Instantiator, which isn’t yet part of Gradle’s public API. I expect more innovations around this post 1.0.