'get' now shows defining scope, related definitions, dependencies

This commit is contained in:
Mark Harrah 2011-02-06 11:33:56 -05:00
parent c9b1b507cd
commit 06a346a543
4 changed files with 34 additions and 9 deletions

View File

@ -238,13 +238,12 @@ object Commands
def get = Command.single(GetCommand, getBrief, getDetailed) { (s, arg) =>
val extracted = Project extract s
import extracted._
val result = session.currentEval().eval(arg, srcName = "get", imports = autoImports(extracted), tpeName = Some("sbt.ScopedSetting[_]"))
val scoped = result.value.asInstanceOf[ScopedSetting[_]]
val result = session.currentEval().eval(arg, srcName = "get", imports = autoImports(extracted), tpeName = Some("sbt.Scoped"))
val scoped = result.value.asInstanceOf[Scoped]
val resolve = Scope.resolveScope(Load.projectScope(curi, cid), curi, rootProject)
(structure.data.get(resolve(scoped.scope), scoped.key)) match {
case None => logger(s).error("No entry for key."); s.fail
case Some(v) => logger(s).info(v.toString); s
}
val detailString = Project.details(structure, resolve(scoped.scope), scoped.key)
logger(s).info(detailString)
s
}
def autoImports(extracted: Extracted): EvalImports = new EvalImports(imports(extracted), "<auto-imports>")
def imports(extracted: Extracted): Seq[(String,Int)] =

View File

@ -106,6 +106,24 @@ object Project extends Init[Scope]
throw new Uninitialized(u.key, u.refKey, msg)
}
def details(structure: Load.BuildStructure, scope: Scope, key: AttributeKey[_]): String =
{
val scoped = ScopedKey(scope,key)
val value =
(structure.data.get(scope, key)) match {
case None => "No entry for key."
case Some(v: Task[_]) => "Task"
case Some(v: InputTask[_]) => "Input task"
case Some(v) => "Value:\n\t" + v.toString
}
val definedIn = structure.data.definingScope(scope, key) match { case Some(sc) => "Provided by:\n\t" + display(scoped); case None => "" }
val cMap = compiled(structure.settings)(structure.delegates, structure.scopeLocal)
val related = cMap.keys.filter(k => k.key == key && k.scope != scope)
val depends = cMap.get(scoped) match { case Some(c) => c.dependencies.toSet; case None => Set.empty }
def printScopes(label: String, scopes: Iterable[ScopedKey[_]]) =
if(scopes.isEmpty) "" else scopes.map(display).mkString(label + ":\n\t", "\n\t", "\n")
value + "\n" + definedIn + "\n" + printScopes("Dependencies", depends) + printScopes("Related", related)
}
val SessionKey = AttributeKey[SessionSettings]("session-settings")
val StructureKey = AttributeKey[Load.BuildStructure]("build-structure")

View File

@ -59,7 +59,7 @@ object Scope
import scope.{project, config, task, extra}
val projectPrefix = project.foldStrict(Project.display, "*", ".")
val configPrefix = config.foldStrict(display, "*:", ".:")
val taskPostfix = task.foldStrict(x => (" for " + x.label) :: Nil, Nil, Nil)
val taskPostfix = task.foldStrict(x => ("for " + x.label) :: Nil, Nil, Nil)
val extraPostfix = extra.foldStrict(_.entries.map( _.toString ).toList, Nil, Nil)
val extras = taskPostfix ::: extraPostfix
val postfix = if(extras.isEmpty) "" else extras.mkString("(", ", ", ")")

View File

@ -10,6 +10,7 @@ sealed trait Settings[Scope]
def data: Map[Scope, AttributeMap]
def keys(scope: Scope): Set[AttributeKey[_]]
def scopes: Set[Scope]
def definingScope(scope: Scope, key: AttributeKey[_]): Option[Scope]
def allKeys[T](f: (Scope, AttributeKey[_]) => T): Seq[T]
def get[T](scope: Scope, key: AttributeKey[T]): Option[T]
def set[T](scope: Scope, key: AttributeKey[T], value: T): Settings[Scope]
@ -23,6 +24,8 @@ private final class Settings0[Scope](val data: Map[Scope, AttributeMap], val del
def get[T](scope: Scope, key: AttributeKey[T]): Option[T] =
delegates(scope).toStream.flatMap(sc => scopeLocal(sc, key) ).headOption
def definingScope(scope: Scope, key: AttributeKey[_]): Option[Scope] =
delegates(scope).toStream.filter(sc => scopeLocal(sc, key).isDefined ).headOption
private def scopeLocal[T](scope: Scope, key: AttributeKey[T]): Option[T] =
(data get scope).flatMap(_ get key)
@ -64,15 +67,20 @@ trait Init[Scope]
def getValue[T](s: Settings[Scope], k: ScopedKey[T]) = s.get(k.scope, k.key).get
def asFunction[T](s: Settings[Scope]): ScopedKey[T] => T = k => getValue(s, k)
def make(init: Seq[Setting[_]])(implicit delegates: Scope => Seq[Scope], scopeLocal: ScopedKey[_] => Seq[Setting[_]]): Settings[Scope] =
def compiled(init: Seq[Setting[_]])(implicit delegates: Scope => Seq[Scope], scopeLocal: ScopedKey[_] => Seq[Setting[_]]): CompiledMap =
{
// prepend per-scope settings
val withLocal = addLocal(init)(scopeLocal)
// group by Scope/Key, dropping dead initializations
val sMap: ScopedMap = grouped(withLocal)
// delegate references to undefined values according to 'delegates'
val dMap: ScopedMap = delegate(sMap)(delegates)
// merge Seq[Setting[_]] into Compiled
val cMap: CompiledMap = compile(dMap)
compile(dMap)
}
def make(init: Seq[Setting[_]])(implicit delegates: Scope => Seq[Scope], scopeLocal: ScopedKey[_] => Seq[Setting[_]]): Settings[Scope] =
{
val cMap = compiled(init)(delegates, scopeLocal)
// order the initializations. cyclic references are detected here.
val ordered: Seq[Compiled] = sort(cMap)
// evaluation: apply the initializations.