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.complete.{ DefaultParsers, Parser }
|
||||||
import sbt.internal.util.{ AttributeKey, JLine }
|
import sbt.internal.util.{ AttributeKey, JLine }
|
||||||
import sbt.internal.{ FileCacheEntry, LegacyWatched }
|
import sbt.internal.{ FileCacheEntry, LegacyWatched }
|
||||||
import sbt.io.FileEventMonitor.{ Creation, Deletion, Event, Update }
|
|
||||||
import sbt.io._
|
import sbt.io._
|
||||||
import sbt.util.{ Level, Logger }
|
import sbt.util.{ Level, Logger }
|
||||||
|
|
||||||
|
|
@ -145,13 +144,14 @@ object Watched {
|
||||||
private[sbt] def onEvent(
|
private[sbt] def onEvent(
|
||||||
sources: Seq[WatchSource],
|
sources: Seq[WatchSource],
|
||||||
projectSources: Seq[WatchSource]
|
projectSources: Seq[WatchSource]
|
||||||
): Event[FileCacheEntry] => Watched.Action =
|
): FileCacheEntry.Event => Watched.Action =
|
||||||
event =>
|
event =>
|
||||||
if (sources.exists(_.accept(event.entry.typedPath.toPath))) Watched.Trigger
|
if (sources.exists(_.accept(event.path))) Watched.Trigger
|
||||||
else if (projectSources.exists(_.accept(event.entry.typedPath.toPath))) event match {
|
else if (projectSources.exists(_.accept(event.path))) {
|
||||||
case Update(prev, cur, _) if prev.value != cur.value => Reload
|
(event.previous, event.current) match {
|
||||||
case _: Creation[_] | _: Deletion[_] => Reload
|
case (Some(p), Some(c)) => if (c == p) Watched.Ignore else Watched.Reload
|
||||||
case _ => Ignore
|
case _ => Watched.Trigger
|
||||||
|
}
|
||||||
} else Ignore
|
} else Ignore
|
||||||
|
|
||||||
private[this] val reRun = if (isWin) "" else " or 'r' to re-run the command"
|
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 action @ (CancelWatch | HandleError | Reload | _: Custom) => action
|
||||||
case Trigger => Trigger
|
case Trigger => Trigger
|
||||||
case _ =>
|
case _ =>
|
||||||
val events = config.fileEventMonitor.poll(10.millis)
|
val events = config.fileEventMonitor
|
||||||
|
.poll(10.millis)
|
||||||
|
.map(new FileCacheEntry.EventImpl(_))
|
||||||
val next = events match {
|
val next = events match {
|
||||||
case Seq() => (Ignore, None)
|
case Seq() => (Ignore, None)
|
||||||
case Seq(head, tail @ _*) =>
|
case Seq(head, tail @ _*) =>
|
||||||
|
|
@ -362,14 +364,14 @@ object Watched {
|
||||||
if (action == HandleError) "error"
|
if (action == HandleError) "error"
|
||||||
else if (action.isInstanceOf[Custom]) action.toString
|
else if (action.isInstanceOf[Custom]) action.toString
|
||||||
else "cancellation"
|
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
|
action
|
||||||
case (Trigger, Some(event)) =>
|
case (Trigger, Some(event)) =>
|
||||||
logger.debug(s"Triggered by ${event.entry.typedPath.toPath}")
|
logger.debug(s"Triggered by ${event.path}")
|
||||||
config.triggeredMessage(event.entry.typedPath.toPath, count).foreach(info)
|
config.triggeredMessage(event.path, count).foreach(info)
|
||||||
Trigger
|
Trigger
|
||||||
case (Reload, Some(event)) =>
|
case (Reload, Some(event)) =>
|
||||||
logger.info(s"Reload triggered by ${event.entry.typedPath.toPath}")
|
logger.info(s"Reload triggered by ${event.path}")
|
||||||
Reload
|
Reload
|
||||||
case _ =>
|
case _ =>
|
||||||
nextAction()
|
nextAction()
|
||||||
|
|
@ -481,7 +483,7 @@ trait WatchConfig {
|
||||||
* @param event the detected sbt.io.FileEventMonitor.Event.
|
* @param event the detected sbt.io.FileEventMonitor.Event.
|
||||||
* @return the next [[Watched.Action Action]] to run.
|
* @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.
|
* Transforms the state after the watch terminates.
|
||||||
|
|
@ -540,7 +542,7 @@ object WatchConfig {
|
||||||
fileEventMonitor: FileEventMonitor[FileCacheEntry],
|
fileEventMonitor: FileEventMonitor[FileCacheEntry],
|
||||||
handleInput: InputStream => Watched.Action,
|
handleInput: InputStream => Watched.Action,
|
||||||
preWatch: (Int, Boolean) => Watched.Action,
|
preWatch: (Int, Boolean) => Watched.Action,
|
||||||
onWatchEvent: Event[FileCacheEntry] => Watched.Action,
|
onWatchEvent: FileCacheEntry.Event => Watched.Action,
|
||||||
onWatchTerminated: (Watched.Action, String, State) => State,
|
onWatchTerminated: (Watched.Action, String, State) => State,
|
||||||
triggeredMessage: (Path, Int) => Option[String],
|
triggeredMessage: (Path, Int) => Option[String],
|
||||||
watchingMessage: Int => Option[String]
|
watchingMessage: Int => Option[String]
|
||||||
|
|
@ -559,7 +561,7 @@ object WatchConfig {
|
||||||
override def handleInput(inputStream: InputStream): Watched.Action = hi(inputStream)
|
override def handleInput(inputStream: InputStream): Watched.Action = hi(inputStream)
|
||||||
override def preWatch(count: Int, lastResult: Boolean): Watched.Action =
|
override def preWatch(count: Int, lastResult: Boolean): Watched.Action =
|
||||||
pw(count, lastResult)
|
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 =
|
override def onWatchTerminated(action: Watched.Action, command: String, state: State): State =
|
||||||
owt(action, command, state)
|
owt(action, command, state)
|
||||||
override def triggeredMessage(path: Path, count: Int): Option[String] =
|
override def triggeredMessage(path: Path, count: Int): Option[String] =
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,12 @@
|
||||||
package sbt
|
package sbt
|
||||||
package internal
|
package internal
|
||||||
import java.lang
|
import java.lang
|
||||||
|
import java.nio.file.Path
|
||||||
import java.util.Optional
|
import java.util.Optional
|
||||||
|
|
||||||
import sbt.internal.inc.{ EmptyStamp, LastModified, Stamp }
|
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 }
|
import xsbti.compile.analysis.{ Stamp => XStamp }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -23,7 +25,33 @@ trait FileCacheEntry {
|
||||||
def lastModified: Option[Long]
|
def lastModified: Option[Long]
|
||||||
}
|
}
|
||||||
object FileCacheEntry {
|
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))
|
DelegateFileCacheEntry(Stamped.converter(typedPath))
|
||||||
private[sbt] implicit class FileCacheEntryOps(val e: FileCacheEntry) extends AnyVal {
|
private[sbt] implicit class FileCacheEntryOps(val e: FileCacheEntry) extends AnyVal {
|
||||||
private[sbt] def stamp: XStamp = e match {
|
private[sbt] def stamp: XStamp = e match {
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ import org.scalatest.{ FlatSpec, Matchers }
|
||||||
import sbt.Watched._
|
import sbt.Watched._
|
||||||
import sbt.WatchedSpec._
|
import sbt.WatchedSpec._
|
||||||
import sbt.internal.FileCacheEntry
|
import sbt.internal.FileCacheEntry
|
||||||
import sbt.io.FileEventMonitor.Event
|
|
||||||
import sbt.io._
|
import sbt.io._
|
||||||
import sbt.io.syntax._
|
import sbt.io.syntax._
|
||||||
import sbt.util.Logger
|
import sbt.util.Logger
|
||||||
|
|
@ -31,7 +30,7 @@ class WatchedSpec extends FlatSpec with Matchers {
|
||||||
logger: Logger = NullLogger,
|
logger: Logger = NullLogger,
|
||||||
handleInput: InputStream => Action = _ => Ignore,
|
handleInput: InputStream => Action = _ => Ignore,
|
||||||
preWatch: (Int, Boolean) => Action = (_, _) => CancelWatch,
|
preWatch: (Int, Boolean) => Action = (_, _) => CancelWatch,
|
||||||
onWatchEvent: Event[FileCacheEntry] => Action = _ => Ignore,
|
onWatchEvent: FileCacheEntry.Event => Action = _ => Ignore,
|
||||||
triggeredMessage: (Path, Int) => Option[String] = (_, _) => None,
|
triggeredMessage: (Path, Int) => Option[String] = (_, _) => None,
|
||||||
watchingMessage: Int => Option[String] = _ => None
|
watchingMessage: Int => Option[String] = _ => None
|
||||||
): WatchConfig = {
|
): WatchConfig = {
|
||||||
|
|
@ -87,7 +86,7 @@ class WatchedSpec extends FlatSpec with Matchers {
|
||||||
val config = Defaults.config(
|
val config = Defaults.config(
|
||||||
globs = Seq(realDir ** AllPassFilter),
|
globs = Seq(realDir ** AllPassFilter),
|
||||||
preWatch = (count, _) => if (count == 2) CancelWatch else Ignore,
|
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 },
|
triggeredMessage = (tp, _) => { queue += tp; None },
|
||||||
watchingMessage = _ => { Files.createFile(bar); Thread.sleep(5); Files.createFile(foo); 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.librarymanagement.{ CompatibilityWarningOptions, IvySbt }
|
||||||
import sbt.internal.server.ServerHandler
|
import sbt.internal.server.ServerHandler
|
||||||
import sbt.internal.util.{ AttributeKey, SourcePosition }
|
import sbt.internal.util.{ AttributeKey, SourcePosition }
|
||||||
import sbt.io.FileEventMonitor.Event
|
|
||||||
import sbt.io._
|
import sbt.io._
|
||||||
import sbt.librarymanagement.Configurations.CompilerPlugin
|
import sbt.librarymanagement.Configurations.CompilerPlugin
|
||||||
import sbt.librarymanagement.LibraryManagementCodec._
|
import sbt.librarymanagement.LibraryManagementCodec._
|
||||||
|
|
@ -102,7 +101,7 @@ object Keys {
|
||||||
val watchConfig = taskKey[WatchConfig]("The configuration for continuous execution.").withRank(BMinusSetting)
|
val watchConfig = taskKey[WatchConfig]("The configuration for continuous execution.").withRank(BMinusSetting)
|
||||||
val watchLogger = taskKey[Logger]("A logger that reports watch events.").withRank(DSetting)
|
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 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 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 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)
|
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