Fix cached update task

Fixes sbt/sbt#3226

One of the checks that the cached update task performs is called `depsUpdated`, which checks if the subproject dependencies have been thawed out of cache of now.
For this to function correctly, when we thaw the `UpdateReport` from JSON, we need to mark the report as cached. This was done subtley in sbt 0.13 for sbinary (https://github.com/sbt/sbt-zero-thirteen/blob/v0.13.15/main/actions/src/main/scala/sbt/CacheIvy.scala#L66-L67).
This commit is contained in:
Eugene Yokota 2017-05-29 17:14:52 -04:00
parent 13ec092be3
commit 3690ff193c
3 changed files with 55 additions and 28 deletions

View File

@ -71,17 +71,22 @@ object LibraryManagement {
def skipResolve(cache: CacheStore): UpdateInputs => UpdateReport = {
import sbt.librarymanagement.LibraryManagementCodec._
Tracked.lastOutput[UpdateInputs, UpdateReport](cache) {
case (_, Some(out)) => out
case (_, Some(out)) => markAsCached(out)
case _ =>
sys.error("Skipping update requested, but update has not previously run successfully.")
}
}
// Mark UpdateReport#stats as "cached." This is used by the dependers later
// to determine whether they now need to run update in the above `upToDate`.
def markAsCached(ur: UpdateReport): UpdateReport =
ur.withStats(ur.stats.withCached(true))
def doResolve(cache: CacheStore): UpdateInputs => UpdateReport = {
val doCachedResolve = { (inChanged: Boolean, updateInputs: UpdateInputs) =>
import sbt.librarymanagement.LibraryManagementCodec._
val cachedResolve = Tracked.lastOutput[UpdateInputs, UpdateReport](cache) {
case (_, Some(out)) if upToDate(inChanged, out) => out
case (_, Some(out)) if upToDate(inChanged, out) => markAsCached(out)
case _ => resolve(updateInputs)
}
import scala.util.control.Exception.catching

View File

@ -1,33 +1,54 @@
// #1620
ivyPaths := IvyPaths(
(baseDirectory in ThisBuild).value,
Some((baseDirectory in LocalRootProject).value / "ivy-cache")
)
scalaVersion := "2.10.4"
scalaVersion in ThisBuild := "2.10.4"
dependencyOverrides in ThisBuild += "com.github.nscala-time" %% "nscala-time" % "1.0.0"
libraryDependencies += "com.github.nscala-time" %% "nscala-time" % "1.0.0"
TaskKey[Unit]("check") := {
val s = (streams in update).value
val cacheStoreFactory = s.cacheStoreFactory sub updateCacheName.value
val module = ivyModule.value
val config = updateConfiguration.value
lazy val root = (project in file("."))
.dependsOn(p1 % Compile)
.settings(
ivyPaths := IvyPaths(
(baseDirectory in ThisBuild).value,
Some((baseDirectory in LocalRootProject).value / "ivy-cache")
),
libraryDependencies += "com.github.nscala-time" %% "nscala-time" % "1.0.0",
import sbt.internal.librarymanagement.IvyConfiguration
import sbt.librarymanagement.{ ModuleSettings, UpdateConfiguration }
// https://github.com/sbt/sbt/pull/1620
// sbt resolves dependencies every compile when using %% with dependencyOverrides
TaskKey[Unit]("check") := {
val s = (streams in update).value
val cacheStoreFactory = s.cacheStoreFactory sub updateCacheName.value
val module = ivyModule.value
val config = updateConfiguration.value
type In = IvyConfiguration :+: ModuleSettings :+: UpdateConfiguration :+: HNil
import sbt.internal.librarymanagement.IvyConfiguration
import sbt.librarymanagement.{ ModuleSettings, UpdateConfiguration }
import sbt.util.CacheImplicits._
import sbt.internal.AltLibraryManagementCodec._
type In = IvyConfiguration :+: ModuleSettings :+: UpdateConfiguration :+: HNil
val f: In => Unit =
Tracked.inputChanged(cacheStoreFactory make "inputs") { (inChanged: Boolean, in: In) =>
if (inChanged)
sys.error(s"Update cache is invalidated: ${module.owner.configuration}, ${module.moduleSettings}, $config")
import sbt.util.CacheImplicits._
import sbt.internal.AltLibraryManagementCodec._
val f: In => Unit =
Tracked.inputChanged(cacheStoreFactory make "inputs") { (inChanged: Boolean, in: In) =>
if (inChanged)
sys.error(s"Update cache is invalidated: ${module.owner.configuration}, ${module.moduleSettings}, $config")
}
f(module.owner.configuration :+: module.moduleSettings :+: config :+: HNil)
},
// https://github.com/sbt/sbt/issues/3226
// update caching is not working on sbt 1.0.x
TaskKey[Unit]("check2") := {
val ur = update.value
if (!ur.stats.cached) {
sys.error(s"update.value is not cached! $ur")
}
val tu = transitiveUpdate.value
if (tu.exists(!_.stats.cached)) {
sys.error(s"uncached transitiveUpdate exists! $tu")
}
}
f(module.owner.configuration :+: module.moduleSettings :+: config :+: HNil)
}
)
lazy val p1 = project
.settings(
libraryDependencies += "com.novocode" % "junit-interface" % "0.11"
)

View File

@ -1,2 +1,3 @@
> compile
> check
> check2