Evaluate "Exec" task arguments at execution time

I have 2 Exec tasks. Output from one task should be an input for another:

task bar(type: Exec) {
    commandLine('./someShellScript')
    standardOutput = new ByteArrayOutputStream()
    ext.output = {
        return standardOutput.toString()
    }
}

task foo(type: Exec) {
    dependsOn bar
    commandLine('./someOtherSript,'
                bar.ext.output()) //this is an output from first task
    standardOutput = new ByteArrayOutputStream()
    ext.output = {
        return standardOutput.toString()
    }
}

But after I wrote this, I realized that evaluation of foo's commandLine happens at the configuration stage (bar.ext.output() is called before bar is executed).

How do I make this kind of connection between these 2 Exec tasks when one acts as input for another?

You could use a lazy evaluated GString for this.

commandLine './someOtherScript', "${->bar.output()}"

Ha! Didn’t know about this one! You saved my day! Thanks!

Hi,

that works really well for a string, but how would you do for a list? I tried something like


task mytask(type: Exec) {
  def cmd = []

  doFirst {
    cmd.add("ls")
  }

  commandLine { -> cmd }
}

with no success, the closure is called at evaluation time (the example above makes no sense per se, imagine that the list we add to cmd comes from another task’s output)

Realistically, the only other option is to use a “configuration task”, that is, a task whose action configures another task.

task foo(type: Exec) {
  dependsOn 'configureFoo'
}

task configureFoo {
  doLast {
    foo.commandLine = // grab from other task's output
  }
}