mirror of https://github.com/sbt/sbt.git
success indication and timestamps for actions
This commit is contained in:
parent
201faacce8
commit
ea188e74cc
|
|
@ -7,7 +7,7 @@ package sbt
|
|||
import Project.ScopedKey
|
||||
import Load.BuildStructure
|
||||
import EvaluateTask.parseResult
|
||||
import Keys.aggregate
|
||||
import Keys.{aggregate, showSuccess, showTiming, timingFormat}
|
||||
import sbt.complete.Parser
|
||||
import java.net.URI
|
||||
import Parser._
|
||||
|
|
@ -76,10 +76,49 @@ final object Aggregation
|
|||
import EvaluateTask._
|
||||
import std.TaskExtra._
|
||||
val toRun = ts map { case KeyValue(k,t) => t.map(v => KeyValue(k,v)) } join;
|
||||
val start = System.currentTimeMillis
|
||||
val result = withStreams(structure){ str => runTask(toRun)(nodeView(s, str, extra.tasks, extra.values)) }
|
||||
val stop = System.currentTimeMillis
|
||||
val log = logger(s)
|
||||
onResult(result, log)( results => if(show) printSettings(results, log))
|
||||
lazy val extracted = Project.extract(s)
|
||||
|
||||
val success = result match { case Value(_) => true; case Inc(_) => false }
|
||||
try { onResult(result, log) { results => if(show) printSettings(results, log) } }
|
||||
finally { printSuccess(start, stop, Project.extract(s), success, log) }
|
||||
}
|
||||
def printSuccess(start: Long, stop: Long, extracted: Extracted, success: Boolean, log: Logger)
|
||||
{
|
||||
import extracted._
|
||||
lazy val enabled = showSuccess in extracted.currentRef get extracted.structure.data getOrElse true
|
||||
if(enabled)
|
||||
{
|
||||
val timingEnabled = showTiming in currentRef get structure.data getOrElse true
|
||||
if(timingEnabled)
|
||||
{
|
||||
val msg = timingString(start, stop, "", structure.data, currentRef, log)
|
||||
if(success) log.success(msg) else log.error(msg)
|
||||
}
|
||||
else if(success)
|
||||
log.success("")
|
||||
}
|
||||
}
|
||||
private def timingString(startTime: Long, endTime: Long, s: String, data: Settings[Scope], currentRef: ProjectRef, log: Logger): String =
|
||||
{
|
||||
val format = timingFormat in currentRef get data getOrElse defaultFormat
|
||||
timing(format, startTime, endTime, "", log)
|
||||
}
|
||||
def timing(format: java.text.DateFormat, startTime: Long, endTime: Long, s: String, log: Logger): String =
|
||||
{
|
||||
val ss = if(s.isEmpty) "" else s + " "
|
||||
val nowString = format.format(new java.util.Date(endTime))
|
||||
"Total " + ss + "time: " + (endTime - startTime + 500) / 1000 + " s, completed " + nowString
|
||||
}
|
||||
def defaultFormat =
|
||||
{
|
||||
import java.text.DateFormat
|
||||
DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM)
|
||||
}
|
||||
|
||||
final case class Dummies[HL <: HList](tasks: KList[Task,HL], values: HL)
|
||||
private[this] def dummyMap[HL <: HList, I](vs: Values[I], data: Settings[Scope], dummies: Dummies[HL]): Dummies[HL2] forSome { type HL2 <: HList } =
|
||||
vs match
|
||||
|
|
|
|||
|
|
@ -64,6 +64,9 @@ object Defaults
|
|||
// shellPrompt :== (_ => "> "),
|
||||
aggregate :== Aggregation.Enabled,
|
||||
maxErrors :== 100,
|
||||
showTiming :== true,
|
||||
timingFormat :== Aggregation.defaultFormat,
|
||||
showSuccess :== true,
|
||||
commands :== Nil,
|
||||
settings <<= EvaluateTask.state map { state => Project.structure(state).data }
|
||||
))
|
||||
|
|
|
|||
|
|
@ -18,6 +18,10 @@ object Keys
|
|||
// logging
|
||||
val logLevel = SettingKey[Level.Value]("log-level")
|
||||
val persistLogLevel = SettingKey[Level.Value]("persist-log-level")
|
||||
val traceLevel = SettingKey[Int]("trace-level")
|
||||
val showSuccess = SettingKey[Boolean]("show-success")
|
||||
val showTiming = SettingKey[Boolean]("show-timing")
|
||||
val timingFormat = SettingKey[java.text.DateFormat]("timing-format")
|
||||
|
||||
// Project keys
|
||||
val projectCommand = AttributeKey[Boolean]("project-command")
|
||||
|
|
|
|||
|
|
@ -8,6 +8,9 @@ abstract class BasicLogger extends AbstractLogger
|
|||
{
|
||||
private var traceEnabledVar = java.lang.Integer.MAX_VALUE
|
||||
private var level: Level.Value = Level.Info
|
||||
private var successEnabledVar = true
|
||||
def successEnabled = successEnabledVar
|
||||
def setSuccessEnabled(flag: Boolean) { successEnabledVar = flag }
|
||||
def getLevel = level
|
||||
def setLevel(newLevel: Level.Value) { level = newLevel }
|
||||
def setTrace(level: Int) { traceEnabledVar = level }
|
||||
|
|
|
|||
|
|
@ -52,6 +52,12 @@ class BufferedLogger(delegate: AbstractLogger) extends AbstractLogger
|
|||
buffer += new SetLevel(newLevel)
|
||||
delegate.setLevel(newLevel)
|
||||
}
|
||||
def setSuccessEnabled(flag: Boolean)
|
||||
{
|
||||
buffer += new SetSuccess(flag)
|
||||
delegate.setSuccessEnabled(flag)
|
||||
}
|
||||
def successEnabled = delegate.successEnabled
|
||||
def getLevel = delegate.getLevel
|
||||
def getTrace = delegate.getTrace
|
||||
def setTrace(level: Int)
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ class ConsoleLogger private[ConsoleLogger](val out: ConsoleOut, override val ans
|
|||
def successMessageColor = Console.RESET
|
||||
override def success(message: => String)
|
||||
{
|
||||
if(atLevel(Level.Info))
|
||||
if(successEnabled)
|
||||
log(successLabelColor, Level.SuccessLabel, successMessageColor, message)
|
||||
}
|
||||
def trace(t: => Throwable): Unit =
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ class FilterLogger(delegate: AbstractLogger) extends BasicLogger
|
|||
if(traceEnabled)
|
||||
delegate.trace(t)
|
||||
}
|
||||
override def setSuccessEnabled(flag: Boolean) { delegate.setSuccessEnabled(flag) }
|
||||
override def successEnabled = delegate.successEnabled
|
||||
override def setTrace(level: Int) { delegate.setTrace(level) }
|
||||
override def getTrace = delegate.getTrace
|
||||
def log(level: Level.Value, message: => String)
|
||||
|
|
@ -23,7 +25,7 @@ class FilterLogger(delegate: AbstractLogger) extends BasicLogger
|
|||
}
|
||||
def success(message: => String)
|
||||
{
|
||||
if(atLevel(Level.Info))
|
||||
if(successEnabled)
|
||||
delegate.success(message)
|
||||
}
|
||||
def control(event: ControlEvent.Value, message: => String)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ class FullLogger(delegate: Logger, override val ansiCodesSupported: Boolean = fa
|
|||
delegate.log(level, message)
|
||||
}
|
||||
def success(message: => String): Unit =
|
||||
info(message)
|
||||
if(successEnabled)
|
||||
delegate.success(message)
|
||||
def control(event: ControlEvent.Value, message: => String): Unit =
|
||||
info(message)
|
||||
def logAll(events: Seq[LogEvent]): Unit = events.foreach(log)
|
||||
|
|
|
|||
|
|
@ -11,9 +11,8 @@ object Level extends Enumeration
|
|||
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. */
|
||||
/** Defines the label to use for success messages.
|
||||
* Because the label for levels is defined in this module, the success label is also defined here. */
|
||||
val SuccessLabel = "success"
|
||||
|
||||
def union(a: Value, b: Value) = if(a.id < b.id) a else b
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ 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 level: Int) extends LogEvent
|
||||
final class SetSuccess(val enabled: Boolean) extends LogEvent
|
||||
final class ControlEvent(val event: ControlEvent.Value, val msg: String) extends LogEvent
|
||||
|
||||
object ControlEvent extends Enumeration
|
||||
|
|
|
|||
|
|
@ -12,9 +12,10 @@ abstract class AbstractLogger extends Logger
|
|||
def setTrace(flag: Int)
|
||||
def getTrace: Int
|
||||
final def traceEnabled = getTrace >= 0
|
||||
def successEnabled: Boolean
|
||||
def setSuccessEnabled(flag: Boolean): Unit
|
||||
|
||||
def atLevel(level: Level.Value) = level.id >= getLevel.id
|
||||
def success(message: => String): Unit
|
||||
def control(event: ControlEvent.Value, message: => String): Unit
|
||||
|
||||
def logAll(events: Seq[LogEvent]): Unit
|
||||
|
|
@ -28,6 +29,7 @@ abstract class AbstractLogger extends Logger
|
|||
case t: Trace => trace(t.exception)
|
||||
case setL: SetLevel => setLevel(setL.newLevel)
|
||||
case setT: SetTrace => setTrace(setT.level)
|
||||
case setS: SetSuccess => setSuccessEnabled(setS.enabled)
|
||||
case c: ControlEvent => control(c.event, c.msg)
|
||||
}
|
||||
}
|
||||
|
|
@ -45,6 +47,7 @@ object Logger
|
|||
override def trace(msg: F0[Throwable]) = lg.trace(msg)
|
||||
override def log(level: Level.Value, msg: F0[String]) = lg.log(level, msg)
|
||||
def trace(t: => Throwable) = trace(f0(t))
|
||||
def success(s: => String) = info(f0(s))
|
||||
def log(level: Level.Value, msg: => String) =
|
||||
{
|
||||
val fmsg = f0(msg)
|
||||
|
|
@ -73,6 +76,7 @@ trait Logger extends xLogger
|
|||
def ansiCodesSupported = false
|
||||
|
||||
def trace(t: => Throwable): Unit
|
||||
def success(message: => String): Unit
|
||||
def log(level: Level.Value, message: => String): Unit
|
||||
|
||||
def debug(msg: F0[String]): Unit = log(Level.Debug, msg)
|
||||
|
|
|
|||
|
|
@ -19,6 +19,11 @@ class MultiLogger(delegates: List[AbstractLogger]) extends BasicLogger
|
|||
super.setTrace(level)
|
||||
dispatch(new SetTrace(level))
|
||||
}
|
||||
override def setSuccessEnabled(flag: Boolean)
|
||||
{
|
||||
super.setSuccessEnabled(flag)
|
||||
dispatch(new SetSuccess(flag))
|
||||
}
|
||||
def trace(t: => Throwable) { dispatch(new Trace(t)) }
|
||||
def log(level: Level.Value, message: => String) { dispatch(new Log(level, message)) }
|
||||
def success(message: => String) { dispatch(new Success(message)) }
|
||||
|
|
|
|||
Loading…
Reference in New Issue