From b382cf464d91814740379bcf3e93e7e368738f73 Mon Sep 17 00:00:00 2001 From: Dan Sanduleac Date: Mon, 19 May 2014 18:31:43 +0100 Subject: [PATCH] build projects' transitiveUpdate to depend on globalPluginUpdate --- main/src/main/scala/sbt/Defaults.scala | 3 ++- main/src/main/scala/sbt/GlobalPlugin.scala | 17 ++++++++++++----- main/src/main/scala/sbt/Keys.scala | 1 + 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index a6d696342..81db813de 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -301,7 +301,8 @@ object Defaults extends BuildCommon { import ScopeFilter.Make.{ inDependencies => inDeps, _ } val selectDeps = ScopeFilter(inDeps(ThisProject, includeRoot = false)) val allUpdates = update.?.all(selectDeps) - Def.task { allUpdates.value.flatten } + // If I am a "build" (a project inside project/) then I have a globalPluginUpdate. + Def.task { allUpdates.value.flatten ++ globalPluginUpdate.?.value } } def watchSetting: Initialize[Watched] = (pollInterval, thisProjectRef, watchingMessage, triggeredMessage) { (interval, base, msg, trigMsg) => diff --git a/main/src/main/scala/sbt/GlobalPlugin.scala b/main/src/main/scala/sbt/GlobalPlugin.scala index 8118c84e1..d1339c8f1 100644 --- a/main/src/main/scala/sbt/GlobalPlugin.scala +++ b/main/src/main/scala/sbt/GlobalPlugin.scala @@ -18,6 +18,7 @@ object GlobalPlugin { projectDescriptors ~= { _ ++ gp.descriptors }, projectDependencies ++= gp.projectID +: gp.dependencies, resolvers <<= resolvers { rs => (rs ++ gp.resolvers).distinct }, + globalPluginUpdate := gp.updateReport, // TODO: these shouldn't be required (but are): the project* settings above should take care of this injectInternalClasspath(Runtime, gp.internalClasspath), injectInternalClasspath(Compile, gp.internalClasspath) @@ -44,10 +45,16 @@ object GlobalPlugin { { import structure.{ data, root, rootProject } val p: Scope = Scope.GlobalScope in ProjectRef(root, rootProject(root)) - val taskInit = (projectID, projectDependencies, projectDescriptors, resolvers, fullClasspath in Runtime, internalDependencyClasspath in Runtime, exportedProducts in Runtime, ivyModule) map { - (pid, pdeps, pdescs, rs, cp, intcp, prods, mod) => - val depMap = pdescs + mod.dependencyMapping(state.log) - GlobalPluginData(pid, pdeps, depMap, rs, cp, (prods ++ intcp).distinct) + + val taskInit = Def.task { + val intcp = (internalDependencyClasspath in Runtime).value + val prods = (exportedProducts in Runtime).value + val depMap = projectDescriptors.value + ivyModule.value.dependencyMapping(state.log) + // If we reference it directly (if it's an executionRoot) then it forces an update, which is not what we want. + val updateReport = Def.taskDyn { Def.task { update.value } }.value + + GlobalPluginData(projectID.value, projectDependencies.value, depMap, resolvers.value, (fullClasspath in Runtime).value, + (prods ++ intcp).distinct, updateReport) } val resolvedTaskInit = taskInit mapReferenced Project.mapScope(Scope replaceThis p) val task = resolvedTaskInit evaluate data @@ -72,5 +79,5 @@ object GlobalPlugin { version := "0.0" )) } -final case class GlobalPluginData(projectID: ModuleID, dependencies: Seq[ModuleID], descriptors: Map[ModuleRevisionId, ModuleDescriptor], resolvers: Seq[Resolver], fullClasspath: Classpath, internalClasspath: Classpath) +final case class GlobalPluginData(projectID: ModuleID, dependencies: Seq[ModuleID], descriptors: Map[ModuleRevisionId, ModuleDescriptor], resolvers: Seq[Resolver], fullClasspath: Classpath, internalClasspath: Classpath, updateReport: UpdateReport) final case class GlobalPlugin(data: GlobalPluginData, structure: BuildStructure, inject: Seq[Setting[_]], base: File) diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index 1f46e57c7..8c4b3f3b2 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -345,6 +345,7 @@ object Keys { val stateStreams = AttributeKey[Streams]("streams-manager", "Streams manager, which provides streams for different contexts. Setting this on State will override the default Streams implementation.") val resolvedScoped = Def.resolvedScoped val pluginData = TaskKey[PluginData]("plugin-data", "Information from the plugin build needed in the main build definition.", DTask) + val globalPluginUpdate = TaskKey[UpdateReport]("global-plugin-update", "A hook to get the UpdateReport of the global plugin.", DTask) // wrapper to work around SI-2915 private[sbt] final class TaskProgress(val progress: ExecuteProgress[Task])