diff --git a/main/Aggregation.scala b/main/Aggregation.scala index 839398924..44df95bff 100644 --- a/main/Aggregation.scala +++ b/main/Aggregation.scala @@ -37,11 +37,12 @@ final object Aggregation val extracted = Project extract s val toRun = ts map { case KeyValue(k,t) => t.map(v => KeyValue(k,v)) } join; + val roots = ts map { case KeyValue(k,_) => k } val config = extractedConfig(extracted, structure) val start = System.currentTimeMillis val (newS, result) = withStreams(structure, s){ str => - val transform = nodeView(s, str, extra.tasks, extra.values) + val transform = nodeView(s, str, roots, extra.tasks, extra.values) runTask(toRun, s,str, structure.index.triggers, config)(transform) } val stop = System.currentTimeMillis diff --git a/main/EvaluateTask.scala b/main/EvaluateTask.scala index 9510787ee..b5fb1e99a 100644 --- a/main/EvaluateTask.scala +++ b/main/EvaluateTask.scala @@ -6,7 +6,7 @@ package sbt import java.io.File import Project.{ScopedKey, Setting} import Keys.{streams, Streams, TaskStreams} - import Keys.{dummyState, dummyStreamsManager, streamsManager, taskDefinitionKey, transformState} + import Keys.{dummyRoots, dummyState, dummyStreamsManager, executionRoots, streamsManager, taskDefinitionKey, transformState} import Scope.{GlobalScope, ThisScope} import Types.const import scala.Console.{RED, RESET} @@ -56,7 +56,8 @@ object EvaluateTask def injectSettings: Seq[Setting[_]] = Seq( (state in GlobalScope) ::= dummyState, - (streamsManager in GlobalScope) ::= dummyStreamsManager + (streamsManager in GlobalScope) ::= dummyStreamsManager, + (executionRoots in GlobalScope) ::= dummyRoots ) def evalPluginDef(log: Logger)(pluginDef: BuildStructure, state: State): Seq[Attributed[File]] = @@ -111,10 +112,10 @@ object EvaluateTask val thisScope = Load.projectScope(ref) val resolvedScope = Scope.replaceThis(thisScope)( taskKey.scope ) for( t <- structure.data.get(resolvedScope, taskKey.key)) yield - (t, nodeView(state, streams)) + (t, nodeView(state, streams, taskKey :: Nil)) } - def nodeView[HL <: HList](state: State, streams: Streams, extraDummies: KList[Task, HL] = KNil, extraValues: HL = HNil): Execute.NodeView[Task] = - Transform(dummyStreamsManager :^: KCons(dummyState, extraDummies), streams :+: HCons(state, extraValues)) + def nodeView[HL <: HList](state: State, streams: Streams, roots: Seq[ScopedKey[_]], extraDummies: KList[Task, HL] = KNil, extraValues: HL = HNil): Execute.NodeView[Task] = + Transform(dummyRoots :^: dummyStreamsManager :^: KCons(dummyState, extraDummies), roots :+: streams :+: HCons(state, extraValues)) def runTask[T](root: Task[T], state: State, streams: Streams, triggers: Triggers[Task], config: EvaluateConfig)(implicit taskToNode: Execute.NodeView[Task]): (State, Result[T]) = { diff --git a/main/GlobalPlugin.scala b/main/GlobalPlugin.scala index e5793120c..3f0148d65 100644 --- a/main/GlobalPlugin.scala +++ b/main/GlobalPlugin.scala @@ -45,14 +45,16 @@ object GlobalPlugin val depMap = pdescs + mod.dependencyMapping(state.log) GlobalPluginData(pid, pdeps, depMap, rs, cp, prods ++ intcp) } - val task = taskInit mapReferenced Project.mapScope(Scope replaceThis p) evaluate data - evaluate(state, structure, task) + val resolvedTaskInit = taskInit mapReferenced Project.mapScope(Scope replaceThis p) + val task = resolvedTaskInit evaluate data + val roots = resolvedTaskInit.dependencies + evaluate(state, structure, task, roots) } - def evaluate[T](state: State, structure: BuildStructure, t: Task[T]): (State, T) = + def evaluate[T](state: State, structure: BuildStructure, t: Task[T], roots: Seq[ScopedKey[_]]): (State, T) = { import EvaluateTask._ withStreams(structure, state) { str => - val nv = nodeView(state, str) + val nv = nodeView(state, str, roots) val config = EvaluateTask.defaultConfig(Project.extract(state), structure) val (newS, result) = runTask(t, state, str, structure.index.triggers, config)(nv) (newS, processResult(result, newS.log)) diff --git a/main/Keys.scala b/main/Keys.scala index e235f8b42..cd13b6c9b 100644 --- a/main/Keys.scala +++ b/main/Keys.scala @@ -317,6 +317,7 @@ object Keys val streams = TaskKey[TaskStreams]("streams", "Provides streams for logging and persisting data.") val isDummyTask = AttributeKey[Boolean]("is-dummy-task", "Internal: used to identify dummy tasks. sbt injects values for these tasks at the start of task execution.") val taskDefinitionKey = AttributeKey[ScopedKey[_]]("task-definition-key", "Internal: used to map a task back to its ScopedKey.") + val (executionRoots, dummyRoots)= dummy[Seq[ScopedKey[_]]]("execution-roots", "The list of root tasks for this task execution. Roots are the top-level tasks that were directly requested to be run.") val (state, dummyState) = dummy[State]("state", "Current build state.") val (streamsManager, dummyStreamsManager) = dummy[Streams]("streams-manager", "Streams manager, which provides streams for different contexts.") val resolvedScoped = SettingKey[ScopedKey[_]]("resolved-scoped", "The ScopedKey for the referencing setting or task.")