Gradle All Tasks are Executed and the Poor Design

There is a quirk in the design of Gradle task, look at the code below without much knowledge about the very details of Gradle

 
task hello {
    println "hello"
}
 
task foo {
    println "foo"
}
 

What would you think about the code? For me, it intuitively means to define two tasks that I can execute any one of them later. Turns out it's not ture and surprised me.

In Gradle, there are two phases: configuration and execution. If you define tasks like above, you are define configuration code for the tasks which are executed at configuration phase, it's like a prologue of each build invocation.

The code itself didn't say anything about it will be executed in configuration phase, instead, from the perspective of a new comer, it makes the perfect sense to consider the code is defining task actions.

It's just a convention that counter-intuitive, but not all people will know all the conventions before starting use the tool, most people learn the convention when the surprise happens.

To define code executed in execution phase, do the following

 
task hello {
    doLast{
        println "hello"
    }
}
 
task foo {
    doLast {
        println "foo"
    }
}
 

Or the syntax sugar

 
task hello << {
    println "hello"
}
 
task foo << {
    println "foo"
}
 

The better desing will be