Skip to content
Browse files

success indication and timestamps for actions

  • Loading branch information...
1 parent 201faac commit ea188e74cc21d87f76ad2e9fc581e9e138a0fee5 @harrah committed Mar 6, 2011
View
43 main/Aggregation.scala
@@ -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
View
3 main/Defaults.scala
@@ -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 }
))
View
4 main/Keys.scala
@@ -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")
View
3 util/log/BasicLogger.scala
@@ -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 }
View
6 util/log/BufferedLogger.scala
@@ -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)
View
2 util/log/ConsoleLogger.scala
@@ -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 =
View
4 util/log/FilterLogger.scala
@@ -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)
View
3 util/log/FullLogger.scala
@@ -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)
View
5 util/log/Level.scala
@@ -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
View
1 util/log/LogEvent.scala
@@ -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
View
6 util/log/Logger.scala
@@ -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)
View
5 util/log/MultiLogger.scala
@@ -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)) }

0 comments on commit ea188e7

Please sign in to comment.
Something went wrong with that request. Please try again.