Command line task


(Barrett Kern) #1

I have a gradle task I wrote that runs something on the command line. The process takes ~15 seconds and writes its status to the console. I want to take action based on the status that is written to the console. I see the standardOutputStream property for an Exec task but anytime I println that it seems to print to the console first and then my process finally writes to the console. How do I handle this situation in gradle?


(sethgoings) #2

I’m not sure what exactly you’re exec’ing (which might have special output behavior that I’m not aware of)…

Could the process be sending things to std error that you’re not intercepting?


(Barrett Kern) #3

I am running my jasmine js unit tests via phantom js(headless webkit tool).

Here is my task definition on my local machine

task runJasmine(type: Exec) {
    workingDir '/src/main/webapp/resources/js/tests/'
      //windows
     commandLine 'cmd', '/c', 'phantomjs jasmine_phantom.js SpecRunner.html results.html'
        println 'execResult ' + execResult
    println 'stdOut ' + standardOutput
    println 'stdIn ' + standardInput
}

Here is the output I am seeing where the printlns in the task seem to print to the console before the script that is running phantom does.

execResult null stdOut org.apache.commons.io.output.CloseShieldOutputStream@1ef479c2 stdIn java.io.ByteArrayInputStream@4465bf6e :my-project:runJasmine

------------------------------------------------------- J A S M I N E

T E S T S -------------------------------------------------------

Test URL: SpecRunner.html Tests completed in 2408 ms Test results file: results.html Tests passed.

BUILD SUCCESSFUL

Total time: 19.377 secs


(Luke Daley) #4

By default, forked processes write through to the parent processes stdout. This isn’t what you want. You want to collect the output and then parse it.

task runJasmine(type: Exec) {
    workingDir '/src/main/webapp/resources/js/tests/'
    //windows
     commandLine 'cmd', '/c', 'phantomjs jasmine_phantom.js SpecRunner.html results.html'
   standardOutput = new ByteArrayOutputStream()
     doLast {
     String output = standardOutput.toString()
   }
}

(Szczepan Faber) #5

The execResult is null because the task hasn’t ran yet.

Printing the standardOutput/input they way you do it is not quite right because:

  • you’re printing it at configuration phase

  • printing it only prints the string representation of the default stream (by default, Gradle uses System.out). If you want to get hold of the output, assign brand new ByteArrayOutputStream. Take a look at the example:

task foo(type: Exec) {
  commandLine = //
      //store the output instead of printing to the console
  standardOutput = new ByteArrayOutputStream()
      //extension method foo.output() can be used to obtain the output String
  ext.output = {
    return standardOutput.toString()
  }
  }
  task showFooOutput(dependsOn: foo) {
  doLast {
    println "Foo's output: ${foo.output()}"
  }
}

Hope that helps!


(Barrett Kern) #6

@Luke - This version of the task worked @Szczepan - I don’t understand this example 100%. Where is ext referring to? What is it? When I lookup exec task I don’t see ext as property listed (perhaps its inherited?).


(sethgoings) #7

ext refers to: http://gradle.org/docs/current/dsl/org.gradle.api.plugins.ExtraPropertiesExtension.html


(Barrett Kern) #8

Thanks that was really helpful. I never knew it existed


(Barrett Kern) #9

Do you guys have any suggestions on how to fail the build if that text indicates failure?


(Luke Daley) #10

You can just throw an exception.