summaryrefslogtreecommitdiff
path: root/src/library/scala/sys/process/ProcessLogger.scala
blob: 1ce77c919634258263159892794f8d93c6567767 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/*                     __                                               *\
**     ________ ___   / /  ___     Scala API                            **
**    / __/ __// _ | / /  / _ |    (c) 2003-2011, LAMP/EPFL             **
**  __\ \/ /__/ __ |/ /__/ __ |    http://scala-lang.org/               **
** /____/\___/_/ |_/____/_/ | |                                         **
**                          |/                                          **
\*                                                                      */

package scala.sys
package process

import java.io._

/** Encapsulates the output and error streams of a running process.
 *  Many of the methods of ProcessBuilder accept a ProcessLogger as
 *  an argument.
 *
 *  @see      ProcessBuilder
 */
trait ProcessLogger {
  /** Will be called with each line read from the process output stream.
   */
  def out(s: => String): Unit

  /** Will be called with each line read from the process error stream.
   */
  def err(s: => String): Unit

  /** If a process is begun with one of these ProcessBuilder methods:
   *
   *    def !(log: ProcessLogger): Int
   *    def !<(log: ProcessLogger): Int
   *
   *  The run will be wrapped in a call to buffer.  This gives the logger
   *  an opportunity to set up and tear down buffering.  At present the
   *  library implementations of ProcessLogger simply execute the body unbuffered.
   */
  def buffer[T](f: => T): T
}

class FileProcessLogger(file: File) extends ProcessLogger with Closeable with Flushable {
  private val writer = (
    new PrintWriter(
      new BufferedWriter(
        new OutputStreamWriter(
          new FileOutputStream(file, true)
        )
      )
    )
  )
  def out(s: => String): Unit = writer println s
  def err(s: => String): Unit = writer println s
  def buffer[T](f: => T): T = f
  def close(): Unit = writer.close()
  def flush(): Unit = writer.flush()
}

object ProcessLogger {
  def apply(file: File): FileProcessLogger = new FileProcessLogger(file)
  def apply(fn: String => Unit): ProcessLogger = apply(fn, fn)
  def apply(fout: String => Unit, ferr: String => Unit): ProcessLogger = new ProcessLogger {
    def out(s: => String): Unit = fout(s)
    def err(s: => String): Unit = ferr(s)
    def buffer[T](f: => T): T = f
  }
}