From 840acba087cc0172665e38015e8565b306ccd72a Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 8 Aug 2014 00:53:09 -0400 Subject: [PATCH] Adds `dependencyPositions` task to explicitly track dependency positions. --- ivy/src/main/scala/sbt/IvyActions.scala | 6 ++--- .../actions/src/main/scala/sbt/CacheIvy.scala | 4 +-- main/src/main/scala/sbt/Defaults.scala | 27 ++++++++++--------- main/src/main/scala/sbt/Keys.scala | 1 + notes/0.13.6.md | 2 +- 5 files changed, 21 insertions(+), 19 deletions(-) diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index 988809fb0..4d69ae2c7 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -31,10 +31,10 @@ final case class GetClassifiersConfiguration(module: GetClassifiersModule, exclu final case class GetClassifiersModule(id: ModuleID, modules: Seq[ModuleID], configurations: Seq[Configuration], classifiers: Seq[String]) final class UnresolvedWarningConfiguration private[sbt] ( - val modulePositions: Seq[(ModuleID, SourcePosition)]) + val modulePositions: Map[ModuleID, SourcePosition]) object UnresolvedWarningConfiguration { - def apply(): UnresolvedWarningConfiguration = apply(Seq()) - def apply(modulePositions: Seq[(ModuleID, SourcePosition)]): UnresolvedWarningConfiguration = + def apply(): UnresolvedWarningConfiguration = apply(Map()) + def apply(modulePositions: Map[ModuleID, SourcePosition]): UnresolvedWarningConfiguration = new UnresolvedWarningConfiguration(modulePositions) } diff --git a/main/actions/src/main/scala/sbt/CacheIvy.scala b/main/actions/src/main/scala/sbt/CacheIvy.scala index 912d590ad..ace282948 100644 --- a/main/actions/src/main/scala/sbt/CacheIvy.scala +++ b/main/actions/src/main/scala/sbt/CacheIvy.scala @@ -56,6 +56,7 @@ object CacheIvy { /* def deliverIC: InputCache[IvyConfiguration :+: ModuleSettings :+: DeliverConfiguration :+: HNil] = implicitly def publishIC: InputCache[IvyConfiguration :+: ModuleSettings :+: PublishConfiguration :+: HNil] = implicitly*/ lazy val moduleIDSeqIC: InputCache[Seq[ModuleID]] = implicitly + lazy val modulePositionMapFormat: Format[Map[ModuleID, SourcePosition]] = implicitly implicit lazy val updateReportFormat: Format[UpdateReport] = { @@ -97,9 +98,6 @@ object CacheIvy { case (2, p, s, e) => RangePosition(p, LineRange(s, e)) } ) - implicit def unresolvedWarningConfigurationFormat: Format[UnresolvedWarningConfiguration] = - wrap[UnresolvedWarningConfiguration, (Seq[(ModuleID, SourcePosition)])](c => (c.modulePositions), { case ps => UnresolvedWarningConfiguration(ps) }) - private[this] final val DisabledValue = 0 private[this] final val BinaryValue = 1 private[this] final val FullValue = 2 diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 97b4ef4b1..037526a02 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -1101,7 +1101,8 @@ object Classpaths { transitiveUpdate <<= transitiveUpdateTask, updateCacheName := "update_cache" + (if (crossPaths.value) s"_${scalaBinaryVersion.value}" else ""), evictionWarningOptions in update := EvictionWarningOptions.default, - unresolvedWarningConfiguration in update <<= unresolvedWarningConfigurationTask, + dependencyPositions <<= dependencyPositionsTask, + unresolvedWarningConfiguration in update := UnresolvedWarningConfiguration(dependencyPositions.value), update <<= updateTask tag (Tags.Update, Tags.Network), update := { import ShowLines._ @@ -1220,7 +1221,7 @@ object Classpaths { updateReportFormat, excludeMap, moduleIDSeqIC, - unresolvedWarningConfigurationFormat + modulePositionMapFormat } def withExcludes(out: File, classifiers: Seq[String], lock: xsbti.GlobalLock)(f: Map[ModuleID, Set[String]] => UpdateReport): UpdateReport = @@ -1314,13 +1315,14 @@ object Classpaths { } private[this] def fileUptodate(file: File, stamps: Map[File, Long]): Boolean = stamps.get(file).forall(_ == file.lastModified) - private[sbt] def unresolvedWarningConfigurationTask: Initialize[Task[UnresolvedWarningConfiguration]] = Def.task { + private[sbt] def dependencyPositionsTask: Initialize[Task[Map[ModuleID, SourcePosition]]] = Def.task { val projRef = thisProjectRef.value val st = state.value val s = streams.value val cacheFile = s.cacheDirectory / updateCacheName.value - implicit val uwConfigCache = moduleIDSeqIC - def modulePositions: Seq[(ModuleID, SourcePosition)] = + implicit val depSourcePosCache = moduleIDSeqIC + implicit val outFormat = modulePositionMapFormat + def modulePositions: Map[ModuleID, SourcePosition] = try { val extracted = (Project extract st) val sk = (libraryDependencies in (GlobalScope in projRef)).scopedKey @@ -1329,18 +1331,19 @@ object Classpaths { (s.key.key == libraryDependencies.key) && (s.key.scope.project == Select(projRef)) } - settings flatMap { + Map(settings flatMap { case s: Setting[Seq[ModuleID]] @unchecked => s.init.evaluate(empty) map { _ -> s.pos } - } + }: _*) } catch { - case _: Throwable => Seq() + case _: Throwable => Map() } - val outCacheFile = cacheFile / "output_uwc" - val f = Tracked.inputChanged(cacheFile / "input_uwc") { (inChanged: Boolean, in: Seq[ModuleID]) => - val outCache = Tracked.lastOutput[Seq[ModuleID], UnresolvedWarningConfiguration](outCacheFile) { + + val outCacheFile = cacheFile / "output_dsp" + val f = Tracked.inputChanged(cacheFile / "input_dsp") { (inChanged: Boolean, in: Seq[ModuleID]) => + val outCache = Tracked.lastOutput[Seq[ModuleID], Map[ModuleID, SourcePosition]](outCacheFile) { case (_, Some(out)) if !inChanged => out - case _ => UnresolvedWarningConfiguration(modulePositions) + case _ => modulePositions } outCache(in) } diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index 99036100b..8ff0aefe1 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -244,6 +244,7 @@ object Keys { val updateConfiguration = SettingKey[UpdateConfiguration]("update-configuration", "Configuration for resolving and retrieving managed dependencies.", DSetting) val updateOptions = SettingKey[UpdateOptions]("update-options", "Options for resolving managed dependencies.", DSetting) val unresolvedWarningConfiguration = TaskKey[UnresolvedWarningConfiguration]("unresolved-warning-configuration", "Configuration for unresolved dependency warning.", DTask) + val dependencyPositions = TaskKey[Map[ModuleID, SourcePosition]]("dependency-positions", "Source positions where the dependencies are defined.", DTask) val ivySbt = TaskKey[IvySbt]("ivy-sbt", "Provides the sbt interface to Ivy.", CTask) val ivyModule = TaskKey[IvySbt#Module]("ivy-module", "Provides the sbt interface to a configured Ivy module.", CTask) val updateCacheName = TaskKey[String]("updateCacheName", "Defines the directory name used to store the update cache files (inside the streams cacheDirectory).", DTask) diff --git a/notes/0.13.6.md b/notes/0.13.6.md index a1e0984a6..97745ca12 100644 --- a/notes/0.13.6.md +++ b/notes/0.13.6.md @@ -95,7 +95,7 @@ sbt 0.13.6 now allows `enablePlugins` and `disablePlugins` to be written directl ### Unresolved dependencies error sbt 0.13.6 will try to reconstruct dependencies tree when it fails to resolve a managed dependency. -This is an approximation, but it should help you figure out where the problematic dependency is coming from: +This is an approximation, but it should help you figure out where the problematic dependency is coming from. When possible sbt will display the source position next to the modules: [warn] :::::::::::::::::::::::::::::::::::::::::::::: [warn] :: UNRESOLVED DEPENDENCIES ::