Add -Dsbt.cli.nodelegation option to experiment with no delegation for running/showing tasks/settings from the command line.

With this set to true, the following is no longer allowed for example:

> compile:update
This commit is contained in:
Mark Harrah 2013-11-25 21:03:40 -05:00
parent 5174f44dc3
commit 5f7a327e5e
2 changed files with 20 additions and 19 deletions

View File

@ -92,23 +92,23 @@ object Act
val (selects, globals) = ss.partition(_.key.scope.task.isSelect) val (selects, globals) = ss.partition(_.key.scope.task.isSelect)
if(globals.nonEmpty) globals else selects if(globals.nonEmpty) globals else selects
} }
def noValidKeys = failure("No such key.") def noValidKeys = failure("No such key.")
def showAmbiguous(keys: Seq[ScopedKey[_]])(implicit show: Show[ScopedKey[_]]): String = def showAmbiguous(keys: Seq[ScopedKey[_]])(implicit show: Show[ScopedKey[_]]): String =
keys.take(3).map(x => show(x)).mkString("", ", ", if(keys.size > 3) ", ..." else "") keys.take(3).map(x => show(x)).mkString("", ", ", if(keys.size > 3) ", ..." else "")
def isValid(data: Settings[Scope])(parsed: ParsedKey): Boolean = def isValid(data: Settings[Scope])(parsed: ParsedKey): Boolean =
{ {
val key = parsed.key val key = parsed.key
data.definingScope(key.scope, key.key) == Some(key.scope) data.definingScope(key.scope, key.key) == Some(key.scope)
} }
def examples(p: Parser[String], exs: Set[String], label: String): Parser[String] = def examples(p: Parser[String], exs: Set[String], label: String): Parser[String] =
p !!! ("Expected " + label) examples exs p !!! ("Expected " + label) examples exs
def examplesStrict(p: Parser[String], exs: Set[String], label: String): Parser[String] = def examplesStrict(p: Parser[String], exs: Set[String], label: String): Parser[String] =
filterStrings(examples(p, exs, label), exs, label) filterStrings(examples(p, exs, label), exs, label)
def optionalAxis[T](p: Parser[T], ifNone: ScopeAxis[T]): Parser[ScopeAxis[T]] = def optionalAxis[T](p: Parser[T], ifNone: ScopeAxis[T]): Parser[ScopeAxis[T]] =
p.? map { opt => toAxis(opt, ifNone) } p.? map { opt => toAxis(opt, ifNone) }
def toAxis[T](opt: Option[T], ifNone: ScopeAxis[T]): ScopeAxis[T] = def toAxis[T](opt: Option[T], ifNone: ScopeAxis[T]): ScopeAxis[T] =
@ -235,7 +235,7 @@ object Act
import extracted.{showKey, structure} import extracted.{showKey, structure}
import Aggregation.evaluatingParser import Aggregation.evaluatingParser
showParser.flatMap { show => showParser.flatMap { show =>
val akp = aggregatedKeyParser(extracted) val akp = aggregatedKeyParser(extracted)
def evaluate(kvs: Seq[ScopedKey[T]] forSome { type T}): Parser[() => State] = def evaluate(kvs: Seq[ScopedKey[T]] forSome { type T}): Parser[() => State] =
evaluatingParser(state, structure, Aggregation.defaultShow(state, show))( keyValues(structure)(kvs) ) evaluatingParser(state, structure, Aggregation.defaultShow(state, show))( keyValues(structure)(kvs) )
def reconstruct(arg: String): String = ShowCommand + " " + arg def reconstruct(arg: String): String = ShowCommand + " " + arg
@ -263,10 +263,10 @@ object Act
def keyValues[T](extracted: Extracted)(keys: Seq[ScopedKey[T]]): Values[T] = keyValues(extracted.structure)(keys) def keyValues[T](extracted: Extracted)(keys: Seq[ScopedKey[T]]): Values[T] = keyValues(extracted.structure)(keys)
def keyValues[T](structure: BuildStructure)(keys: Seq[ScopedKey[T]]): Values[T] = def keyValues[T](structure: BuildStructure)(keys: Seq[ScopedKey[T]]): Values[T] =
keys.flatMap { key => keys.flatMap { key =>
structure.data.get(key.scope, key.key) map { value => getValue(structure.data, key.scope, key.key) map { value => KeyValue(key, value) }
KeyValue(key, value)
}
} }
private[this] def getValue[T](data: Settings[Scope], scope: Scope, key: AttributeKey[T]): Option[T] =
if(java.lang.Boolean.getBoolean("sbt.cli.nodelegation")) data.getDirect(scope, key) else data.get(scope, key)
def requireSession[T](s: State, p: => Parser[T]): Parser[T] = def requireSession[T](s: State, p: => Parser[T]): Parser[T] =
if(s get sessionSettings isEmpty) failure("No project loaded") else p if(s get sessionSettings isEmpty) failure("No project loaded") else p

View File

@ -13,6 +13,7 @@ sealed trait Settings[Scope]
def definingScope(scope: Scope, key: AttributeKey[_]): Option[Scope] def definingScope(scope: Scope, key: AttributeKey[_]): Option[Scope]
def allKeys[T](f: (Scope, AttributeKey[_]) => T): Seq[T] def allKeys[T](f: (Scope, AttributeKey[_]) => T): Seq[T]
def get[T](scope: Scope, key: AttributeKey[T]): Option[T] def get[T](scope: Scope, key: AttributeKey[T]): Option[T]
def getDirect[T](scope: Scope, key: AttributeKey[T]): Option[T]
def set[T](scope: Scope, key: AttributeKey[T], value: T): Settings[Scope] def set[T](scope: Scope, key: AttributeKey[T], value: T): Settings[Scope]
} }
@ -23,11 +24,11 @@ private final class Settings0[Scope](val data: Map[Scope, AttributeMap], val del
def allKeys[T](f: (Scope, AttributeKey[_]) => T): Seq[T] = data.flatMap { case (scope, map) => map.keys.map(k => f(scope, k)) } toSeq; def allKeys[T](f: (Scope, AttributeKey[_]) => T): Seq[T] = data.flatMap { case (scope, map) => map.keys.map(k => f(scope, k)) } toSeq;
def get[T](scope: Scope, key: AttributeKey[T]): Option[T] = def get[T](scope: Scope, key: AttributeKey[T]): Option[T] =
delegates(scope).toStream.flatMap(sc => scopeLocal(sc, key) ).headOption delegates(scope).toStream.flatMap(sc => getDirect(sc, key) ).headOption
def definingScope(scope: Scope, key: AttributeKey[_]): Option[Scope] = def definingScope(scope: Scope, key: AttributeKey[_]): Option[Scope] =
delegates(scope).toStream.filter(sc => scopeLocal(sc, key).isDefined ).headOption delegates(scope).toStream.filter(sc => getDirect(sc, key).isDefined ).headOption
private def scopeLocal[T](scope: Scope, key: AttributeKey[T]): Option[T] = def getDirect[T](scope: Scope, key: AttributeKey[T]): Option[T] =
(data get scope).flatMap(_ get key) (data get scope).flatMap(_ get key)
def set[T](scope: Scope, key: AttributeKey[T], value: T): Settings[Scope] = def set[T](scope: Scope, key: AttributeKey[T], value: T): Settings[Scope] =
@ -73,8 +74,8 @@ trait Init[Scope]
def uniform[S,T](inputs: Seq[Initialize[S]])(f: Seq[S] => T): Initialize[T] = def uniform[S,T](inputs: Seq[Initialize[S]])(f: Seq[S] => T): Initialize[T] =
new Apply[({ type l[L[x]] = List[L[S]] })#l, T](f, inputs.toList, AList.seq[S]) new Apply[({ type l[L[x]] = List[L[S]] })#l, T](f, inputs.toList, AList.seq[S])
/** Constructs a derived setting that will be automatically defined in every scope where one of its dependencies /** Constructs a derived setting that will be automatically defined in every scope where one of its dependencies
* is explicitly defined and the where the scope matches `filter`. * is explicitly defined and the where the scope matches `filter`.
* A setting initialized with dynamic dependencies is only allowed if `allowDynamic` is true. * A setting initialized with dynamic dependencies is only allowed if `allowDynamic` is true.
* Only the static dependencies are tracked, however. */ * Only the static dependencies are tracked, however. */
final def derive[T](s: Setting[T], allowDynamic: Boolean = false, filter: Scope => Boolean = const(true), trigger: AttributeKey[_] => Boolean = const(true)): Setting[T] = { final def derive[T](s: Setting[T], allowDynamic: Boolean = false, filter: Scope => Boolean = const(true), trigger: AttributeKey[_] => Boolean = const(true)): Setting[T] = {
@ -154,7 +155,7 @@ trait Init[Scope]
def addLocal(init: Seq[Setting[_]])(implicit scopeLocal: ScopeLocal): Seq[Setting[_]] = def addLocal(init: Seq[Setting[_]])(implicit scopeLocal: ScopeLocal): Seq[Setting[_]] =
init.flatMap( _.dependencies flatMap scopeLocal ) ++ init init.flatMap( _.dependencies flatMap scopeLocal ) ++ init
def delegate(sMap: ScopedMap)(implicit delegates: Scope => Seq[Scope], display: Show[ScopedKey[_]]): ScopedMap = def delegate(sMap: ScopedMap)(implicit delegates: Scope => Seq[Scope], display: Show[ScopedKey[_]]): ScopedMap =
{ {
def refMap(ref: Setting[_], isFirst: Boolean) = new ValidateRef { def apply[T](k: ScopedKey[T]) = def refMap(ref: Setting[_], isFirst: Boolean) = new ValidateRef { def apply[T](k: ScopedKey[T]) =
@ -178,7 +179,7 @@ trait Init[Scope]
val definedAt = skeys.find( sk => (!isFirst || ref.key != sk) && (sMap contains sk)) val definedAt = skeys.find( sk => (!isFirst || ref.key != sk) && (sMap contains sk))
definedAt.toRight(Undefined(ref, k)) definedAt.toRight(Undefined(ref, k))
} }
private[this] def applyInits(ordered: Seq[Compiled[_]])(implicit delegates: Scope => Seq[Scope]): Settings[Scope] = private[this] def applyInits(ordered: Seq[Compiled[_]])(implicit delegates: Scope => Seq[Scope]): Settings[Scope] =
{ {
val x = java.util.concurrent.Executors.newFixedThreadPool(Runtime.getRuntime.availableProcessors) val x = java.util.concurrent.Executors.newFixedThreadPool(Runtime.getRuntime.availableProcessors)
@ -253,7 +254,7 @@ trait Init[Scope]
override def toString = showFullKey(key) override def toString = showFullKey(key)
} }
final class Flattened(val key: ScopedKey[_], val dependencies: Iterable[ScopedKey[_]]) final class Flattened(val key: ScopedKey[_], val dependencies: Iterable[ScopedKey[_]])
def flattenLocals(compiled: CompiledMap): Map[ScopedKey[_],Flattened] = def flattenLocals(compiled: CompiledMap): Map[ScopedKey[_],Flattened] =
{ {
import collection.breakOut import collection.breakOut
@ -261,7 +262,7 @@ trait Init[Scope]
val ordered = Dag.topologicalSort(locals)(_.dependencies.flatMap(dep => if(dep.key.isLocal) Seq[Compiled[_]](compiled(dep)) else Nil)) val ordered = Dag.topologicalSort(locals)(_.dependencies.flatMap(dep => if(dep.key.isLocal) Seq[Compiled[_]](compiled(dep)) else Nil))
def flatten(cmap: Map[ScopedKey[_],Flattened], key: ScopedKey[_], deps: Iterable[ScopedKey[_]]): Flattened = def flatten(cmap: Map[ScopedKey[_],Flattened], key: ScopedKey[_], deps: Iterable[ScopedKey[_]]): Flattened =
new Flattened(key, deps.flatMap(dep => if(dep.key.isLocal) cmap(dep).dependencies else dep :: Nil)) new Flattened(key, deps.flatMap(dep => if(dep.key.isLocal) cmap(dep).dependencies else dep :: Nil))
val empty = Map.empty[ScopedKey[_],Flattened] val empty = Map.empty[ScopedKey[_],Flattened]
val flattenedLocals = (empty /: ordered) { (cmap, c) => cmap.updated(c.key, flatten(cmap, c.key, c.dependencies)) } val flattenedLocals = (empty /: ordered) { (cmap, c) => cmap.updated(c.key, flatten(cmap, c.key, c.dependencies)) }
compiled flatMap{ case (key, comp) => compiled flatMap{ case (key, comp) =>
@ -365,7 +366,7 @@ trait Init[Scope]
out ++= ds out ++= ds
addDefs(ds) addDefs(ds)
process(ds ::: ss) process(ds ::: ss)
case Nil => case Nil =>
} }
process(defs.toList) process(defs.toList)
out.toList ++ defs out.toList ++ defs
@ -437,7 +438,7 @@ trait Init[Scope]
override final def hashCode = id.hashCode override final def hashCode = id.hashCode
override final def equals(o: Any): Boolean = o match { case d: DefaultSetting[_] => d.id == id; case _ => false } override final def equals(o: Any): Boolean = o match { case d: DefaultSetting[_] => d.id == id; case _ => false }
} }
private[this] def handleUndefined[T](vr: ValidatedInit[T]): Initialize[T] = vr match { private[this] def handleUndefined[T](vr: ValidatedInit[T]): Initialize[T] = vr match {
case Left(undefs) => throw new RuntimeUndefined(undefs) case Left(undefs) => throw new RuntimeUndefined(undefs)