mirror of https://github.com/sbt/sbt.git
Use pickler to cache UpdateReport for update task. #1763
This commit is contained in:
parent
ef1ec99bd0
commit
b70fa6e0c2
|
|
@ -305,7 +305,7 @@ lazy val cacheProj = (project in cachePath).
|
|||
settings(baseSettings: _*).
|
||||
settings(
|
||||
name := "Cache",
|
||||
libraryDependencies ++= Seq(sbinary) ++ scalaXml.value
|
||||
libraryDependencies ++= Seq(sbinary, sbtSerialization) ++ scalaXml.value
|
||||
)
|
||||
|
||||
// Builds on cache to provide caching for filesystem-related operations
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import sbinary.Format
|
|||
import scala.reflect.Manifest
|
||||
import scala.collection.mutable
|
||||
import IO.{ delete, read, write }
|
||||
import sbt.serialization._
|
||||
|
||||
object Tracked {
|
||||
/**
|
||||
|
|
@ -36,6 +37,25 @@ object Tracked {
|
|||
toFile(next)(cacheFile)
|
||||
next
|
||||
}
|
||||
private[sbt] def lastOuputWithJson[I, O: Pickler: Unpickler](cacheFile: File)(f: (I, Option[O]) => O): I => O = in =>
|
||||
{
|
||||
val previous: Option[O] = fromJsonFile[O](cacheFile)
|
||||
val next = f(in, previous)
|
||||
toJsonFile(next)(cacheFile)
|
||||
next
|
||||
}
|
||||
private[sbt] def fromJsonFile[A: Unpickler](file: File): Option[A] =
|
||||
try {
|
||||
val s = IO.read(file, IO.utf8)
|
||||
fromJsonString[A](s).toOption
|
||||
} catch {
|
||||
case e: Throwable => None
|
||||
}
|
||||
private[sbt] def toJsonFile[A: Pickler](a: A)(file: File): Unit =
|
||||
{
|
||||
val str = toJsonString(a)
|
||||
IO.write(file, str, IO.utf8)
|
||||
}
|
||||
|
||||
def inputChanged[I, O](cacheFile: File)(f: (Boolean, I) => O)(implicit ic: InputCache[I]): I => O = in =>
|
||||
{
|
||||
|
|
@ -44,6 +64,18 @@ object Tracked {
|
|||
val changed = help.changed(cacheFile, conv)
|
||||
val result = f(changed, in)
|
||||
|
||||
if (changed)
|
||||
help.save(cacheFile, conv)
|
||||
|
||||
result
|
||||
}
|
||||
private[sbt] def inputChangedWithJson[I: Pickler: Unpickler, O](cacheFile: File)(f: (Boolean, I) => O): I => O = in =>
|
||||
{
|
||||
val help = new JsonCacheHelp[I]
|
||||
val conv = help.convert(in)
|
||||
val changed = help.changed(cacheFile, conv)
|
||||
val result = f(changed, in)
|
||||
|
||||
if (changed)
|
||||
help.save(cacheFile, conv)
|
||||
|
||||
|
|
@ -56,6 +88,18 @@ object Tracked {
|
|||
val changed = help.changed(cacheFile, help.convert(initial))
|
||||
val result = f(changed, initial)
|
||||
|
||||
if (changed)
|
||||
help.save(cacheFile, help.convert(in()))
|
||||
|
||||
result
|
||||
}
|
||||
private[sbt] def outputChangedWithJson[I: Pickler, O](cacheFile: File)(f: (Boolean, I) => O): (() => I) => O = in =>
|
||||
{
|
||||
val initial = in()
|
||||
val help = new JsonCacheHelp[I]
|
||||
val changed = help.changed(cacheFile, help.convert(initial))
|
||||
val result = f(changed, initial)
|
||||
|
||||
if (changed)
|
||||
help.save(cacheFile, help.convert(in()))
|
||||
|
||||
|
|
@ -71,6 +115,16 @@ object Tracked {
|
|||
!ic.equiv.equiv(converted, prev)
|
||||
} catch { case e: Exception => true }
|
||||
}
|
||||
private[sbt] final class JsonCacheHelp[I: Pickler] {
|
||||
def convert(i: I): String = toJsonString(i)
|
||||
def save(cacheFile: File, value: String): Unit =
|
||||
IO.write(cacheFile, value, IO.utf8)
|
||||
def changed(cacheFile: File, converted: String): Boolean =
|
||||
try {
|
||||
val prev = IO.read(cacheFile, IO.utf8)
|
||||
converted != prev
|
||||
} catch { case e: Exception => true }
|
||||
}
|
||||
}
|
||||
|
||||
trait Tracked {
|
||||
|
|
|
|||
|
|
@ -1388,13 +1388,13 @@ object Classpaths {
|
|||
|
||||
val outCacheFile = cacheFile / "output"
|
||||
def skipWork: In => UpdateReport =
|
||||
Tracked.lastOutput[In, UpdateReport](outCacheFile) {
|
||||
Tracked.lastOuputWithJson[In, UpdateReport](outCacheFile) {
|
||||
case (_, Some(out)) => out
|
||||
case _ => sys.error("Skipping update requested, but update has not previously run successfully.")
|
||||
}
|
||||
def doWork: In => UpdateReport =
|
||||
Tracked.inputChanged(cacheFile / "inputs") { (inChanged: Boolean, in: In) =>
|
||||
val outCache = Tracked.lastOutput[In, UpdateReport](outCacheFile) {
|
||||
val outCache = Tracked.lastOuputWithJson[In, UpdateReport](outCacheFile) {
|
||||
case (_, Some(out)) if uptodate(inChanged, out) => out
|
||||
case _ => work(in)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue