Task to run other tasks dynamically

plugins
(Bastien Arata) #1

Hello all,

I’m writing a custom plugin that should register a task to works on multiple items. The list of items to works on is retrieved by an http call. The task to run on a single item is already part of the plugin (I written it first).

So to be clear

class AllItemsTask extends DefaultTask {

  @Input
  final ListProperty<String> filters = project.objects.listProperty(String)

  AllItemsTask() {
    labelsFilter.convention(['default filter'])
  }

  @TaskAction
  void action() {
    def items = httpCall(filters.get())
    def tasks = items.collect({
      SingleItemTask singleItemTask = project.tasks.register(it.name,SingleItemTask).get()
      singleItemTask.itemId.set(it.id)
      return singleItemTask
    })
    // The following statement will not work as I can't use dependsOn when task as started execution
    this.dependsOn tasks.collect { it.name }
  }
}

class SingleItemTask extends DefaultTask {

  @Input
  final Property<Integer> itemId = project.objects.property(Integer)

  @TaskAction
  void action() {
    println itemId.get()
  }
}

What’s the best way to achieve this ? I would like to keep SingleItemTask as a separate task since it could be called directly. And I would like to avoid creating the child tasks at config time, since it could slow down the config stage with the http call.

0 Likes

(uklance) #2

The task model should be defined in the configuration phase and you shouldn’t be doing any “work” in the configuration phase so I’d advise against using a http call to determine the tasks. Id suggest moving the logic to a shared service which is called once by the “single” task and multiple times by the “all” task with all http calls being made in the execution phase.

If the http call always returns the same result for the same inputs, you might consider extracting that to its own task which stores the result as a local file which is used in up-to-date scenarios.

0 Likes