mirror of https://github.com/sbt/sbt.git
Filling in logging and making cross-compile work.
This commit is contained in:
parent
b094fc3cc8
commit
3aba701b00
|
|
@ -0,0 +1,6 @@
|
||||||
|
package xsbti;
|
||||||
|
|
||||||
|
public abstract class CompileFailed extends RuntimeException
|
||||||
|
{
|
||||||
|
public abstract String[] arguments();
|
||||||
|
}
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
package xsbti
|
|
||||||
|
|
||||||
class TestLogger extends Logger
|
|
||||||
{
|
|
||||||
private val buffer = new scala.collection.mutable.ArrayBuffer[F0[Unit]]
|
|
||||||
def info(msg: F0[String]) = buffer("[info] ", msg)
|
|
||||||
def warn(msg: F0[String]) = buffer("[warn] ", msg)
|
|
||||||
def debug(msg: F0[String]) = buffer("[debug] ", msg)
|
|
||||||
def error(msg: F0[String]) = buffer("[error] ", msg)
|
|
||||||
def verbose(msg: F0[String]) = buffer("[verbose] ", msg)
|
|
||||||
def info(msg: => String) = buffer("[info] ", msg)
|
|
||||||
def warn(msg: => String) = buffer("[warn] ", msg)
|
|
||||||
def debug(msg: => String) = buffer("[debug] ", msg)
|
|
||||||
def error(msg: => String) = buffer("[error] ", msg)
|
|
||||||
def verbose(msg: => String) = buffer("[verbose] ", msg)
|
|
||||||
def show() { buffer.foreach(_()) }
|
|
||||||
def clear() { buffer.clear() }
|
|
||||||
def trace(t: F0[Throwable]) { buffer += f0(t().printStackTrace) }
|
|
||||||
private def buffer(s: String, msg: F0[String]) { buffer(s, msg()) }
|
|
||||||
private def buffer(s: String, msg: => String) { buffer += f0(println(s + msg)) }
|
|
||||||
}
|
|
||||||
object TestLogger
|
|
||||||
{
|
|
||||||
def apply[T](f: Logger => T): T =
|
|
||||||
{
|
|
||||||
val log = new TestLogger
|
|
||||||
try { f(log) }
|
|
||||||
catch { case e: Exception => log.show(); throw e }
|
|
||||||
finally { log.clear() }
|
|
||||||
}
|
|
||||||
def apply[L <: TestLogger, T](newLogger: => L)(f: L => T): T =
|
|
||||||
{
|
|
||||||
val log = newLogger
|
|
||||||
try { f(log) }
|
|
||||||
catch { case e: Exception => log.show(); throw e }
|
|
||||||
finally { log.clear() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
/* sbt -- Simple Build Tool
|
||||||
|
* Copyright 2008, 2009 Mark Harrah
|
||||||
|
*/
|
||||||
|
package xsbt
|
||||||
|
|
||||||
|
/** Implements the level-setting methods of Logger.*/
|
||||||
|
abstract class BasicLogger extends Logger
|
||||||
|
{
|
||||||
|
private var traceEnabledVar = true
|
||||||
|
private var level: Level.Value = Level.Info
|
||||||
|
def getLevel = level
|
||||||
|
def setLevel(newLevel: Level.Value) { level = newLevel }
|
||||||
|
def enableTrace(flag: Boolean) { traceEnabledVar = flag }
|
||||||
|
def traceEnabled = traceEnabledVar
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
/* sbt -- Simple Build Tool
|
||||||
|
* Copyright 2008, 2009 Mark Harrah
|
||||||
|
*/
|
||||||
|
package xsbt
|
||||||
|
|
||||||
|
import scala.collection.mutable.ListBuffer
|
||||||
|
|
||||||
|
/** A logger that can buffer the logging done on it and then can flush the buffer
|
||||||
|
* to the delegate logger provided in the constructor. Use 'startRecording' to
|
||||||
|
* start buffering and then 'play' from to flush the buffer to the backing logger.
|
||||||
|
* The logging level set at the time a message is originally logged is used, not
|
||||||
|
* the level at the time 'play' is called.
|
||||||
|
*
|
||||||
|
* This class assumes that it is the only client of the delegate logger.
|
||||||
|
* */
|
||||||
|
class BufferedLogger(delegate: Logger) extends Logger
|
||||||
|
{
|
||||||
|
private[this] val buffer = new ListBuffer[LogEvent]
|
||||||
|
private[this] var recording = false
|
||||||
|
|
||||||
|
/** Enables buffering. */
|
||||||
|
def record() = { recording = true }
|
||||||
|
def buffer[T](f: => T): T =
|
||||||
|
{
|
||||||
|
record()
|
||||||
|
try { f }
|
||||||
|
finally { stopQuietly() }
|
||||||
|
}
|
||||||
|
def bufferQuietly[T](f: => T): T =
|
||||||
|
{
|
||||||
|
record()
|
||||||
|
try
|
||||||
|
{
|
||||||
|
val result = f
|
||||||
|
clear()
|
||||||
|
result
|
||||||
|
}
|
||||||
|
catch { case e => stopQuietly(); throw e }
|
||||||
|
}
|
||||||
|
private def stopQuietly() = try { stop() } catch { case e: Exception => () }
|
||||||
|
|
||||||
|
/** Flushes the buffer to the delegate logger. This method calls logAll on the delegate
|
||||||
|
* so that the messages are written consecutively. The buffer is cleared in the process. */
|
||||||
|
def play() { delegate.logAll(buffer.readOnly); buffer.clear() }
|
||||||
|
/** Clears buffered events and disables buffering. */
|
||||||
|
def clear(): Unit = { buffer.clear(); recording = false }
|
||||||
|
/** Plays buffered events and disables buffering. */
|
||||||
|
def stop() { play(); clear() }
|
||||||
|
|
||||||
|
def setLevel(newLevel: Level.Value)
|
||||||
|
{
|
||||||
|
buffer += new SetLevel(newLevel)
|
||||||
|
delegate.setLevel(newLevel)
|
||||||
|
}
|
||||||
|
def getLevel = delegate.getLevel
|
||||||
|
def traceEnabled = delegate.traceEnabled
|
||||||
|
def enableTrace(flag: Boolean)
|
||||||
|
{
|
||||||
|
buffer += new SetTrace(flag)
|
||||||
|
delegate.enableTrace(flag)
|
||||||
|
}
|
||||||
|
|
||||||
|
def trace(t: => Throwable): Unit =
|
||||||
|
doBufferableIf(traceEnabled, new Trace(t), _.trace(t))
|
||||||
|
def success(message: => String): Unit =
|
||||||
|
doBufferable(Level.Info, new Success(message), _.success(message))
|
||||||
|
def log(level: Level.Value, message: => String): Unit =
|
||||||
|
doBufferable(level, new Log(level, message), _.log(level, message))
|
||||||
|
def logAll(events: Seq[LogEvent]): Unit =
|
||||||
|
if(recording)
|
||||||
|
buffer ++= events
|
||||||
|
else
|
||||||
|
delegate.logAll(events)
|
||||||
|
def control(event: ControlEvent.Value, message: => String): Unit =
|
||||||
|
doBufferable(Level.Info, new ControlEvent(event, message), _.control(event, message))
|
||||||
|
private def doBufferable(level: Level.Value, appendIfBuffered: => LogEvent, doUnbuffered: Logger => Unit): Unit =
|
||||||
|
doBufferableIf(atLevel(level), appendIfBuffered, doUnbuffered)
|
||||||
|
private def doBufferableIf(condition: => Boolean, appendIfBuffered: => LogEvent, doUnbuffered: Logger => Unit): Unit =
|
||||||
|
if(condition)
|
||||||
|
{
|
||||||
|
if(recording)
|
||||||
|
buffer += appendIfBuffered
|
||||||
|
else
|
||||||
|
doUnbuffered(delegate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
/* sbt -- Simple Build Tool
|
||||||
|
* Copyright 2008, 2009 Mark Harrah
|
||||||
|
*/
|
||||||
|
package xsbt
|
||||||
|
|
||||||
|
object ConsoleLogger
|
||||||
|
{
|
||||||
|
private val formatEnabled = ansiSupported && !formatExplicitlyDisabled
|
||||||
|
|
||||||
|
private[this] def formatExplicitlyDisabled = java.lang.Boolean.getBoolean("sbt.log.noformat")
|
||||||
|
private[this] def ansiSupported =
|
||||||
|
try { jline.Terminal.getTerminal.isANSISupported }
|
||||||
|
catch { case e: Exception => !isWindows }
|
||||||
|
|
||||||
|
private[this] def os = System.getProperty("os.name")
|
||||||
|
private[this] def isWindows = os.toLowerCase.indexOf("windows") >= 0
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A logger that logs to the console. On supported systems, the level labels are
|
||||||
|
* colored. */
|
||||||
|
class ConsoleLogger extends BasicLogger
|
||||||
|
{
|
||||||
|
import ConsoleLogger.formatEnabled
|
||||||
|
def messageColor(level: Level.Value) = Console.RESET
|
||||||
|
def labelColor(level: Level.Value) =
|
||||||
|
level match
|
||||||
|
{
|
||||||
|
case Level.Error => Console.RED
|
||||||
|
case Level.Warn => Console.YELLOW
|
||||||
|
case _ => Console.RESET
|
||||||
|
}
|
||||||
|
def successLabelColor = Console.GREEN
|
||||||
|
def successMessageColor = Console.RESET
|
||||||
|
override def success(message: => String)
|
||||||
|
{
|
||||||
|
if(atLevel(Level.Info))
|
||||||
|
log(successLabelColor, Level.SuccessLabel, successMessageColor, message)
|
||||||
|
}
|
||||||
|
def trace(t: => Throwable): Unit =
|
||||||
|
System.out.synchronized
|
||||||
|
{
|
||||||
|
if(traceEnabled)
|
||||||
|
t.printStackTrace
|
||||||
|
}
|
||||||
|
def log(level: Level.Value, message: => String)
|
||||||
|
{
|
||||||
|
if(atLevel(level))
|
||||||
|
log(labelColor(level), level.toString, messageColor(level), message)
|
||||||
|
}
|
||||||
|
private def setColor(color: String)
|
||||||
|
{
|
||||||
|
if(formatEnabled)
|
||||||
|
System.out.synchronized { System.out.print(color) }
|
||||||
|
}
|
||||||
|
private def log(labelColor: String, label: String, messageColor: String, message: String): Unit =
|
||||||
|
System.out.synchronized
|
||||||
|
{
|
||||||
|
for(line <- message.split("""\n"""))
|
||||||
|
{
|
||||||
|
setColor(Console.RESET)
|
||||||
|
System.out.print('[')
|
||||||
|
setColor(labelColor)
|
||||||
|
System.out.print(label)
|
||||||
|
setColor(Console.RESET)
|
||||||
|
System.out.print("] ")
|
||||||
|
setColor(messageColor)
|
||||||
|
System.out.print(line)
|
||||||
|
setColor(Console.RESET)
|
||||||
|
System.out.println()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def logAll(events: Seq[LogEvent]) = System.out.synchronized { events.foreach(log) }
|
||||||
|
def control(event: ControlEvent.Value, message: => String)
|
||||||
|
{ log(labelColor(Level.Info), Level.Info.toString, Console.BLUE, message) }
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
/* sbt -- Simple Build Tool
|
||||||
|
* Copyright 2008, 2009 Mark Harrah
|
||||||
|
*/
|
||||||
|
package xsbt
|
||||||
|
|
||||||
|
/** An enumeration defining the levels available for logging. A level includes all of the levels
|
||||||
|
* with id larger than its own id. For example, Warn (id=3) includes Error (id=4).*/
|
||||||
|
object Level extends Enumeration with NotNull
|
||||||
|
{
|
||||||
|
val Debug = Value(1, "debug")
|
||||||
|
val Info = Value(2, "info")
|
||||||
|
val Warn = Value(3, "warn")
|
||||||
|
val Error = Value(4, "error")
|
||||||
|
/** Defines the label to use for success messages. A success message is logged at the info level but
|
||||||
|
* uses this label. Because the label for levels is defined in this module, the success
|
||||||
|
* label is also defined here. */
|
||||||
|
val SuccessLabel = "success"
|
||||||
|
|
||||||
|
// added because elements was renamed to iterator in 2.8.0 nightly
|
||||||
|
def levels = Debug :: Info :: Warn :: Error :: Nil
|
||||||
|
/** Returns the level with the given name wrapped in Some, or None if no level exists for that name. */
|
||||||
|
def apply(s: String) = levels.find(s == _.toString)
|
||||||
|
/** Same as apply, defined for use in pattern matching. */
|
||||||
|
private[xsbt] def unapply(s: String) = apply(s)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
/* sbt -- Simple Build Tool
|
||||||
|
* Copyright 2008, 2009 Mark Harrah
|
||||||
|
*/
|
||||||
|
package xsbt
|
||||||
|
|
||||||
|
sealed trait LogEvent extends NotNull
|
||||||
|
final class Success(val msg: String) extends LogEvent
|
||||||
|
final class Log(val level: Level.Value, val msg: String) extends LogEvent
|
||||||
|
final class Trace(val exception: Throwable) extends LogEvent
|
||||||
|
final class SetLevel(val newLevel: Level.Value) extends LogEvent
|
||||||
|
final class SetTrace(val enabled: Boolean) extends LogEvent
|
||||||
|
final class ControlEvent(val event: ControlEvent.Value, val msg: String) extends LogEvent
|
||||||
|
|
||||||
|
object ControlEvent extends Enumeration
|
||||||
|
{
|
||||||
|
val Start, Header, Finish = Value
|
||||||
|
}
|
||||||
|
|
@ -3,13 +3,14 @@
|
||||||
*/
|
*/
|
||||||
package xsbt
|
package xsbt
|
||||||
|
|
||||||
abstract class Logger extends NotNull
|
import xsbti.{Logger => xLogger, F0}
|
||||||
|
abstract class Logger extends xLogger with NotNull
|
||||||
{
|
{
|
||||||
def getLevel: Level.Value
|
def getLevel: Level.Value
|
||||||
def setLevel(newLevel: Level.Value)
|
def setLevel(newLevel: Level.Value)
|
||||||
def enableTrace(flag: Boolean)
|
def enableTrace(flag: Boolean)
|
||||||
def traceEnabled: Boolean
|
def traceEnabled: Boolean
|
||||||
|
|
||||||
def atLevel(level: Level.Value) = level.id >= getLevel.id
|
def atLevel(level: Level.Value) = level.id >= getLevel.id
|
||||||
def trace(t: => Throwable): Unit
|
def trace(t: => Throwable): Unit
|
||||||
final def debug(message: => String): Unit = log(Level.Debug, message)
|
final def debug(message: => String): Unit = log(Level.Debug, message)
|
||||||
|
|
@ -19,7 +20,7 @@ abstract class Logger extends NotNull
|
||||||
def success(message: => String): Unit
|
def success(message: => String): Unit
|
||||||
def log(level: Level.Value, message: => String): Unit
|
def log(level: Level.Value, message: => String): Unit
|
||||||
def control(event: ControlEvent.Value, message: => String): Unit
|
def control(event: ControlEvent.Value, message: => String): Unit
|
||||||
|
|
||||||
def logAll(events: Seq[LogEvent]): Unit
|
def logAll(events: Seq[LogEvent]): Unit
|
||||||
/** Defined in terms of other methods in Logger and should not be called from them. */
|
/** Defined in terms of other methods in Logger and should not be called from them. */
|
||||||
final def log(event: LogEvent)
|
final def log(event: LogEvent)
|
||||||
|
|
@ -34,38 +35,11 @@ abstract class Logger extends NotNull
|
||||||
case c: ControlEvent => control(c.event, c.msg)
|
case c: ControlEvent => control(c.event, c.msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def debug(msg: F0[String]): Unit = log(Level.Debug, msg)
|
||||||
|
def warn(msg: F0[String]): Unit = log(Level.Warn, msg)
|
||||||
|
def info(msg: F0[String]): Unit = log(Level.Info, msg)
|
||||||
|
def error(msg: F0[String]): Unit = log(Level.Error, msg)
|
||||||
|
def trace(msg: F0[Throwable]) = trace(msg.apply)
|
||||||
|
def log(level: Level.Value, msg: F0[String]): Unit = log(level, msg.apply)
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed trait LogEvent extends NotNull
|
|
||||||
final class Success(val msg: String) extends LogEvent
|
|
||||||
final class Log(val level: Level.Value, val msg: String) extends LogEvent
|
|
||||||
final class Trace(val exception: Throwable) extends LogEvent
|
|
||||||
final class SetLevel(val newLevel: Level.Value) extends LogEvent
|
|
||||||
final class SetTrace(val enabled: Boolean) extends LogEvent
|
|
||||||
final class ControlEvent(val event: ControlEvent.Value, val msg: String) extends LogEvent
|
|
||||||
|
|
||||||
object ControlEvent extends Enumeration
|
|
||||||
{
|
|
||||||
val Start, Header, Finish = Value
|
|
||||||
}
|
|
||||||
|
|
||||||
/** An enumeration defining the levels available for logging. A level includes all of the levels
|
|
||||||
* with id larger than its own id. For example, Warn (id=3) includes Error (id=4).*/
|
|
||||||
object Level extends Enumeration with NotNull
|
|
||||||
{
|
|
||||||
val Debug = Value(1, "debug")
|
|
||||||
val Info = Value(2, "info")
|
|
||||||
val Warn = Value(3, "warn")
|
|
||||||
val Error = Value(4, "error")
|
|
||||||
/** Defines the label to use for success messages. A success message is logged at the info level but
|
|
||||||
* uses this label. Because the label for levels is defined in this module, the success
|
|
||||||
* label is also defined here. */
|
|
||||||
val SuccessLabel = "success"
|
|
||||||
|
|
||||||
// added because elements was renamed to iterator in 2.8.0 nightly
|
|
||||||
def levels = Debug :: Info :: Warn :: Error :: Nil
|
|
||||||
/** Returns the level with the given name wrapped in Some, or None if no level exists for that name. */
|
|
||||||
def apply(s: String) = levels.find(s == _.toString)
|
|
||||||
/** Same as apply, defined for use in pattern matching. */
|
|
||||||
private[xsbt] def unapply(s: String) = apply(s)
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue