display message after 'set' with defined and affected scopes+keys

This commit is contained in:
Mark Harrah 2012-07-13 13:40:59 -04:00
parent ad621ecbee
commit d6d922a858
3 changed files with 121 additions and 27 deletions

View File

@ -206,15 +206,14 @@ object BuiltinCommands
val extracted = Project extract s
import extracted._
val settings = EvaluateConfigurations.evaluateSetting(session.currentEval(), "<set>", imports(extracted), arg, LineRange(0,0))(currentLoader)
val newSession = if(all) Project.setAll(extracted, settings) else setThis(s, extracted, settings, arg)
reapply(newSession, structure, s)
val setResult = if(all) SettingCompletions.setAll(extracted, settings) else SettingCompletions.setThis(s, extracted, settings, arg)
s.log.info(setResult.quietSummary)
s.log.debug(setResult.verboseSummary)
reapply(setResult.session, structure, s)
}
// @deprecated("Use SettingCompletions.setThis", "0.13.0")
def setThis(s: State, extracted: Extracted, settings: Seq[Project.Setting[_]], arg: String) =
{
import extracted._
val append = Load.transformSettings(Load.projectScope(currentRef), currentRef.build, rootProject, settings)
session.appendSettings( append map (a => (a, arg.split('\n').toList)))
}
SettingCompletions.setThis(s, extracted, settings, arg)
def inspect = Command(InspectCommand, inspectBrief, inspectDetailed)(inspectParser) { case (s, (option, sk)) =>
s.log.info(inspectOutput(s, option, sk))
s

View File

@ -356,26 +356,9 @@ object Project extends Init[Scope] with ProjectExtra
def reverseDependencies(cMap: Map[ScopedKey[_],Flattened], scoped: ScopedKey[_]): Iterable[ScopedKey[_]] =
for( (key,compiled) <- cMap; dep <- compiled.dependencies if dep == scoped) yield key
def setAll(extracted: Extracted, settings: Seq[Setting[_]]) =
{
import extracted._
val allDefs = relation(extracted.structure, true)._1s.toSeq
val projectScope = Load.projectScope(currentRef)
def resolve(s: Setting[_]): Seq[Setting[_]] = Load.transformSettings(projectScope, currentRef.build, rootProject, s :: Nil)
def rescope[T](setting: Setting[T]): Seq[Setting[_]] =
{
val akey = setting.key.key
val global = ScopedKey(Global, akey)
val globalSetting = resolve( Project.setting(global, setting.init, setting.pos) )
globalSetting ++ allDefs.flatMap { d =>
if(d.key == akey)
Seq( SettingKey(akey) in d.scope <<= global)
else
Nil
}
}
extracted.session.appendRaw(settings flatMap { x => rescope(x) } )
}
//@deprecated("Use SettingCompletions.setAll when available.", "0.13.0")
def setAll(extracted: Extracted, settings: Seq[Setting[_]]): SessionSettings =
SettingCompletions.setAll(extracted, settings).session
val ExtraBuilds = AttributeKey[List[URI]]("extra-builds", "Extra build URIs to load in addition to the ones defined by the project.")
def extraBuilds(s: State): List[URI] = getOrNil(s, ExtraBuilds)

View File

@ -0,0 +1,112 @@
package sbt
import java.io.File
import java.net.URI
import Project._
import Scope.{GlobalScope,ThisScope}
import Load.BuildStructure
import Types.{idFun, Id}
import complete.DefaultParsers
private[sbt] class SetResult(val session: SessionSettings, val verboseSummary: String, val quietSummary: String)
private[sbt] object SettingCompletions
{
def setAll(extracted: Extracted, settings: Seq[Setting[_]]): SetResult =
{
import extracted._
val r = relation(extracted.structure, true)
val allDefs = r._1s.toSeq
val projectScope = Load.projectScope(currentRef)
def resolve(s: Setting[_]): Seq[Setting[_]] = Load.transformSettings(projectScope, currentRef.build, rootProject, s :: Nil)
def rescope[T](setting: Setting[T]): Seq[Setting[_]] =
{
val akey = setting.key.key
val global = ScopedKey(Global, akey)
val globalSetting = resolve( Project.setting(global, setting.init, setting.pos) )
globalSetting ++ allDefs.flatMap { d =>
if(d.key == akey)
Seq( SettingKey(akey) in d.scope <<= global)
else
Nil
}
}
val redefined = settings.flatMap(x => rescope(x))
val session = extracted.session.appendRaw(redefined)
setResult(session, r, redefined)
}
def setThis(s: State, extracted: Extracted, settings: Seq[Project.Setting[_]], arg: String): SetResult =
{
import extracted._
val append = Load.transformSettings(Load.projectScope(currentRef), currentRef.build, rootProject, settings)
val r = relation(extracted.structure, true)
val newSession = session.appendSettings( append map (a => (a, arg.split('\n').toList)))
setResult(newSession, r, append)
}
def setResult(session: SessionSettings, r: Relation[ScopedKey[_], ScopedKey[_]], redefined: Seq[Setting[_]])(implicit show: Show[ScopedKey[_]]): SetResult =
{
val redefinedKeys = redefined.map(_.key).toSet
val affectedKeys = redefinedKeys.flatMap(r.reverse)
def summary(verbose: Boolean): String = setSummary(redefinedKeys, affectedKeys, verbose)
new SetResult(session, summary(true), summary(false))
}
def setSummary(redefined: Set[ScopedKey[_]], affected: Set[ScopedKey[_]], verbose: Boolean)(implicit display: Show[ScopedKey[_]]): String =
{
val QuietLimit = 3
def strings(in: Set[ScopedKey[_]]): Seq[String] = in.toSeq.map(sk => display(sk)).sorted
def lines(in: Seq[String]): (String, Boolean) =
if(in.isEmpty)
("no settings or tasks.", false)
else if(verbose)
(in.mkString("\n\t", "\n\t", "\n"), false)
else
quietList(in)
def quietList(in: Seq[String]): (String, Boolean) =
{
val (first, last) = in.splitAt(QuietLimit)
if(last.isEmpty)
(first.mkString(", "), false)
else
{
val s = first.take(QuietLimit - 1).mkString("", ", ", " and " + last.size + " others.")
(s, true)
}
}
if(redefined.isEmpty)
"No settings or tasks were redefined."
else
{
val (redef, trimR) = lines(strings(redefined))
val (used, trimU) = lines(strings(affected))
val details = if(trimR || trimU) "\n\tRun `last` for details." else ""
val valuesString = if(redefined.size == 1) "value" else "values"
"Defining %s\nThe new %s will be used by %s%s".format(redef, valuesString, used, details)
}
}
/*
// add support to Completions for displaying information before or after completions vertically
// or for showing a completion on a line in columns
// possibly show after a completion is selected
// show available keys. can make this sorted by relevance and show top N
// based on the key, select scopes it is defined in (Compile, `package`) or Test with all scopes being shown on second tab
// show
// := (assign value)
// ~= (update value)
// <<= (assign dependent value)
// if key type is appendable, include
// += (append value)
// ++= (append values)
// <+= (append dependent value)
// <++= (append dependent values)
//
// on execution, can indicate that the new value will be used by x, y, z and 10 more (run `last` to see all)
//
val settingParser = matched(parser)
val parser = keyParser.flatMap { key =>
scope(key).* ~ assign ~ initialization)
val scope = token("in" ~ Space) ~ token(scopes <~ Space) ~ token(
val assigns = Map(
":=" ->
*/
}