Exercise: Create "jar" task for every sourceSet?

Just as an experiment, I wanted to see if I could dynamically generate a “Jar” task for every sourceSet, and initially within the task I also wanted to print out the name of the task itself.

I started with the following:

sourceSets.each {
    ss -> task "${ss.name}Jar" (type: Jar) << {
        println "task: " task.name
 from sourceSets[task.name].output
    }
}

Everything but the body of the task seems to be ok (if I remove the body, “gradle tasks” shows the tasks I expect).

The problem seems to come down to figuring out how to access the name of the task I’m currently executing.

There is a ‘+’ missing before ‘task.name’. Instead of ‘sourceSets.each’, use ‘sourceSets.all’. Also the ‘<<’ needs to be removed, and, depending on what behavior you want, the ‘println’ wrapped in a ‘doLast { … }’.

What’s the difference between “each” and “all” (along with a reference, please)?

(this editor could be more intelligent. I’m having trouble figuring out how to add the text including the two less than signs.)

Concerning the two less-than signs, that is shorthand for “doLast”, which would make the entire closure the “doLast()” method. In this situation, I guess it doesn’t make sense to set the “from” property in the “doLast()” method. Is that why the “<<” needs to be removed?

‘each’ is a Groovy method. ‘all’ is a Gradle method that will also trigger for elements added to the collection in the future. You can find the latter in the Javadoc.

Is that why the "< needs to be removed?

Yes. Tasks should be configured in the configuration phase. The code above configures the ‘Jar’ task in the execution phase, and after its main action (which is responsible for creating the Jar) has run. Never using the ‘<<’ shortcut makes it easier to get this right.

Ok, then would you say that the following is a more reasonable version of this (adding the manipulation of the sourceSets name, as the previous version wouldn’t have worked)?

sourceSets.all {
  ss -> task "${ss.name}Jar" (type: Jar) {
    doLast {
      println "task: " + it.getName();
    }
    from sourceSets[it.name - "Jar"].output
  }
}