From e7b8cbfe010ee447546005e1fdcbfe1de599142a Mon Sep 17 00:00:00 2001 From: jvican Date: Thu, 27 Apr 2017 16:00:48 +0200 Subject: [PATCH] Move `cachedUpdate` to new `DependencyResolver` The `cachedUpdate` implementation does not need to be in `Defaults` since it's not using any of the tasks/settings defined there, that's `updateTask`'s job. This commit moves the utilities required by `updateTask` to the `sbt.internal.librarymanagement` namespace. --- main/src/main/scala/sbt/Defaults.scala | 103 +-------------- .../DependencyResolver.scala | 117 ++++++++++++++++++ 2 files changed, 118 insertions(+), 102 deletions(-) create mode 100644 main/src/main/scala/sbt/internal/librarymanagement/DependencyResolver.scala diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index cf894a32c..4965653a4 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -2119,7 +2119,7 @@ object Classpaths { else (evictionWarningOptions in update).value } - cachedUpdate( + DependencyResolver.cachedUpdate( s.cacheStoreFactory.sub(updateCacheName.value), Reference.display(thisProjectRef.value), ivyModule.value, @@ -2138,107 +2138,6 @@ object Classpaths { ) } - private type UpdateInputs = IvyConfiguration :+: ModuleSettings :+: UpdateConfiguration :+: HNil - - private[sbt] def cachedUpdate( - cacheStoreFactory: CacheStoreFactory, - label: String, - module: IvySbt#Module, - updateConfig: UpdateConfiguration, - transform: UpdateReport => UpdateReport, - skip: Boolean, - force: Boolean, - depsUpdated: Boolean, - uwConfig: UnresolvedWarningConfiguration, - logicalClock: LogicalClock, - depDir: Option[File], - ewo: EvictionWarningOptions, - mavenStyle: Boolean, - compatWarning: CompatibilityWarningOptions, - log: Logger - ): UpdateReport = { - - /* Resolve the module settings from the inputs. */ - def resolve(inputs: UpdateInputs): UpdateReport = { - import ShowLines._ - - log.info(s"Updating $label...") - val reportOrUnresolved: Either[UnresolvedWarning, UpdateReport] = - IvyActions.updateEither(module, updateConfig, uwConfig, logicalClock, depDir, log) - - val report = reportOrUnresolved match { - case Right(report0) => report0 - case Left(unresolvedWarning) => - unresolvedWarning.lines.foreach(log.warn(_)) - throw unresolvedWarning.resolveException - } - log.info("Done updating.") - val finalReport = transform(report) - - // Warn of any eviction and compatibility warnings - val ew = EvictionWarning(module, ewo, finalReport, log) - ew.lines foreach { log.warn(_) } - ew.infoAllTheThings foreach { log.info(_) } - CompatibilityWarning.run(compatWarning, module, mavenStyle, log) - - finalReport - } - - /* Check if a update report is still up to date or we must resolve again. */ - def upToDate(inChanged: Boolean, out: UpdateReport): Boolean = { - !force && - !depsUpdated && - !inChanged && - out.allFiles.forall(f => fileUptodate(f, out.stamps)) && - fileUptodate(out.cachedDescriptor, out.stamps) - } - - /* Skip resolve if last output exists, otherwise error. */ - def skipResolve(cache: CacheStore): UpdateInputs => UpdateReport = { - import LibraryManagementCodec._ - Tracked.lastOutput[UpdateInputs, UpdateReport](cache) { - case (_, Some(out)) => out - case _ => - sys.error("Skipping update requested, but update has not previously run successfully.") - } - } - - def doResolve(cache: CacheStore): UpdateInputs => UpdateReport = { - val doCachedResolve = { (inChanged: Boolean, updateInputs: UpdateInputs) => - import LibraryManagementCodec._ - val cachedResolve = Tracked.lastOutput[UpdateInputs, UpdateReport](cache) { - case (_, Some(out)) if upToDate(inChanged, out) => out - case _ => resolve(updateInputs) - } - import scala.util.control.Exception.catching - catching(classOf[NullPointerException], classOf[OutOfMemoryError]) - .withApply { t => - val resolvedAgain = resolve(updateInputs) - val culprit = t.getClass.getSimpleName - log.warn(s"Update task caching failed due to $culprit.") - log.warn("Report the following output to sbt:") - resolvedAgain.toString.lines foreach { log.warn(_) } - log.trace(t) - resolvedAgain - } - .apply(cachedResolve(updateInputs)) - } - - import sbt.internal.librarymanagement.AltLibraryManagementCodec._ - Tracked.inputChanged(cacheStoreFactory.make("inputs"))(doCachedResolve) - } - - // Get the handler to use and feed it in the inputs - val ivyConfig = module.owner.configuration - val settings = module.moduleSettings - val outStore = cacheStoreFactory.make("output") - val handler = if (skip && !force) skipResolve(outStore) else doResolve(outStore) - handler(ivyConfig :+: settings :+: updateConfig :+: HNil) - } - - private[this] def fileUptodate(file: File, stamps: Map[File, Long]): Boolean = - stamps.get(file).forall(_ == file.lastModified) - private[sbt] def dependencyPositionsTask: Initialize[Task[Map[ModuleID, SourcePosition]]] = Def.task { val projRef = thisProjectRef.value diff --git a/main/src/main/scala/sbt/internal/librarymanagement/DependencyResolver.scala b/main/src/main/scala/sbt/internal/librarymanagement/DependencyResolver.scala new file mode 100644 index 000000000..a63a1e19f --- /dev/null +++ b/main/src/main/scala/sbt/internal/librarymanagement/DependencyResolver.scala @@ -0,0 +1,117 @@ +package sbt.internal.librarymanagement + +import java.io.File + +import sbt.internal.util.Types._ +import sbt.internal.util.HNil +import sbt.librarymanagement._ +import sbt.util.{ CacheStore, CacheStoreFactory, Logger, Tracked } +import sbt.librarymanagement.syntax._ +import sbt.util.CacheImplicits._ + +object DependencyResolver { + + private type UpdateInputs = IvyConfiguration :+: ModuleSettings :+: UpdateConfiguration :+: HNil + + private[sbt] def cachedUpdate( + cacheStoreFactory: CacheStoreFactory, + label: String, + module: IvySbt#Module, + updateConfig: UpdateConfiguration, + transform: UpdateReport => UpdateReport, + skip: Boolean, + force: Boolean, + depsUpdated: Boolean, + uwConfig: UnresolvedWarningConfiguration, + logicalClock: LogicalClock, + depDir: Option[File], + ewo: EvictionWarningOptions, + mavenStyle: Boolean, + compatWarning: CompatibilityWarningOptions, + log: Logger + ): UpdateReport = { + + /* Resolve the module settings from the inputs. */ + def resolve(inputs: UpdateInputs): UpdateReport = { + import sbt.util.ShowLines._ + + log.info(s"Updating $label...") + val reportOrUnresolved: Either[UnresolvedWarning, UpdateReport] = + IvyActions.updateEither(module, updateConfig, uwConfig, logicalClock, depDir, log) + + val report = reportOrUnresolved match { + case Right(report0) => report0 + case Left(unresolvedWarning) => + unresolvedWarning.lines.foreach(log.warn(_)) + throw unresolvedWarning.resolveException + } + log.info("Done updating.") + val finalReport = transform(report) + + // Warn of any eviction and compatibility warnings + val ew = EvictionWarning(module, ewo, finalReport, log) + ew.lines.foreach(log.warn(_)) + ew.infoAllTheThings.foreach(log.info(_)) + CompatibilityWarning.run(compatWarning, module, mavenStyle, log) + + finalReport + } + + /* Check if a update report is still up to date or we must resolve again. */ + def upToDate(inChanged: Boolean, out: UpdateReport): Boolean = { + !force && + !depsUpdated && + !inChanged && + out.allFiles.forall(f => fileUptodate(f, out.stamps)) && + fileUptodate(out.cachedDescriptor, out.stamps) + } + + /* Skip resolve if last output exists, otherwise error. */ + def skipResolve(cache: CacheStore): UpdateInputs => UpdateReport = { + import sbt.librarymanagement.LibraryManagementCodec._ + Tracked.lastOutput[UpdateInputs, UpdateReport](cache) { + case (_, Some(out)) => out + case _ => + sys.error("Skipping update requested, but update has not previously run successfully.") + } + } + + 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 _ => resolve(updateInputs) + } + import scala.util.control.Exception.catching + catching(classOf[NullPointerException], classOf[OutOfMemoryError]) + .withApply { t => + val resolvedAgain = resolve(updateInputs) + val culprit = t.getClass.getSimpleName + log.warn(s"Update task caching failed due to $culprit.") + log.warn("Report the following output to sbt:") + resolvedAgain.toString.lines foreach { + log.warn(_) + } + log.trace(t) + resolvedAgain + } + .apply(cachedResolve(updateInputs)) + } + + import sbt.internal.librarymanagement.AltLibraryManagementCodec._ + Tracked.inputChanged(cacheStoreFactory.make("inputs"))(doCachedResolve) + } + + // Get the handler to use and feed it in the inputs + val ivyConfig = module.owner.configuration + val settings = module.moduleSettings + val outStore = cacheStoreFactory.make("output") + val handler = if (skip && !force) skipResolve(outStore) else doResolve(outStore) + handler(ivyConfig :+: settings :+: updateConfig :+: HNil) + } + + private[this] def fileUptodate(file: File, stamps: Map[File, Long]): Boolean = + stamps.get(file).forall(_ == file.lastModified) + +}