mirror of https://github.com/sbt/sbt.git
Add FileCacheEntry
Previously, we were leaking the internal details of incremental compilation to users by defining FileTree(DataView|Repository)[Stamp]. To avoid this, I introduce the new class FileCacheEntry that is quite similar to Stamp except defined using scala Options rather than java Optionals. The implementation class just delegates to an actual Stamp and I provided a private[sbt] ops class that adds a method `stamp` to FileCacheEntry. This will usually just extract the stamp from the implementation class. This allows us to use FileCacheEntry almost interchangeably with Stamp while still avoiding exposing users to Stamp.
This commit is contained in:
parent
ba0494df14
commit
e8af828c73
|
|
@ -9,13 +9,11 @@ package sbt
|
|||
|
||||
import java.io.File
|
||||
|
||||
import sbt.internal.util.AttributeKey
|
||||
import sbt.internal.inc.classpath.ClassLoaderCache
|
||||
import sbt.internal.server.ServerHandler
|
||||
import sbt.io.FileTreeDataView
|
||||
import sbt.internal.util.AttributeKey
|
||||
import sbt.librarymanagement.ModuleID
|
||||
import sbt.util.Level
|
||||
import xsbti.compile.analysis.Stamp
|
||||
|
||||
object BasicKeys {
|
||||
val historyPath = AttributeKey[Option[File]](
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@
|
|||
|
||||
package sbt
|
||||
import sbt.Watched.WatchSource
|
||||
import sbt.internal.FileCacheEntry
|
||||
import sbt.internal.io.{ HybridPollingFileTreeRepository, WatchServiceBackedObservable, WatchState }
|
||||
import sbt.io.FileTreeDataView.{ Observable, Observer }
|
||||
import sbt.io._
|
||||
import FileTreeDataView.{ Observable, Observer }
|
||||
import sbt.util.Logger
|
||||
import xsbti.compile.analysis.Stamp
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
|
|
@ -19,15 +19,15 @@ import scala.concurrent.duration._
|
|||
* Configuration for viewing and monitoring the file system.
|
||||
*/
|
||||
final class FileTreeViewConfig private (
|
||||
val newDataView: () => FileTreeDataView[Stamp],
|
||||
val newDataView: () => FileTreeDataView[FileCacheEntry],
|
||||
val newMonitor: (
|
||||
FileTreeDataView[Stamp],
|
||||
FileTreeDataView[FileCacheEntry],
|
||||
Seq[WatchSource],
|
||||
Logger
|
||||
) => FileEventMonitor[Stamp]
|
||||
) => FileEventMonitor[FileCacheEntry]
|
||||
)
|
||||
object FileTreeViewConfig {
|
||||
private implicit class RepositoryOps(val repository: FileTreeRepository[Stamp]) {
|
||||
private implicit class RepositoryOps(val repository: FileTreeRepository[FileCacheEntry]) {
|
||||
def register(sources: Seq[WatchSource]): Unit = sources foreach { s =>
|
||||
repository.register(s.base.toPath, if (s.recursive) Integer.MAX_VALUE else 0)
|
||||
}
|
||||
|
|
@ -35,10 +35,10 @@ object FileTreeViewConfig {
|
|||
|
||||
/**
|
||||
* Create a new FileTreeViewConfig. This factory takes a generic parameter, T, that is bounded
|
||||
* by {{{sbt.io.FileTreeDataView[Stamp]}}}. The reason for this is to ensure that a
|
||||
* by {{{sbt.io.FileTreeDataView[FileCacheEntry]}}}. The reason for this is to ensure that a
|
||||
* sbt.io.FileTreeDataView that is instantiated by [[FileTreeViewConfig.newDataView]] can be
|
||||
* passed into [[FileTreeViewConfig.newMonitor]] without constraining the type of view to be
|
||||
* {{{sbt.io.FileTreeDataView[Stamp]}}}.
|
||||
* {{{sbt.io.FileTreeDataView[FileCacheEntry]}}}.
|
||||
* @param newDataView create a new sbt.io.FileTreeDataView. This value may be cached in a global
|
||||
* attribute
|
||||
* @param newMonitor create a new sbt.io.FileEventMonitor using the sbt.io.FileTreeDataView
|
||||
|
|
@ -46,13 +46,13 @@ object FileTreeViewConfig {
|
|||
* @tparam T the subtype of sbt.io.FileTreeDataView that is returned by [[FileTreeViewConfig.newDataView]]
|
||||
* @return a [[FileTreeViewConfig]] instance.
|
||||
*/
|
||||
def apply[T <: FileTreeDataView[Stamp]](
|
||||
def apply[T <: FileTreeDataView[FileCacheEntry]](
|
||||
newDataView: () => T,
|
||||
newMonitor: (T, Seq[WatchSource], Logger) => FileEventMonitor[Stamp]
|
||||
newMonitor: (T, Seq[WatchSource], Logger) => FileEventMonitor[FileCacheEntry]
|
||||
): FileTreeViewConfig =
|
||||
new FileTreeViewConfig(
|
||||
newDataView,
|
||||
(view: FileTreeDataView[Stamp], sources: Seq[WatchSource], logger: Logger) =>
|
||||
(view: FileTreeDataView[FileCacheEntry], sources: Seq[WatchSource], logger: Logger) =>
|
||||
newMonitor(view.asInstanceOf[T], sources, logger)
|
||||
)
|
||||
|
||||
|
|
@ -71,14 +71,14 @@ object FileTreeViewConfig {
|
|||
antiEntropy: FiniteDuration
|
||||
): FileTreeViewConfig =
|
||||
FileTreeViewConfig(
|
||||
() => FileTreeView.DEFAULT.asDataView(Stamped.converter),
|
||||
(_: FileTreeDataView[Stamp], sources, logger) => {
|
||||
() => FileTreeView.DEFAULT.asDataView(FileCacheEntry.default),
|
||||
(_: FileTreeDataView[FileCacheEntry], sources, logger) => {
|
||||
val ioLogger: sbt.io.WatchLogger = msg => logger.debug(msg.toString)
|
||||
FileEventMonitor.antiEntropy(
|
||||
new WatchServiceBackedObservable(
|
||||
WatchState.empty(Watched.createWatchService(), sources),
|
||||
delay,
|
||||
Stamped.converter,
|
||||
FileCacheEntry.default,
|
||||
closeService = true,
|
||||
ioLogger
|
||||
),
|
||||
|
|
@ -98,11 +98,15 @@ object FileTreeViewConfig {
|
|||
*/
|
||||
def default(antiEntropy: FiniteDuration): FileTreeViewConfig =
|
||||
FileTreeViewConfig(
|
||||
() => FileTreeRepository.default(Stamped.converter),
|
||||
(repository: FileTreeRepository[Stamp], sources: Seq[WatchSource], logger: Logger) => {
|
||||
() => FileTreeRepository.default(FileCacheEntry.default),
|
||||
(
|
||||
repository: FileTreeRepository[FileCacheEntry],
|
||||
sources: Seq[WatchSource],
|
||||
logger: Logger
|
||||
) => {
|
||||
repository.register(sources)
|
||||
val copied = new Observable[Stamp] {
|
||||
override def addObserver(observer: Observer[Stamp]): Int =
|
||||
val copied = new Observable[FileCacheEntry] {
|
||||
override def addObserver(observer: Observer[FileCacheEntry]): Int =
|
||||
repository.addObserver(observer)
|
||||
override def removeObserver(handle: Int): Unit = repository.removeObserver(handle)
|
||||
override def close(): Unit = {} // Don't close the underlying observable
|
||||
|
|
@ -155,9 +159,9 @@ object FileTreeViewConfig {
|
|||
pollingInterval: FiniteDuration,
|
||||
pollingSources: Seq[WatchSource],
|
||||
): FileTreeViewConfig = FileTreeViewConfig(
|
||||
() => FileTreeRepository.hybrid(Stamped.converter, pollingSources: _*),
|
||||
() => FileTreeRepository.hybrid(FileCacheEntry.default, pollingSources: _*),
|
||||
(
|
||||
repository: HybridPollingFileTreeRepository[Stamp],
|
||||
repository: HybridPollingFileTreeRepository[FileCacheEntry],
|
||||
sources: Seq[WatchSource],
|
||||
logger: Logger
|
||||
) => {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ package sbt
|
|||
import java.io.{ File => JFile }
|
||||
import java.nio.file.Path
|
||||
|
||||
import sbt.internal.FileCacheEntry
|
||||
import sbt.internal.inc.Stamper
|
||||
import sbt.io.TypedPath
|
||||
import xsbti.compile.analysis.Stamp
|
||||
|
|
@ -20,17 +21,17 @@ import xsbti.compile.analysis.Stamp
|
|||
* performance anywhere where we need to check if files have changed before doing potentially
|
||||
* expensive work.
|
||||
*/
|
||||
trait Stamped {
|
||||
def stamp: Stamp
|
||||
private[sbt] trait Stamped {
|
||||
private[sbt] def stamp: Stamp
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides converter functions from TypedPath to [[Stamped]].
|
||||
*/
|
||||
object Stamped {
|
||||
private[sbt] object Stamped {
|
||||
type File = JFile with Stamped with TypedPath
|
||||
def file(typedPath: TypedPath, stamp: Stamp): JFile with Stamped with TypedPath =
|
||||
new StampedFileImpl(typedPath, stamp)
|
||||
def file(typedPath: TypedPath, entry: FileCacheEntry): JFile with Stamped with TypedPath =
|
||||
new StampedFileImpl(typedPath, entry.stamp)
|
||||
|
||||
/**
|
||||
* Converts a TypedPath instance to a [[Stamped]] by calculating the file hash.
|
||||
|
|
@ -47,10 +48,13 @@ object Stamped {
|
|||
* using the last modified time and all other files using the file hash.
|
||||
*/
|
||||
val converter: TypedPath => Stamp = (tp: TypedPath) =>
|
||||
tp.toPath.toString match {
|
||||
case s if s.endsWith(".jar") => binaryConverter(tp)
|
||||
case s if s.endsWith(".class") => binaryConverter(tp)
|
||||
case _ => sourceConverter(tp)
|
||||
if (tp.isDirectory) binaryConverter(tp)
|
||||
else {
|
||||
tp.toPath.toString match {
|
||||
case s if s.endsWith(".jar") => binaryConverter(tp)
|
||||
case s if s.endsWith(".class") => binaryConverter(tp)
|
||||
case _ => sourceConverter(tp)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -18,15 +18,14 @@ import sbt.BasicCommandStrings.{
|
|||
}
|
||||
import sbt.BasicCommands.otherCommandParser
|
||||
import sbt.internal.LabeledFunctions._
|
||||
import sbt.internal.LegacyWatched
|
||||
import sbt.internal.io.{ EventMonitor, Source, WatchState }
|
||||
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 }
|
||||
import xsbti.compile.analysis.Stamp
|
||||
|
||||
import scala.annotation.tailrec
|
||||
import scala.concurrent.duration._
|
||||
|
|
@ -147,7 +146,7 @@ object Watched {
|
|||
private[sbt] def onEvent(
|
||||
sources: Seq[WatchSource],
|
||||
projectSources: Seq[WatchSource]
|
||||
): Event[Stamp] => Watched.Action =
|
||||
): Event[FileCacheEntry] => Watched.Action =
|
||||
event =>
|
||||
if (sources.exists(_.accept(event.entry.typedPath.toPath))) Watched.Trigger
|
||||
else if (projectSources.exists(_.accept(event.entry.typedPath.toPath))) event match {
|
||||
|
|
@ -459,7 +458,7 @@ trait WatchConfig {
|
|||
*
|
||||
* @return an sbt.io.FileEventMonitor instance.
|
||||
*/
|
||||
def fileEventMonitor: FileEventMonitor[Stamp]
|
||||
def fileEventMonitor: FileEventMonitor[FileCacheEntry]
|
||||
|
||||
/**
|
||||
* A function that is periodically invoked to determine whether the watch should stop or
|
||||
|
|
@ -482,7 +481,7 @@ trait WatchConfig {
|
|||
* @param event the detected sbt.io.FileEventMonitor.Event.
|
||||
* @return the next [[Watched.Action Action]] to run.
|
||||
*/
|
||||
def onWatchEvent(event: Event[Stamp]): Watched.Action
|
||||
def onWatchEvent(event: Event[FileCacheEntry]): Watched.Action
|
||||
|
||||
/**
|
||||
* Transforms the state after the watch terminates.
|
||||
|
|
@ -538,10 +537,10 @@ object WatchConfig {
|
|||
*/
|
||||
def default(
|
||||
logger: Logger,
|
||||
fileEventMonitor: FileEventMonitor[Stamp],
|
||||
fileEventMonitor: FileEventMonitor[FileCacheEntry],
|
||||
handleInput: InputStream => Watched.Action,
|
||||
preWatch: (Int, Boolean) => Watched.Action,
|
||||
onWatchEvent: Event[Stamp] => Watched.Action,
|
||||
onWatchEvent: Event[FileCacheEntry] => Watched.Action,
|
||||
onWatchTerminated: (Watched.Action, String, State) => State,
|
||||
triggeredMessage: (TypedPath, Int) => Option[String],
|
||||
watchingMessage: Int => Option[String]
|
||||
|
|
@ -556,11 +555,11 @@ object WatchConfig {
|
|||
val wm = watchingMessage
|
||||
new WatchConfig {
|
||||
override def logger: Logger = l
|
||||
override def fileEventMonitor: FileEventMonitor[Stamp] = fem
|
||||
override def fileEventMonitor: FileEventMonitor[FileCacheEntry] = fem
|
||||
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[Stamp]): Watched.Action = owe(event)
|
||||
override def onWatchEvent(event: Event[FileCacheEntry]): Watched.Action = owe(event)
|
||||
override def onWatchTerminated(action: Watched.Action, command: String, state: State): State =
|
||||
owt(action, command, state)
|
||||
override def triggeredMessage(typedPath: TypedPath, count: Int): Option[String] =
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* sbt
|
||||
* Copyright 2011 - 2018, Lightbend, Inc.
|
||||
* Copyright 2008 - 2010, Mark Harrah
|
||||
* Licensed under Apache License 2.0 (see LICENSE)
|
||||
*/
|
||||
|
||||
package sbt
|
||||
package internal
|
||||
import java.lang
|
||||
import java.util.Optional
|
||||
|
||||
import sbt.internal.inc.{ EmptyStamp, LastModified, Stamp }
|
||||
import sbt.io.TypedPath
|
||||
import xsbti.compile.analysis.{ Stamp => XStamp }
|
||||
|
||||
/**
|
||||
* Represents a cache entry for a FileTreeRepository. It can be extended to add user defined
|
||||
* data to the FileTreeRepository cache.
|
||||
*/
|
||||
trait FileCacheEntry {
|
||||
def hash: Option[String]
|
||||
def lastModified: Option[Long]
|
||||
}
|
||||
object FileCacheEntry {
|
||||
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 {
|
||||
case DelegateFileCacheEntry(s) => s
|
||||
case _ =>
|
||||
e.hash
|
||||
.map(Stamp.fromString)
|
||||
.orElse(e.lastModified.map(new LastModified(_)))
|
||||
.getOrElse(EmptyStamp)
|
||||
}
|
||||
}
|
||||
|
||||
private case class DelegateFileCacheEntry(private val stamp: XStamp)
|
||||
extends FileCacheEntry
|
||||
with XStamp {
|
||||
override def getValueId: Int = stamp.getValueId
|
||||
override def writeStamp(): String = stamp.writeStamp()
|
||||
override def getHash: Optional[String] = stamp.getHash
|
||||
override def getLastModified: Optional[lang.Long] = stamp.getLastModified
|
||||
override def hash: Option[String] = getHash match {
|
||||
case h if h.isPresent => Some(h.get)
|
||||
case _ => None
|
||||
}
|
||||
override def lastModified: Option[Long] = getLastModified match {
|
||||
case l if l.isPresent => Some(l.get)
|
||||
case _ => None
|
||||
}
|
||||
override def equals(o: Any): Boolean = o match {
|
||||
case that: DelegateFileCacheEntry => this.stamp == that.stamp
|
||||
case that: XStamp => this.stamp == that
|
||||
case _ => false
|
||||
}
|
||||
override def hashCode: Int = stamp.hashCode
|
||||
override def toString: String = s"FileCacheEntry(hash = $hash, lastModified = $lastModified)"
|
||||
}
|
||||
}
|
||||
|
|
@ -14,10 +14,10 @@ import java.util.concurrent.atomic.AtomicBoolean
|
|||
import org.scalatest.{ FlatSpec, Matchers }
|
||||
import sbt.Watched._
|
||||
import sbt.WatchedSpec._
|
||||
import sbt.internal.FileCacheEntry
|
||||
import sbt.io.FileEventMonitor.Event
|
||||
import sbt.io.{ FileEventMonitor, IO, TypedPath }
|
||||
import sbt.util.Logger
|
||||
import xsbti.compile.analysis.Stamp
|
||||
|
||||
import scala.collection.mutable
|
||||
import scala.concurrent.duration._
|
||||
|
|
@ -27,11 +27,11 @@ class WatchedSpec extends FlatSpec with Matchers {
|
|||
private val fileTreeViewConfig = FileTreeViewConfig.default(50.millis)
|
||||
def config(
|
||||
sources: Seq[WatchSource],
|
||||
fileEventMonitor: Option[FileEventMonitor[Stamp]] = None,
|
||||
fileEventMonitor: Option[FileEventMonitor[FileCacheEntry]] = None,
|
||||
logger: Logger = NullLogger,
|
||||
handleInput: InputStream => Action = _ => Ignore,
|
||||
preWatch: (Int, Boolean) => Action = (_, _) => CancelWatch,
|
||||
onWatchEvent: Event[Stamp] => Action = _ => Ignore,
|
||||
onWatchEvent: Event[FileCacheEntry] => Action = _ => Ignore,
|
||||
triggeredMessage: (TypedPath, Int) => Option[String] = (_, _) => None,
|
||||
watchingMessage: Int => Option[String] = _ => None
|
||||
): WatchConfig = {
|
||||
|
|
|
|||
|
|
@ -274,7 +274,7 @@ object Defaults extends BuildCommon {
|
|||
fileTreeViewConfig := FileManagement.defaultFileTreeView.value,
|
||||
fileTreeView := state.value
|
||||
.get(Keys.globalFileTreeView)
|
||||
.getOrElse(FileTreeView.DEFAULT.asDataView(Stamped.converter)),
|
||||
.getOrElse(FileTreeView.DEFAULT.asDataView(FileCacheEntry.default)),
|
||||
externalHooks := {
|
||||
val view = fileTreeView.value
|
||||
compileOptions =>
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ import sbt.librarymanagement.ivy.{ Credentials, IvyConfiguration, IvyPaths, Upda
|
|||
import sbt.testing.Framework
|
||||
import sbt.util.{ Level, Logger }
|
||||
import xsbti.compile._
|
||||
import xsbti.compile.analysis.Stamp
|
||||
|
||||
import scala.concurrent.duration.{ Duration, FiniteDuration }
|
||||
import scala.xml.{ NodeSeq, Node => XNode }
|
||||
|
|
@ -94,14 +93,14 @@ object Keys {
|
|||
@deprecated("This is no longer used for continuous execution", "1.3.0")
|
||||
val watch = SettingKey(BasicKeys.watch)
|
||||
val suppressSbtShellNotification = settingKey[Boolean]("""True to suppress the "Executing in batch mode.." message.""").withRank(CSetting)
|
||||
val fileTreeView = taskKey[FileTreeDataView[Stamp]]("A view of the file system")
|
||||
val fileTreeView = taskKey[FileTreeDataView[FileCacheEntry]]("A view of the file system")
|
||||
val pollInterval = settingKey[FiniteDuration]("Interval between checks for modified sources by the continuous execution command.").withRank(BMinusSetting)
|
||||
val pollingDirectories = settingKey[Seq[Watched.WatchSource]]("Directories that cannot be cached and must always be rescanned. Typically these will be NFS mounted or something similar.").withRank(DSetting)
|
||||
val watchAntiEntropy = settingKey[FiniteDuration]("Duration for which the watch EventMonitor will ignore events for a file after that file has triggered a build.").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 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[Stamp] => Watched.Action]("Determines how to handle a file event").withRank(BMinusSetting)
|
||||
val watchOnEvent = taskKey[Event[FileCacheEntry] => 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)
|
||||
|
|
@ -457,7 +456,7 @@ object Keys {
|
|||
val (executionRoots, dummyRoots) = Def.dummy[Seq[ScopedKey[_]]]("executionRoots", "The list of root tasks for this task execution. Roots are the top-level tasks that were directly requested to be run.")
|
||||
val state = Def.stateKey
|
||||
val streamsManager = Def.streamsManagerKey
|
||||
private[sbt] val globalFileTreeView = AttributeKey[FileTreeDataView[Stamp]](
|
||||
private[sbt] val globalFileTreeView = AttributeKey[FileTreeDataView[FileCacheEntry]](
|
||||
"globalFileTreeView",
|
||||
"Provides a view into the file system that may or may not cache the tree in memory",
|
||||
1000
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ import sbt.io.syntax._
|
|||
import sbt.io.{ FileTreeDataView, IO }
|
||||
import sbt.util.{ Level, Logger, Show }
|
||||
import xsbti.compile.CompilerCache
|
||||
import xsbti.compile.analysis.Stamp
|
||||
|
||||
import scala.annotation.tailrec
|
||||
import scala.concurrent.ExecutionContext
|
||||
|
|
@ -863,7 +862,7 @@ object BuiltinCommands {
|
|||
()
|
||||
}
|
||||
val (_, config: FileTreeViewConfig) = extracted.runTask(Keys.fileTreeViewConfig, s)
|
||||
val view: FileTreeDataView[Stamp] = config.newDataView()
|
||||
val view: FileTreeDataView[FileCacheEntry] = config.newDataView()
|
||||
val newState = s.addExitHook(cleanup())
|
||||
cleanup()
|
||||
newState
|
||||
|
|
|
|||
|
|
@ -20,7 +20,10 @@ import scala.collection.mutable
|
|||
|
||||
private[sbt] object ExternalHooks {
|
||||
private val javaHome = Option(System.getProperty("java.home")).map(Paths.get(_))
|
||||
def apply(options: CompileOptions, view: FileTreeDataView[Stamp]): DefaultExternalHooks = {
|
||||
def apply(
|
||||
options: CompileOptions,
|
||||
view: FileTreeDataView[FileCacheEntry]
|
||||
): DefaultExternalHooks = {
|
||||
import scala.collection.JavaConverters._
|
||||
val sources = options.sources()
|
||||
val cachedSources = new java.util.HashMap[File, Stamp]
|
||||
|
|
@ -30,7 +33,7 @@ private[sbt] object ExternalHooks {
|
|||
case f: File => cachedSources.put(f, converter(f))
|
||||
}
|
||||
view match {
|
||||
case r: FileTreeRepository[Stamp] =>
|
||||
case r: FileTreeRepository[FileCacheEntry] =>
|
||||
r.register(options.classesDirectory.toPath, Integer.MAX_VALUE)
|
||||
options.classpath.foreach { f =>
|
||||
r.register(f.toPath, Integer.MAX_VALUE)
|
||||
|
|
@ -41,7 +44,7 @@ private[sbt] object ExternalHooks {
|
|||
options.classpath.foreach { f =>
|
||||
view.listEntries(f.toPath, Integer.MAX_VALUE, _ => true) foreach { e =>
|
||||
e.value match {
|
||||
case Right(value) => allBinaries.put(e.typedPath.toPath.toFile, value)
|
||||
case Right(value) => allBinaries.put(e.typedPath.toPath.toFile, value.stamp)
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
|
|
@ -49,7 +52,7 @@ private[sbt] object ExternalHooks {
|
|||
// rather than a directory.
|
||||
view.listEntries(f.toPath, -1, _ => true) foreach { e =>
|
||||
e.value match {
|
||||
case Right(value) => allBinaries.put(e.typedPath.toPath.toFile, value)
|
||||
case Right(value) => allBinaries.put(e.typedPath.toPath.toFile, value.stamp)
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,13 +10,12 @@ package sbt.internal
|
|||
import java.io.IOException
|
||||
import java.nio.file.Path
|
||||
|
||||
import sbt.BasicCommandStrings.ContinuousExecutePrefix
|
||||
import sbt.Keys._
|
||||
import sbt._
|
||||
import sbt.io.FileTreeDataView.Entry
|
||||
import sbt.io.syntax.File
|
||||
import sbt.io.{ FileFilter, FileTreeDataView, FileTreeRepository }
|
||||
import sbt._
|
||||
import BasicCommandStrings.ContinuousExecutePrefix
|
||||
import xsbti.compile.analysis.Stamp
|
||||
|
||||
private[sbt] object FileManagement {
|
||||
private[sbt] def defaultFileTreeView: Def.Initialize[Task[FileTreeViewConfig]] = Def.task {
|
||||
|
|
@ -52,7 +51,7 @@ private[sbt] object FileManagement {
|
|||
val view = fileTreeView.value
|
||||
val include = filter.toTask.value
|
||||
val ex = excludes.toTask.value
|
||||
val sourceFilter: Entry[Stamp] => Boolean = (entry: Entry[Stamp]) => {
|
||||
val sourceFilter: Entry[FileCacheEntry] => Boolean = (entry: Entry[FileCacheEntry]) => {
|
||||
val typedPath = entry.typedPath
|
||||
val file = new java.io.File(typedPath.toPath.toString) {
|
||||
override def isDirectory: Boolean = typedPath.isDirectory
|
||||
|
|
|
|||
Loading…
Reference in New Issue