mirror of https://github.com/sbt/sbt.git
Add Event trait to FileCacheEntry
Rather than exposing the FileEventMonitor.Event types, which are under active development in the io repo, I am adding a new event trait to FileCacheEntry. This trait doesn't expose any internal implementation details.
This commit is contained in:
parent
86200345e1
commit
be94b25d68
|
|
@ -23,7 +23,6 @@ import sbt.internal.util.Types.const
|
|||
import sbt.internal.util.complete.{ DefaultParsers, Parser }
|
||||
import sbt.internal.util.{ AttributeKey, JLine }
|
||||
import sbt.internal.{ FileCacheEntry, LegacyWatched }
|
||||
import sbt.io.FileEventMonitor.{ Creation, Deletion, Event, Update }
|
||||
import sbt.io._
|
||||
import sbt.util.{ Level, Logger }
|
||||
|
||||
|
|
@ -145,13 +144,14 @@ object Watched {
|
|||
private[sbt] def onEvent(
|
||||
sources: Seq[WatchSource],
|
||||
projectSources: Seq[WatchSource]
|
||||
): Event[FileCacheEntry] => Watched.Action =
|
||||
): FileCacheEntry.Event => Watched.Action =
|
||||
event =>
|
||||
if (sources.exists(_.accept(event.entry.typedPath.toPath))) Watched.Trigger
|
||||
else if (projectSources.exists(_.accept(event.entry.typedPath.toPath))) event match {
|
||||
case Update(prev, cur, _) if prev.value != cur.value => Reload
|
||||
case _: Creation[_] | _: Deletion[_] => Reload
|
||||
case _ => Ignore
|
||||
if (sources.exists(_.accept(event.path))) Watched.Trigger
|
||||
else if (projectSources.exists(_.accept(event.path))) {
|
||||
(event.previous, event.current) match {
|
||||
case (Some(p), Some(c)) => if (c == p) Watched.Ignore else Watched.Reload
|
||||
case _ => Watched.Trigger
|
||||
}
|
||||
} else Ignore
|
||||
|
||||
private[this] val reRun = if (isWin) "" else " or 'r' to re-run the command"
|
||||
|
|
@ -333,7 +333,9 @@ object Watched {
|
|||
case action @ (CancelWatch | HandleError | Reload | _: Custom) => action
|
||||
case Trigger => Trigger
|
||||
case _ =>
|
||||
val events = config.fileEventMonitor.poll(10.millis)
|
||||
val events = config.fileEventMonitor
|
||||
.poll(10.millis)
|
||||
.map(new FileCacheEntry.EventImpl(_))
|
||||
val next = events match {
|
||||
case Seq() => (Ignore, None)
|
||||
case Seq(head, tail @ _*) =>
|
||||
|
|
@ -362,14 +364,14 @@ object Watched {
|
|||
if (action == HandleError) "error"
|
||||
else if (action.isInstanceOf[Custom]) action.toString
|
||||
else "cancellation"
|
||||
logger.debug(s"Stopping watch due to $cause from ${event.entry.typedPath.toPath}")
|
||||
logger.debug(s"Stopping watch due to $cause from ${event.path}")
|
||||
action
|
||||
case (Trigger, Some(event)) =>
|
||||
logger.debug(s"Triggered by ${event.entry.typedPath.toPath}")
|
||||
config.triggeredMessage(event.entry.typedPath.toPath, count).foreach(info)
|
||||
logger.debug(s"Triggered by ${event.path}")
|
||||
config.triggeredMessage(event.path, count).foreach(info)
|
||||
Trigger
|
||||
case (Reload, Some(event)) =>
|
||||
logger.info(s"Reload triggered by ${event.entry.typedPath.toPath}")
|
||||
logger.info(s"Reload triggered by ${event.path}")
|
||||
Reload
|
||||
case _ =>
|
||||
nextAction()
|
||||
|
|
@ -481,7 +483,7 @@ trait WatchConfig {
|
|||
* @param event the detected sbt.io.FileEventMonitor.Event.
|
||||
* @return the next [[Watched.Action Action]] to run.
|
||||
*/
|
||||
def onWatchEvent(event: Event[FileCacheEntry]): Watched.Action
|
||||
def onWatchEvent(event: FileCacheEntry.Event): Watched.Action
|
||||
|
||||
/**
|
||||
* Transforms the state after the watch terminates.
|
||||
|
|
@ -540,7 +542,7 @@ object WatchConfig {
|
|||
fileEventMonitor: FileEventMonitor[FileCacheEntry],
|
||||
handleInput: InputStream => Watched.Action,
|
||||
preWatch: (Int, Boolean) => Watched.Action,
|
||||
onWatchEvent: Event[FileCacheEntry] => Watched.Action,
|
||||
onWatchEvent: FileCacheEntry.Event => Watched.Action,
|
||||
onWatchTerminated: (Watched.Action, String, State) => State,
|
||||
triggeredMessage: (Path, Int) => Option[String],
|
||||
watchingMessage: Int => Option[String]
|
||||
|
|
@ -559,7 +561,7 @@ object WatchConfig {
|
|||
override def handleInput(inputStream: InputStream): Watched.Action = hi(inputStream)
|
||||
override def preWatch(count: Int, lastResult: Boolean): Watched.Action =
|
||||
pw(count, lastResult)
|
||||
override def onWatchEvent(event: Event[FileCacheEntry]): Watched.Action = owe(event)
|
||||
override def onWatchEvent(event: FileCacheEntry.Event): Watched.Action = owe(event)
|
||||
override def onWatchTerminated(action: Watched.Action, command: String, state: State): State =
|
||||
owt(action, command, state)
|
||||
override def triggeredMessage(path: Path, count: Int): Option[String] =
|
||||
|
|
|
|||
|
|
@ -8,10 +8,12 @@
|
|||
package sbt
|
||||
package internal
|
||||
import java.lang
|
||||
import java.nio.file.Path
|
||||
import java.util.Optional
|
||||
|
||||
import sbt.internal.inc.{ EmptyStamp, LastModified, Stamp }
|
||||
import sbt.io.TypedPath
|
||||
import sbt.io.FileEventMonitor.{ Creation, Deletion, Update }
|
||||
import sbt.io.{ FileEventMonitor, TypedPath }
|
||||
import xsbti.compile.analysis.{ Stamp => XStamp }
|
||||
|
||||
/**
|
||||
|
|
@ -23,7 +25,33 @@ trait FileCacheEntry {
|
|||
def lastModified: Option[Long]
|
||||
}
|
||||
object FileCacheEntry {
|
||||
def default(typedPath: TypedPath): FileCacheEntry =
|
||||
trait Event {
|
||||
def path: Path
|
||||
def previous: Option[FileCacheEntry]
|
||||
def current: Option[FileCacheEntry]
|
||||
}
|
||||
private[sbt] class EventImpl(event: FileEventMonitor.Event[FileCacheEntry]) extends Event {
|
||||
override def path: Path = event.entry.typedPath.toPath
|
||||
override def previous: Option[FileCacheEntry] = event match {
|
||||
case Deletion(entry, _) => entry.value.toOption
|
||||
case Update(previous, _, _) => previous.value.toOption
|
||||
case _ => None
|
||||
}
|
||||
override def current: Option[FileCacheEntry] = event match {
|
||||
case Creation(entry, _) => entry.value.toOption
|
||||
case Update(_, current, _) => current.value.toOption
|
||||
case _ => None
|
||||
}
|
||||
override def equals(o: Any): Boolean = o match {
|
||||
case that: Event =>
|
||||
this.path == that.path && this.previous == that.previous && this.current == that.current
|
||||
case _ => false
|
||||
}
|
||||
override def hashCode(): Int =
|
||||
((path.hashCode * 31) ^ previous.hashCode() * 31) ^ current.hashCode()
|
||||
override def toString: String = s"Event($path, $previous, $current)"
|
||||
}
|
||||
private[sbt] def default(typedPath: TypedPath): FileCacheEntry =
|
||||
DelegateFileCacheEntry(Stamped.converter(typedPath))
|
||||
private[sbt] implicit class FileCacheEntryOps(val e: FileCacheEntry) extends AnyVal {
|
||||
private[sbt] def stamp: XStamp = e match {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ import org.scalatest.{ FlatSpec, Matchers }
|
|||
import sbt.Watched._
|
||||
import sbt.WatchedSpec._
|
||||
import sbt.internal.FileCacheEntry
|
||||
import sbt.io.FileEventMonitor.Event
|
||||
import sbt.io._
|
||||
import sbt.io.syntax._
|
||||
import sbt.util.Logger
|
||||
|
|
@ -31,7 +30,7 @@ class WatchedSpec extends FlatSpec with Matchers {
|
|||
logger: Logger = NullLogger,
|
||||
handleInput: InputStream => Action = _ => Ignore,
|
||||
preWatch: (Int, Boolean) => Action = (_, _) => CancelWatch,
|
||||
onWatchEvent: Event[FileCacheEntry] => Action = _ => Ignore,
|
||||
onWatchEvent: FileCacheEntry.Event => Action = _ => Ignore,
|
||||
triggeredMessage: (Path, Int) => Option[String] = (_, _) => None,
|
||||
watchingMessage: Int => Option[String] = _ => None
|
||||
): WatchConfig = {
|
||||
|
|
@ -87,7 +86,7 @@ class WatchedSpec extends FlatSpec with Matchers {
|
|||
val config = Defaults.config(
|
||||
globs = Seq(realDir ** AllPassFilter),
|
||||
preWatch = (count, _) => if (count == 2) CancelWatch else Ignore,
|
||||
onWatchEvent = e => if (e.entry.typedPath.toPath == foo) Trigger else Ignore,
|
||||
onWatchEvent = e => if (e.path == foo) Trigger else Ignore,
|
||||
triggeredMessage = (tp, _) => { queue += tp; None },
|
||||
watchingMessage = _ => { Files.createFile(bar); Thread.sleep(5); Files.createFile(foo); None }
|
||||
)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import sbt.internal.io.WatchState
|
|||
import sbt.internal.librarymanagement.{ CompatibilityWarningOptions, IvySbt }
|
||||
import sbt.internal.server.ServerHandler
|
||||
import sbt.internal.util.{ AttributeKey, SourcePosition }
|
||||
import sbt.io.FileEventMonitor.Event
|
||||
import sbt.io._
|
||||
import sbt.librarymanagement.Configurations.CompilerPlugin
|
||||
import sbt.librarymanagement.LibraryManagementCodec._
|
||||
|
|
@ -102,7 +101,7 @@ object Keys {
|
|||
val watchConfig = taskKey[WatchConfig]("The configuration for continuous execution.").withRank(BMinusSetting)
|
||||
val watchLogger = taskKey[Logger]("A logger that reports watch events.").withRank(DSetting)
|
||||
val watchHandleInput = settingKey[InputStream => Watched.Action]("Function that is periodically invoked to determine if the continous build should be stopped or if a build should be triggered. It will usually read from stdin to respond to user commands.").withRank(BMinusSetting)
|
||||
val watchOnEvent = taskKey[Event[FileCacheEntry] => Watched.Action]("Determines how to handle a file event").withRank(BMinusSetting)
|
||||
val watchOnEvent = taskKey[FileCacheEntry.Event => Watched.Action]("Determines how to handle a file event").withRank(BMinusSetting)
|
||||
val watchOnTermination = taskKey[(Watched.Action, String, State) => State]("Transforms the input state after the continuous build completes.").withRank(BMinusSetting)
|
||||
val watchService = settingKey[() => WatchService]("Service to use to monitor file system changes.").withRank(BMinusSetting)
|
||||
val watchProjectSources = taskKey[Seq[Watched.WatchSource]]("Defines the sources for the sbt meta project to watch to trigger a reload.").withRank(CSetting)
|
||||
|
|
|
|||
Loading…
Reference in New Issue