I combined these and came up with this. The expected RC is there because I have a program I need to run in one project that returns 1 when it works. This does depend on the text of the Exception, but it will still do something reasonable it that doesn't match.
private val ProcessErrorP: Regex = "(.*): error=(\\d+),(.*)".r.unanchored
case class ProcessInfo(stdout: String, stderr: String, exitCode: Int, private val expectedRd: Int) {
def succeeded: Boolean = exitCode == expectedRd
def failed: Boolean = !succeeded
def asOpt: Option[String] = if (succeeded) None else Some(stderr)
}
/**
* Run a simple command
* @param command -- what to run
* @return -- what happened
*/
def run(command: String, expectedRc: Int = 0): ProcessInfo = {
try {
val stdout = new StringBuilder
val stderr = new StringBuilder
val status = command ! ProcessLogger(stdout append _, stderr append _)
ProcessInfo(stdout.toString(), stderr.toString(), status, expectedRc)
} catch {
case io: IOException =>
val dm = io.getMessage
dm match {
case ProcessErrorP(message, code, reason) =>
ProcessInfo("", s"$message, $reason", code.toInt, expectedRc)
case m: String =>
ProcessInfo("", m, 999, expectedRc)
}
}
}