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


(Greg Ward) #1

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!


(Peter Niederwieser) #2

‘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.


(Matias Bjarland) #3

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.


(Peter Niederwieser) #4

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.