How do I learn Gradle?

(Jason Pickens) #1


As I mentioned in my other post I am very new to Gradle and I have found it pretty tough going.

Part of it is the Groovy syntax which is probably just a familiarity issue. It’s hard when learning a new language and a build system at the same time. The main problem I have is that there so many different ways of doing the same thing. That just makes the learning curve so much harder. Part of this is syntax but I don’t think it all is. A really strict linter might help in this regard if one exists?

The Gradle DSL is also quite hard to work out. Everything looks deceptively similar but that similarity doesn’t help because things aren’t the same. Like at the top level there are the methods on the project plus a few other things like the build script and plugins. Then there are tasks which kind of look like the other top level things but aren’t. Then the splattering of objects (?) and closures. This is likely completely wrong.

Which brings me to my main point, how do you know what to pass to a closure? The docs don’t say much other than it must be a closure and neither does the source code. The only way I have managed this far is by copying examples and pure luck. I much prefer having a good reference to go to, that way I can figure out on my own without an example and go beyond what the example would show me.

This isn’t really a criticism of Gradle just my frustrations as a beginner. I come from the Scala/sbt ecosystem so we have similar issues over there. Any pointers to help me to help myself would be much appreciated.


(Hien Le) #2

Understanding these Groovy features helped me greatly in deciphering the Gradle DSL:

  1. Closures specifically scoping
  2. Omitting parentheses
  3. Getter and Setters

Together they allow Domain Specific Languages that bypass the noisy syntax you’d inherit if building a DSL on Java, but at times does make it seem symbols are being pulled out of thin air. Understanding that conceptually the build file’s default scope is Project aids greatly in looking up “the syntax”.

Given a Gradle snippet and using Project as the starting point you can usually locate the specification. This Groovy copy example:

task copyReport(type: Copy) {
    from file("$buildDir/reports/my-report.pdf")
    into file("$buildDir/toArchive")

would lead you to this reading order (Javadoc direct links might be flaky):

  1. Project.file(Object path)
  2. Project.task​(Map<java.lang.String,?> args, String name, Closure configureClosure
  3. Copy task and the into and from methods

When encountering a symbol like task in a script, start with the Project JavaDoc and look for these names:

  1. task in case it’s just calling a method with omitted parentheses
  2. task with a closure if there’s braces immediately following it
  3. getTask or setTask if there’s an = immediately following it and it’s assigning a property
  4. getTask and see if it’s a method returning a Handler type

Following that process for the dependencies block in a build script should take you down this research path:

  1. Project.getDependencies
  2. DependencyHandler

Hope that’s a good starting point to help you get over the “everything is magic” hurdle.

If you get confused about a symbol’s availability or spec, using reflection to dump the class name and properties should help you get back to the right docs.

(Oleksandr Gavenko) #3

Learning Gradle besides hello-world examples is extremely hard.

I’d recommend get familiar with Groovy first:

Then you need to run existing examples:

and add a lot of println(). Try on every object getClass() or println it.metaClass.methods*.name.sort().unique() to explore objects.

Download Gradle binary distro with sources and make sure your IDE can jump into Gradle sources!!! Javadoc and implementation uncover a lot that official documentation is missing.

Official documentation has good quality but it is not pleasant for cover to cover reading (( Check and read concepts when you miss something:

Remember that Gradle is a moving project and each major version has breaking changes. Read release notes:

(Oleksandr Gavenko) #4

Do println(it.getClass()) (or similar) and check class source code, study methods + javadoc, look for super class methods, check known overriding/implementing classes.

For example from Project source code:

Task task(String name, Closure configureClosure);
Task task(String name, Action<? super Task> configureAction);

It gives example how to create task with Closure and Action.

Source code for DefaultProject:

public Task task(String task, Closure configureClosure) {
    return taskContainer.create(task).configure(configureClosure);

and javadoc for:

 * <p>Applies the statements of the closure against this task object. The delegate object for the closure is set to
 * this task.</p>
Task configure(Closure configureClosure);

So when you use Clousure it is set to Task!