Best way to work on multi-line output from external process called from groovy script?

I use this method:

def runProcess(List cmd) {
  def process = cmd.execute()
  def output = new StringWriter(), error = new StringWriter()
  process.waitForProcessOutput(output, error)
  def exitCode = process.exitValue()
  if (exitCode) {
    throw new Exception("Error: $error with code: $exitCode")
  return output.toString().split()

To run external processes that can return one or multiple lines of output.

Sometimes I need to inspect each line and return a match if found. First I tried with an eachLine closure but found that I cannot return from that (Can you break from a Groovy "each" closure?):

def sample() {
  String tagName = ""
  def tags = runProcess(["git", "tag"])
  tags.eachLine { tag -> 
    println "tag $tag"
    if(tag = "mytag") {
      tagName = tag
      // Cannot return from a eachLine closure :-(
      return tag
  return tagName

The above will work but if I have 1000 lines it will go through all of them - since the return statement is ignored.

I am now trying with a classic for loop:

def sample() {

  def tags = runProcess(["git", "tag"])
  println "tags.getClass() "  + tags.getClass() // this is java.lang.String
  String[] tagsArr = tags.split("\n");
  println "tags.getClass() "  + tagsArr.getClass() // this is [Ljava.lang.String
  if (tagsArr != null && tagsArr.length > 0) { // does NOT = true when tagsArr is empty :-(
     for (String tag : tagsArr) {
        def desc = shellCommand(["git", "describe","--tags","$tag"])
        if(desc.trim() == "mytag") {
          println "Found tag: $tag at HEAD"
          return tag

This is pretty verbose/ugly and does not work when tagsArr is empty (still investigating this and any input is appreciated!).

Any suggestions on how to implement better handling of multi-lines output from calling an external process?

Also this from above:

return output.toString().split()

does not seem right...

I have also looked at:

which looks quite verbose/extensive. I hoped that groovy offered some minimal way of doing this to avoid this kind of "low level" boilerplate code.

Sidenote. Interestingly enough this page:

does not mention waitForProcessOutput which I thought was the most robust way to get output from an external process.

Read more here:

Content Attribution

This content was originally published by u123 at Recent Questions - Stack Overflow, and is syndicated here via their RSS feed. You can read the original post over there.

%d bloggers like this: