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
|
||||
|
||||
abstract class Logger extends NotNull
|
||||
import xsbti.{Logger => xLogger, F0}
|
||||
abstract class Logger extends xLogger with NotNull
|
||||
{
|
||||
def getLevel: Level.Value
|
||||
def setLevel(newLevel: Level.Value)
|
||||
def enableTrace(flag: Boolean)
|
||||
def traceEnabled: Boolean
|
||||
|
||||
|
||||
def atLevel(level: Level.Value) = level.id >= getLevel.id
|
||||
def trace(t: => Throwable): Unit
|
||||
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 log(level: Level.Value, message: => String): Unit
|
||||
def control(event: ControlEvent.Value, message: => String): Unit
|
||||
|
||||
|
||||
def logAll(events: Seq[LogEvent]): Unit
|
||||
/** Defined in terms of other methods in Logger and should not be called from them. */
|
||||
final def log(event: LogEvent)
|
||||
|
|
@ -34,38 +35,11 @@ abstract class Logger extends NotNull
|
|||
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