diff options
Diffstat (limited to 'src/partest-alternative/scala/tools/partest/io/Logging.scala')
-rw-r--r-- | src/partest-alternative/scala/tools/partest/io/Logging.scala | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/src/partest-alternative/scala/tools/partest/io/Logging.scala b/src/partest-alternative/scala/tools/partest/io/Logging.scala new file mode 100644 index 0000000000..52239ffb2c --- /dev/null +++ b/src/partest-alternative/scala/tools/partest/io/Logging.scala @@ -0,0 +1,137 @@ +package scala.tools +package partest +package io + +import java.io.{ StringWriter, PrintWriter, Writer } +import scala.tools.nsc.io._ +import scala.util.control.ControlThrowable + +trait Logging { + universe: Universe => + + class PartestANSIWriter extends ANSIWriter(Console.out) { + override def colorful: Int = ANSIWriter(universe.isAnsi) + private def printIf(cond: Boolean, msg: String) = + if (cond) { outline("debug: ") ; println(msg) } + + val verbose = printIf(isVerbose || isDebug, _: String) + val debug = printIf(isDebug, _: String) + } + + lazy val NestUI = new PartestANSIWriter() + + import NestUI.{ _outline, _success, _failure, _warning, _default } + + def markOutline(msg: String) = _outline + msg + _default + def markSuccess(msg: String) = _success + msg + _default + def markFailure(msg: String) = _failure + msg + _default + def markWarning(msg: String) = _warning + msg + _default + def markNormal(msg: String) = _default + msg + + def outline(msg: String) = NestUI outline msg + def success(msg: String) = NestUI success msg + def failure(msg: String) = NestUI failure msg + def warning(msg: String) = NestUI warning msg + def normal(msg: String) = NestUI normal msg + + def verbose(msg: String) = NestUI verbose msg + def debug(msg: String) = NestUI debug msg + + trait EntityLogging { + self: TestEntity => + + lazy val logWriter = new LogWriter(logFile) + + /** Redirect stdout and stderr to logFile, run body, return result. + */ + def loggingOutAndErr[T](body: => T): T = { + val log = logFile.printStream(append = true) + + try Console.withOut(log) { + Console.withErr(log) { + body + } + } + finally log.close() + } + + /** What to print in a failure summary. + */ + def failureMessage() = if (diffOutput != "") diffOutput else safeSlurp(logFile) + + /** For tracing. Outputs a line describing the next action. tracePath + * is a path wrapper which prints name or full path depending on verbosity. + */ + def trace(msg: String) = if (isTrace || isDryRun) System.err.println(">> [%s] %s".format(label, msg)) + + def tracePath(path: Path): String = if (isVerbose) path.path else path.name + def tracePath(path: String): String = tracePath(Path(path)) + + /** v == verbose. + */ + def vtrace(msg: String) = if (isVerbose) trace(msg) + + /** Run body, writes result to logFile. Any throwable is + * caught, stringified, and written to the log. + */ + def loggingResult(body: => String) = + try returning(true)(_ => logFile writeAll body) + catch { + case x: ControlThrowable => throw x + case x: InterruptedException => debug(this + " received interrupt, failing.\n") ; false + case x: Throwable => logException(x) + } + + def throwableToString(x: Throwable): String = { + val w = new StringWriter + x.printStackTrace(new PrintWriter(w)) + w.toString + } + + def warnAndLog(str: String) = { + warning(toStringTrunc(str, 800)) + logWriter append str + } + + def warnAndLogException(msg: String, ex: Throwable) = + warnAndLog(msg + throwableToString(ex)) + + def deleteLog(force: Boolean = false) = + if (universe.isNoCleanup && !force) debug("Not cleaning up " + logFile) + else logFile.deleteIfExists() + + def onException(x: Throwable) { logException(x) } + def logException(x: Throwable) = { + val msg = throwableToString(x) + if (!isTerse) + normal(msg) + + logWriter append msg + false + } + } + + /** A writer which doesn't create the file until a write comes in. + */ + class LazilyCreatedWriter(log: File) extends Writer { + @volatile private var isCreated = false + private lazy val underlying = { + isCreated = true + log.bufferedWriter() + } + + def flush() = if (isCreated) underlying.flush() + def close() = if (isCreated) underlying.close() + def write(chars: Array[Char], off: Int, len: Int) = { + underlying.write(chars, off, len) + underlying.flush() + } + } + + class LogWriter(log: File) extends PrintWriter(new LazilyCreatedWriter(log), true) { + override def print(s: String) = { + super.print(s) + flush() + } + } +}
\ No newline at end of file |