How to pass data from one task to another?


(Christian Abegg) #1

In the following simplified project, I have one task that prepares some data and another task that consumes this data. To pass the data from one task to another, I use the project extensions.

// build.gradle
task prepare() << {
 project.ext.myProperty = "hello world"
}
task consume() {
 dependsOn prepare
 doLast {
  logger.info project.ext.myProperty
 }
}

Now, I have to implement this logic in a custom plugin implemented in Java.

public class PrepareTask extends DefaultTask {
   @TaskAction
 public void prepare() {
  getProject().getExtensions().add("myProperty", "hello world");
 }
  }
public class ConsumeTask extends DefaultTask {
   private String myProperty;
   @TaskAction
 public void consume() {
  getProject().getLogger().info(myProperty);
 }
   public String getMyProperty() {
  return myProperty;
 }
   public void setMyProperty(String myProperty) {
  this.myProperty = myProperty;
 }
}
public class MyPlugin implements Plugin<Project> {
    @Override
 public void apply(Project project) {
  PrepareTask prepare = project.getTasks().create("prepare", PrepareTask.class);
  ConsumeTask consume = project.getTasks().create("consume", ConsumeTask.class);
      consume.dependsOn(prepare);
      // FIXME
   consume.setMyProperty(...);
 }
}

My problem is: in the MyPlugin class, during configuration time, I can not access the project extension as the PrepareTask has not run yet.

I see the following alternatives to pass data from one task to another: - save the data to a file and read the file in the consuming task, at configuration time you just have to know the filename - keep the data as a property of the PrepareTask and access it from the ConsumeTask during execution time (i.e. [pseudo code] project.getTasks().get(‘prepareTask’).getMyProperty()) - use a doFirst Action which read from project.extentions and sets it to the task

Questions: 1) Are there other possibilities to pass data from one task to another? 2) What is the recommeded way to pass data from one task to another? 3) Is there a possibility to tell the ConsumeTask to look in the project extensions when executed, without implementing this explicitely in the ConsumeTask itself (i.e. [pseudo code] consume.setMyProperty((Project project) => { return project.getExtenstions().get(“myProperty”); } )


(Christian Abegg) #2

Update: I found a way to read the data in the extension after the ‘prepare’ task was executed and without adding a dependency to the container to the ‘consume’ task. I added a doFirst action which copies the data to the ‘consume’ task.

public class MyPlugin implements Plugin<Project> {
    @Override
    public void apply(Project project) {
        PrepareTask prepare = project.getTasks().create("prepare", PrepareTask.class);
        ConsumeTask consume = project.getTasks().create("consume", ConsumeTask.class);
        consume.dependsOn(prepare);
        consume.doFirst(new CopyDataFromExtensionAction());
    }
}
public class CopyDataFromExtensionActionimplements Action<Task> {
   @Override
 public void execute(Task task) {
  FrontendExtension extension = task.getProject().getExtensions().getByType(FrontendExtension.class);
  String value = extension.get("myProperty");
  ((ConsumeTask)task).setMyProperty(value);
 }
}

What do you think?