From 4ec092617f4d5471ada6c839c9307853a3031b17 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 13 May 2015 08:02:48 -0400 Subject: [PATCH 1/3] Add forceUpdateMs --- main/src/main/scala/sbt/Defaults.scala | 11 +++++++++-- main/src/main/scala/sbt/Keys.scala | 1 + notes/0.13.9/forceupdatems.markdown | 9 +++++++++ .../dependency-management/force-update-ms/build.sbt | 13 +++++++++++++ .../dependency-management/force-update-ms/test | 11 +++++++++++ 5 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 notes/0.13.9/forceupdatems.markdown create mode 100644 sbt/src/sbt-test/dependency-management/force-update-ms/build.sbt create mode 100644 sbt/src/sbt-test/dependency-management/force-update-ms/test diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index e75c97832..5b38a5b5b 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -115,7 +115,8 @@ object Defaults extends BuildCommon { pomPostProcess :== idFun, pomAllRepositories :== false, pomIncludeRepository :== Classpaths.defaultRepositoryFilter, - updateOptions := UpdateOptions() + updateOptions := UpdateOptions(), + forceUpdateMs :== None ) /** Core non-plugin settings for sbt builds. These *must* be on every build or the sbt engine will fail to run at all. */ @@ -1324,7 +1325,13 @@ object Classpaths { def updateTask: Initialize[Task[UpdateReport]] = Def.task { val depsUpdated = transitiveUpdate.value.exists(!_.stats.cached) val isRoot = executionRoots.value contains resolvedScoped.value + val forceUpdate = forceUpdateMs.value val s = streams.value + val fullUpdateOutput = s.cacheDirectory / "out" + val forceUpdateByTime = forceUpdate match { + case None => false + case Some(period) => fullUpdateOutput.exists() && fullUpdateOutput.lastModified() <= (System.currentTimeMillis() - period) + } val scalaProvider = appConfiguration.value.provider.scalaProvider // Only substitute unmanaged jars for managed jars when the major.minor parts of the versions the same for: @@ -1360,7 +1367,7 @@ object Classpaths { if (executionRoots.value exists { _.key == evicted.key }) EvictionWarningOptions.empty else (evictionWarningOptions in update).value cachedUpdate(s.cacheDirectory / updateCacheName.value, show, ivyModule.value, uc, transform, - skip = (skip in update).value, force = isRoot, depsUpdated = depsUpdated, + skip = (skip in update).value, force = isRoot || forceUpdateByTime, depsUpdated = depsUpdated, uwConfig = uwConfig, logicalClock = logicalClock, depDir = Some(depDir), ewo = ewo, log = s.log) } diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index 59faafdae..93fce1a0c 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -324,6 +324,7 @@ object Keys { val publishArtifact = SettingKey[Boolean]("publish-artifact", "Enables (true) or disables (false) publishing an artifact.", AMinusSetting) val packagedArtifact = TaskKey[(Artifact, File)]("packaged-artifact", "Generates a packaged artifact, returning the Artifact and the produced File.", CTask) val checksums = SettingKey[Seq[String]]("checksums", "The list of checksums to generate and to verify for dependencies.", BSetting) + val forceUpdateMs = SettingKey[Option[Long]]("force-update-ms", "Amount of time in milliseconds after which to force a full update to occur", CSetting) val classifiersModule = TaskKey[GetClassifiersModule]("classifiers-module", rank = CTask) val conflictWarning = SettingKey[ConflictWarning]("conflict-warning", "Configures warnings for conflicts in dependency management.", CSetting) diff --git a/notes/0.13.9/forceupdatems.markdown b/notes/0.13.9/forceupdatems.markdown new file mode 100644 index 000000000..f506c8ad6 --- /dev/null +++ b/notes/0.13.9/forceupdatems.markdown @@ -0,0 +1,9 @@ + [@ajsquared]: https://github.com/ajsquared + + +### Changes with compatibility implications + +### Improvements +- Adds `forceUpdateMs` key, that takes values of `Option[Long]` representing a number of milliseconds. If set, a full `update` will occur after that amount of time without needing to explicitly run the `update` task. + +### Fixes diff --git a/sbt/src/sbt-test/dependency-management/force-update-ms/build.sbt b/sbt/src/sbt-test/dependency-management/force-update-ms/build.sbt new file mode 100644 index 000000000..ca910bdd9 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/force-update-ms/build.sbt @@ -0,0 +1,13 @@ +libraryDependencies += "log4j" % "log4j" % "1.2.16" % "compile" + +autoScalaLibrary := 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 perfomed") + } +} \ No newline at end of file diff --git a/sbt/src/sbt-test/dependency-management/force-update-ms/test b/sbt/src/sbt-test/dependency-management/force-update-ms/test new file mode 100644 index 000000000..f88058665 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/force-update-ms/test @@ -0,0 +1,11 @@ +$ absent target/resolution-cache +> compile +$ exists target/resolution-cache +> checkLastUpdateTime +$ sleep 10000 +> compile +# This is expected to fail +-> checkLastUpdateTime +> set forceUpdateMs := Some(5000) +> compile +> checkLastUpdateTime \ No newline at end of file From 32b1f655032717bab86ce521550c2cf6e48be820 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 13 May 2015 08:04:44 -0400 Subject: [PATCH 2/3] Update note --- notes/0.13.9/forceupdatems.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notes/0.13.9/forceupdatems.markdown b/notes/0.13.9/forceupdatems.markdown index f506c8ad6..fd631b8b7 100644 --- a/notes/0.13.9/forceupdatems.markdown +++ b/notes/0.13.9/forceupdatems.markdown @@ -4,6 +4,6 @@ ### Changes with compatibility implications ### Improvements -- Adds `forceUpdateMs` key, that takes values of `Option[Long]` representing a number of milliseconds. If set, a full `update` will occur after that amount of time without needing to explicitly run the `update` task. +- Adds `forceUpdateMs` key, that takes values of `Option[Long]` representing a number of milliseconds. If set, a full `update` will occur after that amount of time without needing to explicitly run the `update` task. By [@ajsquared][@ajsquared] ### Fixes From 7c0f455c79a572f9f888f1b5ad6d43492bb0612d Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 13 May 2015 14:18:27 -0400 Subject: [PATCH 3/3] Use FiniteDuration to represent time rather than a long --- main/src/main/scala/sbt/Defaults.scala | 14 ++++++++------ main/src/main/scala/sbt/Keys.scala | 4 ++-- notes/0.13.9/forceupdatems.markdown | 9 --------- notes/0.13.9/forceupdateperiod.markdown | 9 +++++++++ .../build.sbt | 0 .../{force-update-ms => force-update-period}/test | 2 +- 6 files changed, 20 insertions(+), 18 deletions(-) delete mode 100644 notes/0.13.9/forceupdatems.markdown create mode 100644 notes/0.13.9/forceupdateperiod.markdown rename sbt/src/sbt-test/dependency-management/{force-update-ms => force-update-period}/build.sbt (100%) rename sbt/src/sbt-test/dependency-management/{force-update-ms => force-update-period}/test (54%) diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 5b38a5b5b..cd05b9c77 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -3,7 +3,7 @@ */ package sbt -import scala.concurrent.duration.Duration +import scala.concurrent.duration.{ FiniteDuration, Duration } import Attributed.data import Scope.{ fillTaskAxis, GlobalScope, ThisScope } import sbt.Compiler.InputsWithPrevious @@ -27,7 +27,7 @@ import org.apache.ivy.core.module.{ descriptor, id } import descriptor.ModuleDescriptor, id.ModuleRevisionId import java.io.{ File, PrintWriter } import java.net.{ URI, URL, MalformedURLException } -import java.util.concurrent.Callable +import java.util.concurrent.{ TimeUnit, Callable } import sbinary.DefaultProtocol.StringFormat import Cache.seqFormat import CommandStrings.ExportStream @@ -116,7 +116,7 @@ object Defaults extends BuildCommon { pomAllRepositories :== false, pomIncludeRepository :== Classpaths.defaultRepositoryFilter, updateOptions := UpdateOptions(), - forceUpdateMs :== None + forceUpdatePeriod :== None ) /** Core non-plugin settings for sbt builds. These *must* be on every build or the sbt engine will fail to run at all. */ @@ -1325,12 +1325,14 @@ object Classpaths { def updateTask: Initialize[Task[UpdateReport]] = Def.task { val depsUpdated = transitiveUpdate.value.exists(!_.stats.cached) val isRoot = executionRoots.value contains resolvedScoped.value - val forceUpdate = forceUpdateMs.value + val forceUpdate = forceUpdatePeriod.value val s = streams.value val fullUpdateOutput = s.cacheDirectory / "out" val forceUpdateByTime = forceUpdate match { - case None => false - case Some(period) => fullUpdateOutput.exists() && fullUpdateOutput.lastModified() <= (System.currentTimeMillis() - period) + case None => false + case Some(period) => + val elapsedDuration = new FiniteDuration(System.currentTimeMillis() - fullUpdateOutput.lastModified(), TimeUnit.MILLISECONDS) + fullUpdateOutput.exists() && elapsedDuration > period } val scalaProvider = appConfiguration.value.provider.scalaProvider diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index 93fce1a0c..939dd9b77 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -5,7 +5,7 @@ package sbt import java.io.File import java.net.URL -import scala.concurrent.duration.Duration +import scala.concurrent.duration.{ FiniteDuration, Duration } import Def.ScopedKey import complete._ import inc.Analysis @@ -324,7 +324,7 @@ object Keys { val publishArtifact = SettingKey[Boolean]("publish-artifact", "Enables (true) or disables (false) publishing an artifact.", AMinusSetting) val packagedArtifact = TaskKey[(Artifact, File)]("packaged-artifact", "Generates a packaged artifact, returning the Artifact and the produced File.", CTask) val checksums = SettingKey[Seq[String]]("checksums", "The list of checksums to generate and to verify for dependencies.", BSetting) - val forceUpdateMs = SettingKey[Option[Long]]("force-update-ms", "Amount of time in milliseconds after which to force a full update to occur", CSetting) + val forceUpdatePeriod = SettingKey[Option[FiniteDuration]]("force-update-period", "Duration after which to force a full update to occur", CSetting) val classifiersModule = TaskKey[GetClassifiersModule]("classifiers-module", rank = CTask) val conflictWarning = SettingKey[ConflictWarning]("conflict-warning", "Configures warnings for conflicts in dependency management.", CSetting) diff --git a/notes/0.13.9/forceupdatems.markdown b/notes/0.13.9/forceupdatems.markdown deleted file mode 100644 index fd631b8b7..000000000 --- a/notes/0.13.9/forceupdatems.markdown +++ /dev/null @@ -1,9 +0,0 @@ - [@ajsquared]: https://github.com/ajsquared - - -### Changes with compatibility implications - -### Improvements -- Adds `forceUpdateMs` key, that takes values of `Option[Long]` representing a number of milliseconds. If set, a full `update` will occur after that amount of time without needing to explicitly run the `update` task. By [@ajsquared][@ajsquared] - -### Fixes diff --git a/notes/0.13.9/forceupdateperiod.markdown b/notes/0.13.9/forceupdateperiod.markdown new file mode 100644 index 000000000..49e171b5d --- /dev/null +++ b/notes/0.13.9/forceupdateperiod.markdown @@ -0,0 +1,9 @@ + [@ajsquared]: https://github.com/ajsquared + + +### Changes with compatibility implications + +### Improvements +- Adds `forceUpdatePeriod` key, that takes values of `Option[FiniteDuration]`. If set, a full `update` will occur after that amount of time without needing to explicitly run the `update` task. By [@ajsquared][@ajsquared] + +### Fixes diff --git a/sbt/src/sbt-test/dependency-management/force-update-ms/build.sbt b/sbt/src/sbt-test/dependency-management/force-update-period/build.sbt similarity index 100% rename from sbt/src/sbt-test/dependency-management/force-update-ms/build.sbt rename to sbt/src/sbt-test/dependency-management/force-update-period/build.sbt diff --git a/sbt/src/sbt-test/dependency-management/force-update-ms/test b/sbt/src/sbt-test/dependency-management/force-update-period/test similarity index 54% rename from sbt/src/sbt-test/dependency-management/force-update-ms/test rename to sbt/src/sbt-test/dependency-management/force-update-period/test index f88058665..39e776d09 100644 --- a/sbt/src/sbt-test/dependency-management/force-update-ms/test +++ b/sbt/src/sbt-test/dependency-management/force-update-period/test @@ -6,6 +6,6 @@ $ sleep 10000 > compile # This is expected to fail -> checkLastUpdateTime -> set forceUpdateMs := Some(5000) +> set forceUpdatePeriod := Some(new scala.concurrent.duration.FiniteDuration(5000, java.util.concurrent.TimeUnit.MILLISECONDS)) > compile > checkLastUpdateTime \ No newline at end of file