diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index fdbac4ffe..fa2c3eb7d 100644 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -3797,7 +3797,7 @@ object Classpaths { forceUpdatePeriod.value match { case None => false case Some(period) => - val fullUpdateOutput = cacheDirectory / "out" + val fullUpdateOutput = cacheDirectory / "output" val now = System.currentTimeMillis val diff = now - IO.getModifiedTimeOrZero(fullUpdateOutput) val elapsedDuration = new FiniteDuration(diff, TimeUnit.MILLISECONDS) diff --git a/main/src/main/scala/sbt/internal/LibraryManagement.scala b/main/src/main/scala/sbt/internal/LibraryManagement.scala index 9a0f0d362..750a51c9f 100644 --- a/main/src/main/scala/sbt/internal/LibraryManagement.scala +++ b/main/src/main/scala/sbt/internal/LibraryManagement.scala @@ -110,13 +110,16 @@ private[sbt] object LibraryManagement { } /* Skip resolve if last output exists, otherwise error. */ - def skipResolve(cache: CacheStore): UpdateInputs => UpdateReport = { + def skipResolve(cache: CacheStore)(inputs: UpdateInputs): UpdateReport = { import sbt.librarymanagement.LibraryManagementCodec._ - Tracked.lastOutput[UpdateInputs, UpdateReport](cache) { - case (_, Some(out)) => markAsCached(out) - case _ => - sys.error("Skipping update requested, but update has not previously run successfully.") - } + val cachedReport = Tracked + .lastOutput[UpdateInputs, UpdateReport](cache) { + case (_, Some(out)) => out + case _ => + sys.error("Skipping update requested, but update has not previously run successfully.") + } + .apply(inputs) + markAsCached(cachedReport) } // Mark UpdateReport#stats as "cached." This is used by the dependers later @@ -127,15 +130,21 @@ private[sbt] object LibraryManagement { 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) => markAsCached(out) - case pair => - log.debug(s"""not up to date. inChanged = $inChanged, force = $force""") - resolve - } - import scala.util.control.Exception.catching - catching(classOf[NullPointerException], classOf[OutOfMemoryError]) - .withApply { t => + try { + var isCached = false + val report = Tracked + .lastOutput[UpdateInputs, UpdateReport](cache) { + case (_, Some(out)) if upToDate(inChanged, out) => + isCached = true + out + case pair => + log.debug(s"""not up to date. inChanged = $inChanged, force = $force""") + resolve + } + .apply(updateInputs) + if (isCached) markAsCached(report) else report + } catch { + case t @ (_: NullPointerException | _: OutOfMemoryError) => val resolvedAgain = resolve val culprit = t.getClass.getSimpleName log.warn(s"Update task caching failed due to $culprit.") @@ -143,8 +152,7 @@ private[sbt] object LibraryManagement { resolvedAgain.toString.linesIterator.foreach(log.warn(_)) log.trace(t) resolvedAgain - } - .apply(cachedResolve(updateInputs)) + } } import LibraryManagementCodec._ Tracked.inputChanged(cacheStoreFactory.make("inputs"))(doCachedResolve) @@ -155,7 +163,7 @@ private[sbt] object LibraryManagement { val extraInputHash = module.extraInputHash val settings = module.moduleSettings val outStore = cacheStoreFactory.make("output") - val handler = if (skip && !force) skipResolve(outStore) else doResolve(outStore) + val handler = if (skip && !force) skipResolve(outStore)(_) else doResolve(outStore) // Remove clock for caching purpose val withoutClock = updateConfig.withLogicalClock(LogicalClock.unknown) handler((extraInputHash, settings, withoutClock)) @@ -257,7 +265,7 @@ private[sbt] object LibraryManagement { forceUpdatePeriod.value match { case None => false case Some(period) => - val fullUpdateOutput = cacheDirectory / "out" + val fullUpdateOutput = cacheDirectory / "output" val now = System.currentTimeMillis val diff = now - fullUpdateOutput.lastModified() val elapsedDuration = new scala.concurrent.duration.FiniteDuration( diff --git a/sbt-app/src/sbt-test/dependency-management/force-update-period/build.sbt b/sbt-app/src/sbt-test/dependency-management/force-update-period/build.sbt index 11bcdf94e..23d58d7d1 100644 --- a/sbt-app/src/sbt-test/dependency-management/force-update-period/build.sbt +++ b/sbt-app/src/sbt-test/dependency-management/force-update-period/build.sbt @@ -1,17 +1,19 @@ ThisBuild / useCoursier := false +name := "force-update-period" +scalaVersion := "2.12.18" libraryDependencies += "log4j" % "log4j" % "1.2.16" % "compile" - autoScalaLibrary := false -crossPaths := false - -TaskKey[Unit]("check-last-update-time") := (streams map { (s) => - val fullUpdateOutput = s.cacheDirectory / "out" - val timeDiff = System.currentTimeMillis()-fullUpdateOutput.lastModified() - val exists = fullUpdateOutput.exists() - s.log.info(s"Amount of time since last full update: $timeDiff") - if (exists && timeDiff > 5000) { - sys.error("Full update not performed") +TaskKey[Unit]("check-last-update-time") := { + val s = streams.value + val updateOutput = crossTarget.value / "update" / updateCacheName.value / "output" + if (!updateOutput.exists()) { + sys.error("Update cache does not exist") } -}).value + val timeDiff = System.currentTimeMillis() - updateOutput.lastModified() + s.log.info(s"Amount of time since last full update: $timeDiff") + if (timeDiff > 5000) { + sys.error("Update not performed") + } +} diff --git a/sbt-app/src/sbt-test/dependency-management/force-update-period/test b/sbt-app/src/sbt-test/dependency-management/force-update-period/test index 39e776d09..17ae82b98 100644 --- a/sbt-app/src/sbt-test/dependency-management/force-update-period/test +++ b/sbt-app/src/sbt-test/dependency-management/force-update-period/test @@ -1,11 +1,11 @@ -$ absent target/resolution-cache +$ absent target/scala-2.12/resolution-cache > compile -$ exists target/resolution-cache +$ exists target/scala-2.12/resolution-cache > checkLastUpdateTime -$ sleep 10000 +$ sleep 5000 > compile # This is expected to fail -> checkLastUpdateTime > set forceUpdatePeriod := Some(new scala.concurrent.duration.FiniteDuration(5000, java.util.concurrent.TimeUnit.MILLISECONDS)) > compile -> checkLastUpdateTime \ No newline at end of file +> checkLastUpdateTime