When are task rules evaluated and added and can a task rule define more than one task?

I am wondering a little about when the closure runs when you are defining a task rule?

For example:

tasks.addRule(“Pattern: ping”) { String taskName ->

if (taskName.startsWith(“ping”)) {

task(taskName) << {

println "Pinging: " + (taskName - ‘ping’)

}

}

}

When doing this inside a plugin, I came to the conclusion that it became quite handy to define more than just one task, and to work with the task graph to set up dependencies between tasks I wanted to execute in a certain order.

ie.

tasks.addRule(“Pattern: ping”) { String taskName ->

if (taskName.startsWith(“ping”)) {

def someTask = task(‘someTask’) << {

println “hello”

}

def myRule = task(taskName) << {

println "Pinging: " + (taskName - ‘ping’)

}

myRule.dependsOn someTask

}

}

Is that a hack or is it perfectly fine to carry on doing that?

With this pattern it becomes quite easy to see both the configuration phase and execution phase code of a particular task inside a plugin, but then it dawned on me that I don’t actually know when the addRule() code runs, is it initialisation or configuration?

It’s typically configuration, but that’s not really an inherent characteristic.

When you ask for a task, via any way, if no task can be found with that name then task rules get a chance to respond before Gradle gives up and tells you it can’t find the task.

If the only reason the task rule is firing is because of the name of one of tasks that you requested be run via the invocation (e.g. command line) then the rule is going to fire right at the end of the configuration phase.

Hopefully that helps.

Yes, I think I understand now. The exact point when a task rule defined in a class that extends an AbstractRule is after gradle.projectsEvaluated() but of course before the taskgraph is complete.

It would be nice to capture that in the documentation as I was sitting here wondering why a closure I added to projectsEvaluated() wasn’t firing. It wasn’t “because all projects are already evaluated” … took me some time to figure out.