allow watching and triggered messages to be customized

This commit is contained in:
Mark Harrah 2011-09-16 22:04:51 -04:00
parent babe8dbbdb
commit de6f55952f
3 changed files with 24 additions and 3 deletions

View File

@ -56,6 +56,8 @@ object Defaults extends BuildCommon
autoScalaLibrary :== true,
onLoad <<= onLoad ?? idFun[State],
onUnload <<= onUnload ?? idFun[State],
watchingMessage <<= watchingMessage ?? Watched.defaultWatchingMessage,
triggeredMessage <<= triggeredMessage ?? Watched.defaultTriggeredMessage,
definesClass :== FileValueCache(Locate.definesClass _ ).get,
trapExit :== false,
trapExit in run :== true,
@ -224,11 +226,13 @@ object Defaults extends BuildCommon
def watchTransitiveSourcesTask: Initialize[Task[Seq[File]]] =
inDependencies[Task[Seq[File]]](watchSources.task, const(std.TaskExtra.constant(Nil)), includeRoot = true) apply { _.join.map(_.flatten) }
def watchSetting: Initialize[Watched] = (pollInterval, thisProjectRef) { (interval, base) =>
def watchSetting: Initialize[Watched] = (pollInterval, thisProjectRef, watchingMessage, triggeredMessage) { (interval, base, msg, trigMsg) =>
new Watched {
val scoped = watchTransitiveSources in base
val key = ScopedKey(scoped.scope, scoped.key)
override def pollInterval = interval
override def watchingMessage(s: WatchState) = msg(s)
override def triggeredMessage(s: WatchState) = trigMsg(s)
override def watchPaths(s: State) = EvaluateTask.evaluateTask(Project structure s, key, s, base) match {
case Some(Value(ps)) => ps
case Some(Inc(i)) => throw i

View File

@ -61,6 +61,8 @@ object Keys
val pollInterval = SettingKey[Int]("poll-interval", "Interval between checks for modified sources by the continuous execution command.")
val watchSources = TaskKey[Seq[File]]("watch-sources", "Defines the sources in this project for continuous execution to watch for changes.")
val watchTransitiveSources = TaskKey[Seq[File]]("watch-transitive-sources", "Defines the sources in all projects for continuous execution to watch.")
val watchingMessage = SettingKey[WatchState => String]("watching-message", "The message to show when triggered execution waits for sources to change.")
val triggeredMessage = SettingKey[WatchState => String]("triggered-message", "The message to show before triggered execution executes an action after sources change.")
// Path Keys
val baseDirectory = SettingKey[File]("base-directory", "The base directory. Depending on the scope, this is the base directory for the build, project, configuration, or task.")

View File

@ -6,6 +6,7 @@ package sbt
import CommandSupport.{ClearOnFailure,FailureWall}
import annotation.tailrec
import java.io.File
import Types.const
trait Watched
{
@ -15,10 +16,19 @@ trait Watched
/** The time in milliseconds between checking for changes. The actual time between the last change made to a file and the
* execution time is between `pollInterval` and `pollInterval*2`.*/
def pollInterval: Int = Watched.PollDelayMillis
/** The message to show when triggered execution waits for sources to change.*/
def watchingMessage(s: WatchState): String = Watched.defaultWatchingMessage(s)
/** The message to show before an action is run. */
def triggeredMessage(s: WatchState): String = Watched.defaultTriggeredMessage(s)
}
object Watched
{
val defaultWatchingMessage: WatchState => String = _.count + ". Waiting for source changes... (press enter to interrupt)"
val defaultTriggeredMessage: WatchState => String = const("")
val clearWhenTriggered: WatchState => String = const(clearScreen)
def clearScreen: String = "\033[2J\033[0;0H"
private[this] class AWatched extends Watched
def multi(base: Watched, paths: Seq[Watched]): Watched =
@ -27,11 +37,14 @@ object Watched
override def watchPaths(s: State) = (base.watchPaths(s) /: paths)(_ ++ _.watchPaths(s))
override def terminateWatch(key: Int): Boolean = base.terminateWatch(key)
override val pollInterval = (base +: paths).map(_.pollInterval).min
override def watchingMessage(s: WatchState) = base.watchingMessage(s)
override def triggeredMessage(s: WatchState) = base.triggeredMessage(s)
}
def empty: Watched = new AWatched
val PollDelayMillis = 500
def isEnter(key: Int): Boolean = key == 10 || key == 13
def printIfDefined(msg: String) = if(!msg.isEmpty) System.out.println(msg)
def executeContinuously(watched: Watched, s: State, next: String, repeat: String): State =
{
@ -40,7 +53,7 @@ object Watched
val watchState = s get ContinuousState getOrElse WatchState.empty
if(watchState.count > 0)
System.out.println(watchState.count + ". Waiting for source changes... (press enter to interrupt)")
printIfDefined(watched watchingMessage watchState)
val (triggered, newWatchState, newState) =
try {
@ -54,8 +67,10 @@ object Watched
(false, watchState, s.fail)
}
if(triggered)
if(triggered) {
printIfDefined(watched triggeredMessage newWatchState)
(ClearOnFailure :: next :: FailureWall :: repeat :: s).put(ContinuousState, newWatchState)
}
else
{
while (System.in.available() > 0) System.in.read()