mirror of https://github.com/sbt/sbt.git
Add watchPersistFileStamps key
The persistentFileStampCache does seem to work pretty well but in case users encounter issues, I add a boolean flag that allows the user to turn this behavior off and always re-stamp every source file in every task evaluation run.
This commit is contained in:
parent
ec09e73437
commit
4007810adb
|
|
@ -153,6 +153,7 @@ object Defaults extends BuildCommon {
|
|||
inputFileStamper :== sbt.nio.FileStamper.Hash,
|
||||
outputFileStamper :== sbt.nio.FileStamper.LastModified,
|
||||
watchForceTriggerOnAnyChange :== true,
|
||||
watchPersistFileStamps :== true,
|
||||
watchTriggers :== Nil,
|
||||
clean := { () },
|
||||
sbt.nio.Keys.fileStampCache := {
|
||||
|
|
|
|||
|
|
@ -291,20 +291,22 @@ private[sbt] object Continuous extends DeprecatedContinuous {
|
|||
} else {
|
||||
FileTreeRepository.default
|
||||
}
|
||||
val attributeMap = new FileStamp.Cache
|
||||
repo.addObserver(t => attributeMap.invalidate(t.path))
|
||||
val fileStampCache = new FileStamp.Cache
|
||||
repo.addObserver(t => fileStampCache.invalidate(t.path))
|
||||
try {
|
||||
val stateWithRepo = state
|
||||
.put(globalFileTreeRepository, repo)
|
||||
.put(persistentFileStampCache, attributeMap)
|
||||
setup(stateWithRepo, command) { (commands, s, valid, invalid) =>
|
||||
val stateWithRepo = state.put(globalFileTreeRepository, repo)
|
||||
val fullState =
|
||||
if (extracted.get(watchPersistFileStamps))
|
||||
stateWithRepo.put(persistentFileStampCache, fileStampCache)
|
||||
else stateWithRepo
|
||||
setup(fullState, command) { (commands, s, valid, invalid) =>
|
||||
EvaluateTask.withStreams(extracted.structure, s)(_.use(streams in Global) { streams =>
|
||||
implicit val logger: Logger = streams.log
|
||||
if (invalid.isEmpty) {
|
||||
val currentCount = new AtomicInteger(count)
|
||||
val configs = getAllConfigs(valid.map(v => v._1 -> v._2))
|
||||
val callbacks =
|
||||
aggregate(configs, logger, in, s, currentCount, isCommand, commands, attributeMap)
|
||||
aggregate(configs, logger, in, s, currentCount, isCommand, commands, fileStampCache)
|
||||
val task = () => {
|
||||
currentCount.getAndIncrement()
|
||||
// abort as soon as one of the tasks fails
|
||||
|
|
@ -401,7 +403,7 @@ private[sbt] object Continuous extends DeprecatedContinuous {
|
|||
count: AtomicInteger,
|
||||
isCommand: Boolean,
|
||||
commands: Seq[String],
|
||||
attributeMap: FileStamp.Cache
|
||||
fileStampCache: FileStamp.Cache
|
||||
)(
|
||||
implicit extracted: Extracted
|
||||
): Callbacks = {
|
||||
|
|
@ -411,7 +413,7 @@ private[sbt] object Continuous extends DeprecatedContinuous {
|
|||
val onStart: () => Watch.Action = getOnStart(project, commands, configs, rawLogger, count)
|
||||
val nextInputEvent: () => Watch.Action = parseInputEvents(configs, state, inputStream, logger)
|
||||
val (nextFileEvent, cleanupFileMonitor): (() => Option[(Watch.Event, Watch.Action)], () => Unit) =
|
||||
getFileEvents(configs, rawLogger, state, count, commands, attributeMap)
|
||||
getFileEvents(configs, rawLogger, state, count, commands, fileStampCache)
|
||||
val nextEvent: () => Watch.Action =
|
||||
combineInputAndFileEvents(nextInputEvent, nextFileEvent, logger)
|
||||
val onExit = () => {
|
||||
|
|
@ -476,7 +478,7 @@ private[sbt] object Continuous extends DeprecatedContinuous {
|
|||
state: State,
|
||||
count: AtomicInteger,
|
||||
commands: Seq[String],
|
||||
attributeMap: FileStamp.Cache
|
||||
fileStampCache: FileStamp.Cache
|
||||
)(implicit extracted: Extracted): (() => Option[(Watch.Event, Watch.Action)], () => Unit) = {
|
||||
val trackMetaBuild = configs.forall(_.watchSettings.trackMetaBuild)
|
||||
val buildGlobs =
|
||||
|
|
@ -491,7 +493,7 @@ private[sbt] object Continuous extends DeprecatedContinuous {
|
|||
def watchEvent(stamper: FileStamper, forceTrigger: Boolean): Option[Watch.Event] = {
|
||||
if (!event.exists) {
|
||||
Some(Deletion(event))
|
||||
attributeMap.remove(event.path) match {
|
||||
fileStampCache.remove(event.path) match {
|
||||
case null => None
|
||||
case _ => Some(Deletion(event))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,6 +85,9 @@ object Keys {
|
|||
val watchOnTermination = settingKey[(Watch.Action, String, Int, State) => State](
|
||||
"Transforms the state upon completion of a watch. The String argument is the command that was run during the watch. The Int parameter specifies how many times the command was run during the watch."
|
||||
).withRank(DSetting)
|
||||
val watchPersistFileStamps = settingKey[Boolean](
|
||||
"Toggles whether or not the continuous build will reuse the file stamps computed in previous runs. Setting this to true decrease watch startup latency but could cause inconsistent results if many source files are concurrently modified."
|
||||
).withRank(DSetting)
|
||||
val watchStartMessage = settingKey[(Int, String, Seq[String]) => Option[String]](
|
||||
"The message to show when triggered execution waits for sources to change. The parameters are the current watch iteration count, the current project name and the tasks that are being run with each build."
|
||||
).withRank(DSetting)
|
||||
|
|
|
|||
Loading…
Reference in New Issue