February 29, 2016

Gradle Goodness: Methods Generated For Setting Task Properties

If we create our own tasks in Gradle we usually extend from the DefaultTask or a subclass of DefaultTask. The tasks that are included with Gradle also extend from this class. Gradle will create a proxy class for the actual class implementation and adds (among other things) also a property setter method. The method has the name of the property and has a single argument of the same type as the property. It is different from the setProperty and getProperty methods already added by Groovy. For example if we have a task with a property with the name message of type String then Gradle will add the method message(String) to the proxy class.

In the following example task we have one property user:

// File: buildSrc/src/main/groovy/com/mrhaki/gradle/Hello.groovy
package com.mrhaki.gradle

import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction

class Hello extends DefaultTask {
    String user

    void sayHello() {
        println "Hello $user, how are you doing?"

With the following test we can check that the method user(String) is actually created and we can use it to set a value for the user property:

// File: src/test/groovy/com/mrhaki/gradle/HelloTaskSpec.groovy
package com.mrhaki.gradle

import org.gradle.api.Project
import org.gradle.testfixtures.ProjectBuilder
import spock.lang.Specification
import spock.lang.Subject

class HelloTaskSpec extends Specification {

    private Hello task

    private Project project = ProjectBuilder.builder().build()

    def "user() method is generated to set user property"() {
        task = project.task('helloSample', type: Hello) {
            // Gradle generates proxy class to allow
            // 'setter(value)' methods for properties.
            // In this case we invoke user(String),
            // which maps to setUser(String).
            user 'sample'

        task.user == 'sample'

    def "Groovy syntax property assignment to set user property"() {
        task = project.task('helloSample', type: Hello) {
            // Groovy syntax for setUser(String).
            user = 'sample user'

        task.user == 'sample user'

The following build file has two tasks of type Hello where we use the user(String) method and a property assignment:

import com.mrhaki.gradle.Hello

task helloMrhaki(type: Hello) {
    user = 'mrhaki'

task helloHubert(type: Hello) {
    user 'Hubert'

The idea of this blog post is from watching a great presentation by Vitaliy Zasadnyy about Gradle plugins during a Mashup Gradle/Android Meetup.

Written with Gradle 2.11.