summaryrefslogtreecommitdiff
path: root/src/library/scala/sys/process/ProcessBuilder.scala
diff options
context:
space:
mode:
authorJosh Suereth <joshua.suereth@gmail.com>2011-08-31 19:16:18 +0000
committerJosh Suereth <joshua.suereth@gmail.com>2011-08-31 19:16:18 +0000
commit0377cad8c6a26be5b6dd59323dd171634400005a (patch)
treec0834284a990bd94c76d06d28785d9b84a9a4e41 /src/library/scala/sys/process/ProcessBuilder.scala
parent0e0e2055f355bf701d9a712abf69dcb52fc1eda1 (diff)
downloadscala-0377cad8c6a26be5b6dd59323dd171634400005a.tar.gz
scala-0377cad8c6a26be5b6dd59323dd171634400005a.tar.bz2
scala-0377cad8c6a26be5b6dd59323dd171634400005a.zip
Document the usage and methods of scala.sys.pro...
Document the usage and methods of scala.sys.process. From the first international scaladoc marathon. Contributed by: Daniel Sobral
Diffstat (limited to 'src/library/scala/sys/process/ProcessBuilder.scala')
-rw-r--r--src/library/scala/sys/process/ProcessBuilder.scala104
1 files changed, 99 insertions, 5 deletions
diff --git a/src/library/scala/sys/process/ProcessBuilder.scala b/src/library/scala/sys/process/ProcessBuilder.scala
index 0e34e7be1b..9acdc59094 100644
--- a/src/library/scala/sys/process/ProcessBuilder.scala
+++ b/src/library/scala/sys/process/ProcessBuilder.scala
@@ -12,7 +12,66 @@ package process
import processInternal._
import ProcessBuilder._
-/** Represents a runnable process. */
+/** Represents a runnable process.
+ *
+ * This is the main component of this package. A `ProcessBuilder` may be composed with
+ * others, either concatenating their outputs or piping them from one to the next, and
+ * possibly with conditional execution depending on the last process exit value.
+ *
+ * Once executed, one can retrieve the output or redirect it to a
+ * [[scala.sys.process.ProcessLogger]], or one can get the exit value, discarding or
+ * redirecting the output.
+ *
+ * One creates a `ProcessBuilder` through factories provided in [[scala.sys.process.Process]]'s
+ * companion object, or implicit conversions based on these factories made available in the
+ * package object [[scala.sys.process]].
+ *
+ * Let's examine in detail one example of usage:
+ *
+ * {{{
+ * import scala.sys.process._
+ * "find src -name *.scala -exec grep null {} ;" #| "xargs test -z" #&& "echo null-free" #|| "echo null detected" !
+ * }}}
+ *
+ * Note that every `String` is implicitly converted into a `ProcessBuilder`
+ * through the implicits imported from [[scala.sys.process]]. These `ProcessBuilder` are then
+ * combined in three different ways.
+ *
+ * 1. `#|` pipes the output of the first command into the input of the second command. It
+ * mirrors a shell pipe (`|`).
+ * 2. `#&&` conditionally executes the second command if the previous one finished with
+ * exit value 0. It mirrors shell's `&&`.
+ * 3. `#||` conditionally executes the third command if the exit value of the previous
+ * command is is different than zero. It mirrors shell's `&&`.
+ *
+ * Not shown here, the equivalent of a shell's `;` would be `###`. The reason for this name is
+ * that `;` is a reserved token in Scala.
+ *
+ * Finally, `!` at the end executes the commands, and returns the exit value. If the output
+ * was desired instead, one could run that with `!!` instead.
+ *
+ * If one wishes to execute the commands in background, one can either call `run`, which
+ * returns a [[scala.sys.process.Process]] from which the exit value can be obtained, or
+ * `lines`, which returns a [scala.collection.immutable.Stream] of output lines. This throws
+ * an exception at the end of the `Stream` is the exit value is non-zero. To avoid exceptions,
+ * one can use `lines_!` instead.
+ *
+ * One can also start the commands in specific ways to further control their I/O. Using `!<` to
+ * start the commands will use the stdin from the current process for them. All methods can
+ * be used passing a [[scala.sys.process.ProcessLogger]] to capture the output, both stderr and
+ * stdout. And, when using `run`, one can pass a [[scala.sys.process.ProcessIO]] to control
+ * stdin, stdout and stderr.
+ *
+ * The stdin of a command can be redirected from a `java.io.InputStream`, a `java.io.File`, a
+ * `java.net.URL` or another `ProcessBuilder` through the method `#<`. Likewise, the stdout
+ * can be sent to a `java.io.OutputStream`, a `java.io.File` or another `ProcessBuilder` with
+ * the method `#>`. The method `#>>` can be used to append the output to a `java.io.File`.
+ * For example:
+ *
+ * {{{
+ * new URL("http://databinder.net/dispatch/About") #> "grep JSON" #>> new File("About_JSON") !
+ * }}}
+ */
trait ProcessBuilder extends Source with Sink {
/** Starts the process represented by this builder, blocks until it exits, and returns the output as a String. Standard error is
* sent to the console. If the exit code is non-zero, an exception is thrown.*/
@@ -83,40 +142,75 @@ trait ProcessBuilder extends Source with Sink {
def hasExitValue: Boolean
}
+/** This object contains traits used to describe input and output sources. */
object ProcessBuilder extends ProcessBuilderImpl {
+ /** Used when creating [[scala.sys.process.ProcessBuilder.Source]] from an URL. */
trait URLBuilder extends Source {
}
+
+ /** Used when creating [[scala.sys.process.ProcessBuilder.Source]] and/or
+ * [[scala.sys.process.ProcessBuilder.Sink]] from a file.
+ */
trait FileBuilder extends Sink with Source {
+ /** Append the contents of a `java.io.File` to this file */
def #<<(f: File): ProcessBuilder
+
+ /** Append the contents from a `java.net.URL` to this file */
def #<<(u: URL): ProcessBuilder
+
+ /** Append the contents of a `java.io.InputStream` to this file */
def #<<(i: => InputStream): ProcessBuilder
+
+ /** Append the contents of a [[scala.sys.process.ProcessBuilder]] to this file */
def #<<(p: ProcessBuilder): ProcessBuilder
}
+
+ /** Represents everything that can be used as an input to a
+ * [[scala.sys.process.ProcessBuilder]].
+ */
trait Source {
protected def toSource: ProcessBuilder
+
/** Writes the output stream of this process to the given file. */
def #> (f: File): ProcessBuilder = toFile(f, false)
+
/** Appends the output stream of this process to the given file. */
def #>> (f: File): ProcessBuilder = toFile(f, true)
+
/** Writes the output stream of this process to the given OutputStream. The
- * argument is call-by-name, so the stream is recreated, written, and closed each
- * time this process is executed. */
+ * argument is call-by-name, so the stream is recreated, written, and closed each
+ * time this process is executed.
+ */
def #>(out: => OutputStream): ProcessBuilder = #> (new OStreamBuilder(out, "<output stream>"))
+
+ /** Writes the output stream of this process to a [[scala.sys.process.ProcessBuilder]]. */
def #>(b: ProcessBuilder): ProcessBuilder = new PipedBuilder(toSource, b, false)
+
+ /** Returnes a [[scala.sys.process.ProcessBuilder]] representing this `Source`. */
def cat = toSource
private def toFile(f: File, append: Boolean) = #> (new FileOutput(f, append))
}
+
+ /** Represents everything that can receive an output from a
+ * [[scala.sys.process.ProcessBuilder]].
+ */
trait Sink {
protected def toSink: ProcessBuilder
+
/** Reads the given file into the input stream of this process. */
def #< (f: File): ProcessBuilder = #< (new FileInput(f))
+
/** Reads the given URL into the input stream of this process. */
def #< (f: URL): ProcessBuilder = #< (new URLInput(f))
+
/** Reads the given InputStream into the input stream of this process. The
- * argument is call-by-name, so the stream is recreated, read, and closed each
- * time this process is executed. */
+ * argument is call-by-name, so the stream is recreated, read, and closed each
+ * time this process is executed.
+ */
def #<(in: => InputStream): ProcessBuilder = #< (new IStreamBuilder(in, "<input stream>"))
+
+ /** Reads the output of a [[scala.sys.process.ProcessBuilder]] into the input stream of this process. */
def #<(b: ProcessBuilder): ProcessBuilder = new PipedBuilder(b, toSink, false)
}
}