mirror of https://github.com/sbt/sbt.git
Moved type parameter for FileInfo(s).Style to abstract type
This commit is contained in:
parent
6e414e96c5
commit
74adf5d9f6
|
|
@ -2,6 +2,7 @@ package xsbt
|
||||||
|
|
||||||
import sbinary.{CollectionTypes, Format, JavaFormats, Operations}
|
import sbinary.{CollectionTypes, Format, JavaFormats, Operations}
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import scala.reflect.Manifest
|
||||||
|
|
||||||
trait Cache[I,O]
|
trait Cache[I,O]
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,138 +1,5 @@
|
||||||
package xsbt
|
package xsbt
|
||||||
|
|
||||||
import java.io.File
|
|
||||||
import CacheIO.{fromFile, toFile}
|
|
||||||
import sbinary.Format
|
|
||||||
import scala.reflect.Manifest
|
|
||||||
|
|
||||||
trait Tracked extends NotNull
|
|
||||||
{
|
|
||||||
def clear: Task[Unit]
|
|
||||||
def clean: Task[Unit]
|
|
||||||
}
|
|
||||||
|
|
||||||
class Changed[O](val task: Task[O], val file: File)(implicit input: InputCache[O]) extends Tracked
|
|
||||||
{
|
|
||||||
def clean = Task.empty
|
|
||||||
def clear = Clean(file)
|
|
||||||
def apply[O2](ifChanged: O => O2, ifUnchanged: O => O2): Task[O2] { type Input = O } =
|
|
||||||
task map { value =>
|
|
||||||
val cache = OpenResource.fileInputStream(file)(input.uptodate(value))
|
|
||||||
if(cache.uptodate)
|
|
||||||
ifUnchanged(value)
|
|
||||||
else
|
|
||||||
{
|
|
||||||
OpenResource.fileOutputStream(false)(file)(cache.update)
|
|
||||||
ifChanged(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
class Difference[F <: FileInfo](val filesTask: Task[Set[File]], val style: FilesInfo.Style[F], val cache: File, val shouldClean: Boolean)(implicit mf: Manifest[F]) extends Tracked
|
|
||||||
{
|
|
||||||
def this(filesTask: Task[Set[File]], style: FilesInfo.Style[F], cache: File)(implicit mf: Manifest[F]) = this(filesTask, style, cache, false)
|
|
||||||
def this(files: Set[File], style: FilesInfo.Style[F], cache: File, shouldClean: Boolean)(implicit mf: Manifest[F]) = this(Task(files), style, cache)
|
|
||||||
def this(files: Set[File], style: FilesInfo.Style[F], cache: File)(implicit mf: Manifest[F]) = this(Task(files), style, cache, false)
|
|
||||||
|
|
||||||
val clear = Clean(cache)
|
|
||||||
val clean = if(shouldClean) cleanTask else Task.empty
|
|
||||||
def cleanTask = Clean(Task(raw(cachedFilesInfo)))
|
|
||||||
|
|
||||||
private def cachedFilesInfo = fromFile(style.formats)(cache).files
|
|
||||||
private def raw(fs: Set[F]): Set[File] = fs.map(_.file)
|
|
||||||
|
|
||||||
def apply[T](f: ChangeReport[File] => Task[T]): Task[T] =
|
|
||||||
filesTask bind { files =>
|
|
||||||
val lastFilesInfo = cachedFilesInfo
|
|
||||||
val lastFiles = raw(lastFilesInfo)
|
|
||||||
val currentFiles = files.map(_.getAbsoluteFile)
|
|
||||||
val currentFilesInfo = style(files)
|
|
||||||
|
|
||||||
val report = new ChangeReport[File]
|
|
||||||
{
|
|
||||||
lazy val allInputs = currentFiles
|
|
||||||
lazy val removed = lastFiles -- allInputs
|
|
||||||
lazy val added = allInputs -- lastFiles
|
|
||||||
lazy val modified = raw(lastFilesInfo -- currentFilesInfo.files)
|
|
||||||
lazy val unmodified = allInputs -- modified
|
|
||||||
}
|
|
||||||
|
|
||||||
f(report) map { result =>
|
|
||||||
toFile(style.formats)(currentFilesInfo)(cache)
|
|
||||||
result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
object InvalidateFiles
|
|
||||||
{
|
|
||||||
def apply(cacheDirectory: File): Invalidate[File] = apply(cacheDirectory, true)
|
|
||||||
def apply(cacheDirectory: File, translateProducts: Boolean): Invalidate[File] =
|
|
||||||
{
|
|
||||||
import sbinary.DefaultProtocol.FileFormat
|
|
||||||
new Invalidate[File](cacheDirectory, translateProducts, FileUtilities.delete)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
class Invalidate[T](val cacheDirectory: File, val translateProducts: Boolean, cleanT: T => Unit)
|
|
||||||
(implicit format: Format[T], mf: Manifest[T]) extends Tracked
|
|
||||||
{
|
|
||||||
def this(cacheDirectory: File, translateProducts: Boolean)(implicit format: Format[T], mf: Manifest[T]) =
|
|
||||||
this(cacheDirectory, translateProducts, x => ())
|
|
||||||
|
|
||||||
private val trackFormat = new TrackingFormat[T](cacheDirectory, translateProducts)
|
|
||||||
private def cleanAll(fs: Set[T]) = fs.foreach(cleanT)
|
|
||||||
|
|
||||||
def clear = Clean(cacheDirectory)
|
|
||||||
def clean = Task(cleanAll(trackFormat.read.allProducts))
|
|
||||||
def apply[R](changes: ChangeReport[T])(f: (InvalidationReport[T], UpdateTracking[T]) => Task[R]): Task[R] =
|
|
||||||
apply(Task(changes))(f)
|
|
||||||
def apply[R](changesTask: Task[ChangeReport[T]])(f: (InvalidationReport[T], UpdateTracking[T]) => Task[R]): Task[R] =
|
|
||||||
{
|
|
||||||
changesTask bind { changes =>
|
|
||||||
val tracker = trackFormat.read
|
|
||||||
def invalidatedBy(file: T) = tracker.products(file) ++ tracker.sources(file) ++ tracker.usedBy(file) ++ tracker.dependsOn(file)
|
|
||||||
|
|
||||||
import scala.collection.mutable.HashSet
|
|
||||||
val invalidated = new HashSet[T]
|
|
||||||
val invalidatedProducts = new HashSet[T]
|
|
||||||
def invalidate(files: Iterable[T]): Unit =
|
|
||||||
for(file <- files if !invalidated(file))
|
|
||||||
{
|
|
||||||
invalidated += file
|
|
||||||
if(!tracker.sources(file).isEmpty) invalidatedProducts += file
|
|
||||||
invalidate(invalidatedBy(file))
|
|
||||||
}
|
|
||||||
|
|
||||||
invalidate(changes.modified)
|
|
||||||
tracker.removeAll(invalidated)
|
|
||||||
|
|
||||||
val report = new InvalidationReport[T]
|
|
||||||
{
|
|
||||||
val invalid = Set(invalidated.toSeq : _*)
|
|
||||||
val invalidProducts = Set(invalidatedProducts.toSeq : _*)
|
|
||||||
val valid = changes.unmodified -- invalid
|
|
||||||
}
|
|
||||||
cleanAll(report.invalidProducts)
|
|
||||||
|
|
||||||
f(report, tracker) map { result =>
|
|
||||||
trackFormat.write(tracker)
|
|
||||||
result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
class BasicTracked[F <: FileInfo](filesTask: Task[Set[File]], style: FilesInfo.Style[F], cacheDirectory: File)(implicit mf: Manifest[F]) extends Tracked
|
|
||||||
{
|
|
||||||
private val changed = new Difference(filesTask, style, new File(cacheDirectory, "files"))
|
|
||||||
private val invalidation = InvalidateFiles(cacheDirectory)
|
|
||||||
val clean = invalidation.clean
|
|
||||||
val clear = Clean(cacheDirectory)
|
|
||||||
|
|
||||||
def apply[R](f: (ChangeReport[File], InvalidationReport[File], UpdateTracking[File]) => Task[R]): Task[R] =
|
|
||||||
changed { sourceChanges =>
|
|
||||||
invalidation(sourceChanges) { (report, tracking) =>
|
|
||||||
f(sourceChanges, report, tracking)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private object DependencyTracking
|
private object DependencyTracking
|
||||||
{
|
{
|
||||||
import scala.collection.mutable.{Set, HashMap, Map, MultiMap}
|
import scala.collection.mutable.{Set, HashMap, Map, MultiMap}
|
||||||
|
|
@ -150,12 +17,6 @@ trait UpdateTracking[T] extends NotNull
|
||||||
def tag(source: T, t: Array[Byte]): Unit
|
def tag(source: T, t: Array[Byte]): Unit
|
||||||
def read: ReadTracking[T]
|
def read: ReadTracking[T]
|
||||||
}
|
}
|
||||||
object Clean
|
|
||||||
{
|
|
||||||
def apply(src: Task[Set[File]]): Task[Unit] = src map FileUtilities.delete
|
|
||||||
def apply(srcs: File*): Task[Unit] = Task(FileUtilities.delete(srcs))
|
|
||||||
def apply(srcs: Set[File]): Task[Unit] = Task(FileUtilities.delete(srcs))
|
|
||||||
}
|
|
||||||
import scala.collection.Set
|
import scala.collection.Set
|
||||||
trait ReadTracking[T] extends NotNull
|
trait ReadTracking[T] extends NotNull
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import java.io.{File, IOException}
|
||||||
import sbinary.{DefaultProtocol, Format}
|
import sbinary.{DefaultProtocol, Format}
|
||||||
import DefaultProtocol._
|
import DefaultProtocol._
|
||||||
import Function.tupled
|
import Function.tupled
|
||||||
|
import scala.reflect.Manifest
|
||||||
|
|
||||||
sealed trait FileInfo extends NotNull
|
sealed trait FileInfo extends NotNull
|
||||||
{
|
{
|
||||||
|
|
@ -25,30 +26,39 @@ private final case class FileHashModified(file: File, hash: List[Byte], lastModi
|
||||||
|
|
||||||
object FileInfo
|
object FileInfo
|
||||||
{
|
{
|
||||||
sealed trait Style[F <: FileInfo] extends NotNull
|
sealed trait Style extends NotNull
|
||||||
{
|
{
|
||||||
|
type F <: FileInfo
|
||||||
implicit def apply(file: File): F
|
implicit def apply(file: File): F
|
||||||
implicit def unapply(info: F): File = info.file
|
implicit def unapply(info: F): File = info.file
|
||||||
implicit val format: Format[F]
|
implicit val format: Format[F]
|
||||||
|
/*val manifest: Manifest[F]
|
||||||
|
def formatManifest: Manifest[Format[F]] = CacheIO.manifest[Format[F]]*/
|
||||||
import Cache._
|
import Cache._
|
||||||
implicit def infoInputCache: InputCache[File] = wrapInputCache[File,F]
|
implicit def infoInputCache: InputCache[File] = wrapInputCache[File,F]
|
||||||
implicit def infoOutputCache: OutputCache[File] = wrapOutputCache[File,F]
|
implicit def infoOutputCache: OutputCache[File] = wrapOutputCache[File,F]
|
||||||
}
|
}
|
||||||
object full extends Style[HashModifiedFileInfo]
|
object full extends Style
|
||||||
{
|
{
|
||||||
|
type F = HashModifiedFileInfo
|
||||||
|
//val manifest: Manifest[F] = CacheIO.manifest[HashModifiedFileInfo]
|
||||||
implicit def apply(file: File): HashModifiedFileInfo = make(file, Hash(file).toList, file.lastModified)
|
implicit def apply(file: File): HashModifiedFileInfo = make(file, Hash(file).toList, file.lastModified)
|
||||||
def make(file: File, hash: List[Byte], lastModified: Long): HashModifiedFileInfo = FileHashModified(file.getAbsoluteFile, hash, lastModified)
|
def make(file: File, hash: List[Byte], lastModified: Long): HashModifiedFileInfo = FileHashModified(file.getAbsoluteFile, hash, lastModified)
|
||||||
implicit val format: Format[HashModifiedFileInfo] = wrap(f => (f.file, f.hash, f.lastModified), tupled(make _))
|
implicit val format: Format[HashModifiedFileInfo] = wrap(f => (f.file, f.hash, f.lastModified), tupled(make _))
|
||||||
}
|
}
|
||||||
object hash extends Style[HashFileInfo]
|
object hash extends Style
|
||||||
{
|
{
|
||||||
|
type F = HashFileInfo
|
||||||
|
//val manifest: Manifest[F] = CacheIO.manifest[HashFileInfo]
|
||||||
implicit def apply(file: File): HashFileInfo = make(file, computeHash(file).toList)
|
implicit def apply(file: File): HashFileInfo = make(file, computeHash(file).toList)
|
||||||
def make(file: File, hash: List[Byte]): HashFileInfo = FileHash(file.getAbsoluteFile, hash)
|
def make(file: File, hash: List[Byte]): HashFileInfo = FileHash(file.getAbsoluteFile, hash)
|
||||||
implicit val format: Format[HashFileInfo] = wrap(f => (f.file, f.hash), tupled(make _))
|
implicit val format: Format[HashFileInfo] = wrap(f => (f.file, f.hash), tupled(make _))
|
||||||
private def computeHash(file: File) = try { Hash(file) } catch { case e: Exception => Nil }
|
private def computeHash(file: File) = try { Hash(file) } catch { case e: Exception => Nil }
|
||||||
}
|
}
|
||||||
object lastModified extends Style[ModifiedFileInfo]
|
object lastModified extends Style
|
||||||
{
|
{
|
||||||
|
type F = ModifiedFileInfo
|
||||||
|
//val manifest: Manifest[F] = CacheIO.manifest[ModifiedFileInfo]
|
||||||
implicit def apply(file: File): ModifiedFileInfo = make(file, file.lastModified)
|
implicit def apply(file: File): ModifiedFileInfo = make(file, file.lastModified)
|
||||||
def make(file: File, lastModified: Long): ModifiedFileInfo = FileModified(file.getAbsoluteFile, lastModified)
|
def make(file: File, lastModified: Long): ModifiedFileInfo = FileModified(file.getAbsoluteFile, lastModified)
|
||||||
implicit val format: Format[ModifiedFileInfo] = wrap(f => (f.file, f.lastModified), tupled(make _))
|
implicit val format: Format[ModifiedFileInfo] = wrap(f => (f.file, f.lastModified), tupled(make _))
|
||||||
|
|
@ -58,21 +68,27 @@ object FileInfo
|
||||||
final case class FilesInfo[F <: FileInfo] private(files: Set[F]) extends NotNull
|
final case class FilesInfo[F <: FileInfo] private(files: Set[F]) extends NotNull
|
||||||
object FilesInfo
|
object FilesInfo
|
||||||
{
|
{
|
||||||
sealed trait Style[F <: FileInfo] extends NotNull
|
sealed trait Style extends NotNull
|
||||||
{
|
{
|
||||||
|
val fileStyle: FileInfo.Style
|
||||||
|
type F = fileStyle.F
|
||||||
|
//def manifest: Manifest[F] = fileStyle.manifest
|
||||||
implicit def apply(files: Set[File]): FilesInfo[F]
|
implicit def apply(files: Set[File]): FilesInfo[F]
|
||||||
implicit def unapply(info: FilesInfo[F]): Set[File] = info.files.map(_.file)
|
implicit def unapply(info: FilesInfo[F]): Set[File] = info.files.map(_.file)
|
||||||
implicit val formats: Format[FilesInfo[F]]
|
implicit val formats: Format[FilesInfo[F]]
|
||||||
|
val manifest: Manifest[Format[FilesInfo[F]]]
|
||||||
import Cache._
|
import Cache._
|
||||||
implicit def infosInputCache: InputCache[Set[File]] = wrapInputCache[Set[File],FilesInfo[F]]
|
implicit def infosInputCache: InputCache[Set[File]] = wrapInputCache[Set[File],FilesInfo[F]]
|
||||||
implicit def infosOutputCache: OutputCache[Set[File]] = wrapOutputCache[Set[File],FilesInfo[F]]
|
implicit def infosOutputCache: OutputCache[Set[File]] = wrapOutputCache[Set[File],FilesInfo[F]]
|
||||||
}
|
}
|
||||||
private final class BasicStyle[F <: FileInfo](fileStyle: FileInfo.Style[F])(implicit infoFormat: Format[F]) extends Style[F]
|
private final class BasicStyle[FI <: FileInfo](val fileStyle: FileInfo.Style { type F = FI })
|
||||||
|
(implicit val manifest: Manifest[Format[FilesInfo[FI]]]) extends Style
|
||||||
{
|
{
|
||||||
|
private implicit val infoFormat: Format[FI] = fileStyle.format
|
||||||
implicit def apply(files: Set[File]): FilesInfo[F] = FilesInfo( files.map(_.getAbsoluteFile).map(fileStyle.apply) )
|
implicit def apply(files: Set[File]): FilesInfo[F] = FilesInfo( files.map(_.getAbsoluteFile).map(fileStyle.apply) )
|
||||||
implicit val formats: Format[FilesInfo[F]] = wrap(_.files, (fs: Set[F]) => new FilesInfo(fs))
|
implicit val formats: Format[FilesInfo[F]] = wrap(_.files, (fs: Set[F]) => new FilesInfo(fs))
|
||||||
}
|
}
|
||||||
lazy val full: Style[HashModifiedFileInfo] = new BasicStyle(FileInfo.full)(FileInfo.full.format)
|
lazy val full: Style = new BasicStyle(FileInfo.full)
|
||||||
lazy val hash: Style[HashFileInfo] = new BasicStyle(FileInfo.hash)(FileInfo.hash.format)
|
lazy val hash: Style = new BasicStyle(FileInfo.hash)
|
||||||
lazy val lastModified: Style[ModifiedFileInfo] = new BasicStyle(FileInfo.lastModified)(FileInfo.lastModified.format)
|
lazy val lastModified: Style = new BasicStyle(FileInfo.lastModified)
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,141 @@
|
||||||
|
package xsbt
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
import CacheIO.{fromFile, toFile}
|
||||||
|
import sbinary.Format
|
||||||
|
import scala.reflect.Manifest
|
||||||
|
|
||||||
|
trait Tracked extends NotNull
|
||||||
|
{
|
||||||
|
def clear: Task[Unit]
|
||||||
|
def clean: Task[Unit]
|
||||||
|
}
|
||||||
|
object Clean
|
||||||
|
{
|
||||||
|
def apply(src: Task[Set[File]]): Task[Unit] = src map FileUtilities.delete
|
||||||
|
def apply(srcs: File*): Task[Unit] = Task(FileUtilities.delete(srcs))
|
||||||
|
def apply(srcs: Set[File]): Task[Unit] = Task(FileUtilities.delete(srcs))
|
||||||
|
}
|
||||||
|
|
||||||
|
class Changed[O](val task: Task[O], val file: File)(implicit input: InputCache[O]) extends Tracked
|
||||||
|
{
|
||||||
|
def clean = Task.empty
|
||||||
|
def clear = Clean(file)
|
||||||
|
def apply[O2](ifChanged: O => O2, ifUnchanged: O => O2): Task[O2] { type Input = O } =
|
||||||
|
task map { value =>
|
||||||
|
val cache = OpenResource.fileInputStream(file)(input.uptodate(value))
|
||||||
|
if(cache.uptodate)
|
||||||
|
ifUnchanged(value)
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OpenResource.fileOutputStream(false)(file)(cache.update)
|
||||||
|
ifChanged(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class Difference(val filesTask: Task[Set[File]], val style: FilesInfo.Style, val cache: File, val shouldClean: Boolean) extends Tracked
|
||||||
|
{
|
||||||
|
def this(filesTask: Task[Set[File]], style: FilesInfo.Style, cache: File) = this(filesTask, style, cache, false)
|
||||||
|
def this(files: Set[File], style: FilesInfo.Style, cache: File, shouldClean: Boolean) = this(Task(files), style, cache)
|
||||||
|
def this(files: Set[File], style: FilesInfo.Style, cache: File) = this(Task(files), style, cache, false)
|
||||||
|
|
||||||
|
val clear = Clean(cache)
|
||||||
|
val clean = if(shouldClean) cleanTask else Task.empty
|
||||||
|
def cleanTask = Clean(Task(raw(cachedFilesInfo)))
|
||||||
|
|
||||||
|
private def cachedFilesInfo = fromFile(style.formats)(cache)(style.manifest).files
|
||||||
|
private def raw(fs: Set[style.F]): Set[File] = fs.map(_.file)
|
||||||
|
|
||||||
|
def apply[T](f: ChangeReport[File] => Task[T]): Task[T] =
|
||||||
|
filesTask bind { files =>
|
||||||
|
val lastFilesInfo = cachedFilesInfo
|
||||||
|
val lastFiles = raw(lastFilesInfo)
|
||||||
|
val currentFiles = files.map(_.getAbsoluteFile)
|
||||||
|
val currentFilesInfo = style(files)
|
||||||
|
|
||||||
|
val report = new ChangeReport[File]
|
||||||
|
{
|
||||||
|
lazy val allInputs = currentFiles
|
||||||
|
lazy val removed = lastFiles -- allInputs
|
||||||
|
lazy val added = allInputs -- lastFiles
|
||||||
|
lazy val modified = raw(lastFilesInfo -- currentFilesInfo.files)
|
||||||
|
lazy val unmodified = allInputs -- modified
|
||||||
|
}
|
||||||
|
|
||||||
|
f(report) map { result =>
|
||||||
|
toFile(style.formats)(currentFilesInfo)(cache)(style.manifest)
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
object InvalidateFiles
|
||||||
|
{
|
||||||
|
def apply(cacheDirectory: File): Invalidate[File] = apply(cacheDirectory, true)
|
||||||
|
def apply(cacheDirectory: File, translateProducts: Boolean): Invalidate[File] =
|
||||||
|
{
|
||||||
|
import sbinary.DefaultProtocol.FileFormat
|
||||||
|
new Invalidate[File](cacheDirectory, translateProducts, FileUtilities.delete)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class Invalidate[T](val cacheDirectory: File, val translateProducts: Boolean, cleanT: T => Unit)
|
||||||
|
(implicit format: Format[T], mf: Manifest[T]) extends Tracked
|
||||||
|
{
|
||||||
|
def this(cacheDirectory: File, translateProducts: Boolean)(implicit format: Format[T], mf: Manifest[T]) =
|
||||||
|
this(cacheDirectory, translateProducts, x => ())
|
||||||
|
|
||||||
|
private val trackFormat = new TrackingFormat[T](cacheDirectory, translateProducts)
|
||||||
|
private def cleanAll(fs: Set[T]) = fs.foreach(cleanT)
|
||||||
|
|
||||||
|
def clear = Clean(cacheDirectory)
|
||||||
|
def clean = Task(cleanAll(trackFormat.read.allProducts))
|
||||||
|
def apply[R](changes: ChangeReport[T])(f: (InvalidationReport[T], UpdateTracking[T]) => Task[R]): Task[R] =
|
||||||
|
apply(Task(changes))(f)
|
||||||
|
def apply[R](changesTask: Task[ChangeReport[T]])(f: (InvalidationReport[T], UpdateTracking[T]) => Task[R]): Task[R] =
|
||||||
|
{
|
||||||
|
changesTask bind { changes =>
|
||||||
|
val tracker = trackFormat.read
|
||||||
|
def invalidatedBy(file: T) = tracker.products(file) ++ tracker.sources(file) ++ tracker.usedBy(file) ++ tracker.dependsOn(file)
|
||||||
|
|
||||||
|
import scala.collection.mutable.HashSet
|
||||||
|
val invalidated = new HashSet[T]
|
||||||
|
val invalidatedProducts = new HashSet[T]
|
||||||
|
def invalidate(files: Iterable[T]): Unit =
|
||||||
|
for(file <- files if !invalidated(file))
|
||||||
|
{
|
||||||
|
invalidated += file
|
||||||
|
if(!tracker.sources(file).isEmpty) invalidatedProducts += file
|
||||||
|
invalidate(invalidatedBy(file))
|
||||||
|
}
|
||||||
|
|
||||||
|
invalidate(changes.modified)
|
||||||
|
tracker.removeAll(invalidated)
|
||||||
|
|
||||||
|
val report = new InvalidationReport[T]
|
||||||
|
{
|
||||||
|
val invalid = Set(invalidated.toSeq : _*)
|
||||||
|
val invalidProducts = Set(invalidatedProducts.toSeq : _*)
|
||||||
|
val valid = changes.unmodified -- invalid
|
||||||
|
}
|
||||||
|
cleanAll(report.invalidProducts)
|
||||||
|
|
||||||
|
f(report, tracker) map { result =>
|
||||||
|
trackFormat.write(tracker)
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class BasicTracked(filesTask: Task[Set[File]], style: FilesInfo.Style, cacheDirectory: File) extends Tracked
|
||||||
|
{
|
||||||
|
private val changed = new Difference(filesTask, style, new File(cacheDirectory, "files"))
|
||||||
|
private val invalidation = InvalidateFiles(cacheDirectory)
|
||||||
|
val clean = invalidation.clean
|
||||||
|
val clear = Clean(cacheDirectory)
|
||||||
|
|
||||||
|
def apply[R](f: (ChangeReport[File], InvalidationReport[File], UpdateTracking[File]) => Task[R]): Task[R] =
|
||||||
|
changed { sourceChanges =>
|
||||||
|
invalidation(sourceChanges) { (report, tracking) =>
|
||||||
|
f(sourceChanges, report, tracking)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,25 +1,33 @@
|
||||||
package xsbt
|
package xsbt
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import Task._
|
import scala.reflect.Manifest
|
||||||
|
import Task._
|
||||||
|
|
||||||
object Sync
|
object Sync
|
||||||
{
|
{
|
||||||
def sources(inputDirectory: Task[File], outputDirectory: Task[File]) =
|
def sources(inputDirectory: Task[File], outputDirectory: Task[File]) =
|
||||||
{
|
{
|
||||||
import Paths._
|
import Paths._
|
||||||
(inputDirectory, outputDirectory) map { (in, out) =>
|
(inputDirectory, outputDirectory) map { (in, out) =>
|
||||||
FileUtilities.assertDirectories(in, out)
|
FileUtilities.assertDirectories(in, out)
|
||||||
(in ***) x FileMapper.rebase(in, out)
|
(in ***) x FileMapper.rebase(in, out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
def apply(inputDirectory: Task[File], outputDirectory: Task[File], cacheFile: File): Sync =
|
||||||
|
apply(sources(inputDirectory, outputDirectory), cacheFile)
|
||||||
|
def apply(inputDirectory: Task[File], outputDirectory: Task[File], style: FilesInfo.Style, cacheFile: File): Sync =
|
||||||
|
apply(sources(inputDirectory, outputDirectory), style, cacheFile)
|
||||||
|
def apply(sources: Task[Iterable[(File,File)]], cacheDirectory: File): Sync =
|
||||||
|
apply(sources, FilesInfo.hash, cacheDirectory)
|
||||||
|
def apply(sources: Task[Iterable[(File,File)]], style: FilesInfo.Style, cacheDirectory: File): Sync =
|
||||||
|
new Sync(sources, style, cacheDirectory)
|
||||||
}
|
}
|
||||||
class Sync(val sources: Task[Iterable[(File,File)]], val cacheDirectory: File) extends TrackedTaskDefinition[Set[File]]
|
class Sync(val sources: Task[Iterable[(File,File)]], val style: FilesInfo.Style, val cacheDirectory: File) extends TrackedTaskDefinition[Set[File]]
|
||||||
{
|
{
|
||||||
val tracking = new BasicTracked(sources.map(Set() ++ _.map(_._1)), FilesInfo.hash, cacheFile("sources"))
|
val tracking = new BasicTracked(sources.map(Set() ++ _.map(_._1)), style, cacheFile("sources"))
|
||||||
val tracked = Seq(tracking)
|
val tracked = Seq(tracking)
|
||||||
|
|
||||||
def this(inputDirectory: Task[File], outputDirectory: Task[File], cacheFile: File) = this(Sync.sources(inputDirectory, outputDirectory), cacheFile)
|
|
||||||
lazy val task =
|
lazy val task =
|
||||||
sources bind { srcs =>
|
sources bind { srcs =>
|
||||||
val sourcesTargets = srcs.toSeq
|
val sourcesTargets = srcs.toSeq
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue