'set every <setting>' for overriding every definition of a key. fixes #154

This commit is contained in:
Mark Harrah 2011-12-13 17:29:08 -05:00
parent 454bc6095b
commit 7347e89f73
5 changed files with 44 additions and 9 deletions

View File

@ -106,7 +106,7 @@ InspectCommand + """ [tree] <key>
"Related" shows all of the scopes in which the key is defined.""" "Related" shows all of the scopes in which the key is defined."""
val SetCommand = "set" val SetCommand = "set"
val setBrief = (SetCommand + " <setting-expression>", "Evaluates the given Setting and applies it to the current project.") val setBrief = (SetCommand + "[every] <setting-expression>", "Evaluates the given Setting and applies it to the current project.")
val setDetailed = val setDetailed =
SetCommand + """ <setting-expression> SetCommand + """ <setting-expression>
@ -117,7 +117,12 @@ SetCommand + """ <setting-expression>
This command does not rebuild the build definitions, plugins, or configurations. This command does not rebuild the build definitions, plugins, or configurations.
It does not automatically persist the setting(s) either. It does not automatically persist the setting(s) either.
To persist the setting(s), run 'session save' or 'session save-all'.""" To persist the setting(s), run 'session save' or 'session save-all'.
If 'every' is specified, the setting is evaluated in the current context
and the resulting value is used in every scope. This overrides the value
bound to the key everywhere.
"""
def SessionCommand = "session" def SessionCommand = "session"
def sessionBrief = (SessionCommand + " <session-command>", "Manipulates session settings. For details, run 'help " + SessionCommand + "'.") def sessionBrief = (SessionCommand + " <session-command>", "Manipulates session settings. For details, run 'help " + SessionCommand + "'.")

View File

@ -519,7 +519,7 @@ object Load
} }
def initialSession(structure: BuildStructure, rootEval: () => Eval): SessionSettings = def initialSession(structure: BuildStructure, rootEval: () => Eval): SessionSettings =
new SessionSettings(structure.root, rootProjectMap(structure.units), structure.settings, Map.empty, rootEval) new SessionSettings(structure.root, rootProjectMap(structure.units), structure.settings, Map.empty, Nil, rootEval)
def rootProjectMap(units: Map[URI, LoadedBuildUnit]): Map[URI, String] = def rootProjectMap(units: Map[URI, LoadedBuildUnit]): Map[URI, String] =
{ {

View File

@ -387,14 +387,19 @@ object BuiltinCommands
val newStructure = Load.reapply(newSession.mergeSettings, structure)( Project.showContextKey(newSession, structure) ) val newStructure = Load.reapply(newSession.mergeSettings, structure)( Project.showContextKey(newSession, structure) )
Project.setProject(newSession, newStructure, s) Project.setProject(newSession, newStructure, s)
} }
def set = Command.single(SetCommand, setBrief, setDetailed) { (s, arg) => def set = Command(SetCommand, setBrief, setDetailed)(setParser) { case (s, (all, arg)) =>
val extracted = Project extract s val extracted = Project extract s
import extracted._ import extracted._
val settings = EvaluateConfigurations.evaluateSetting(session.currentEval(), "<set>", imports(extracted), arg, 0)(currentLoader) val settings = EvaluateConfigurations.evaluateSetting(session.currentEval(), "<set>", imports(extracted), arg, 0)(currentLoader)
val append = Load.transformSettings(Load.projectScope(currentRef), currentRef.build, rootProject, settings) val newSession = if(all) Project.setAll(extracted, settings) else setThis(s, extracted, settings, arg)
val newSession = session.appendSettings( append map (a => (a, arg)))
reapply(newSession, structure, s) reapply(newSession, structure, s)
} }
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)))
}
def inspect = Command(InspectCommand, inspectBrief, inspectDetailed)(inspectParser) { case (s, (option, sk)) => def inspect = Command(InspectCommand, inspectBrief, inspectDetailed)(inspectParser) { case (s, (option, sk)) =>
logger(s).info(inspectOutput(s, option, sk)) logger(s).info(inspectOutput(s, option, sk))
s s
@ -430,6 +435,9 @@ object BuiltinCommands
val ext = Project.extract(s) val ext = Project.extract(s)
(ext.structure, Select(ext.currentRef), ext.showKey) (ext.structure, Select(ext.currentRef), ext.showKey)
} }
def setParser = (s: State) => token(Space ~> flag("every" ~ Space)) ~ token(any.+.string)
import InspectOption._ import InspectOption._
def inspectParser = (s: State) => spacedInspectOptionParser(s) flatMap { def inspectParser = (s: State) => spacedInspectOptionParser(s) flatMap {
case opt @ (Uses | Definitions) => allKeyParser(s).map(key => (opt, Project.ScopedKey(Global, key))) case opt @ (Uses | Definitions) => allKeyParser(s).map(key => (opt, Project.ScopedKey(Global, key)))

View File

@ -317,6 +317,27 @@ object Project extends Init[Scope] with ProjectExtra
def reverseDependencies(cMap: Map[ScopedKey[_],Flattened], scoped: ScopedKey[_]): Iterable[ScopedKey[_]] = def reverseDependencies(cMap: Map[ScopedKey[_],Flattened], scoped: ScopedKey[_]): Iterable[ScopedKey[_]] =
for( (key,compiled) <- cMap; dep <- compiled.dependencies if dep == scoped) yield key 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) )
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) } )
}
object LoadAction extends Enumeration { object LoadAction extends Enumeration {
val Return, Current, Plugins = Value val Return, Current, Plugins = Value
} }

View File

@ -11,14 +11,15 @@ package sbt
import SessionSettings._ import SessionSettings._
final case class SessionSettings(currentBuild: URI, currentProject: Map[URI, String], original: Seq[Setting[_]], append: SessionMap, currentEval: () => Eval) final case class SessionSettings(currentBuild: URI, currentProject: Map[URI, String], original: Seq[Setting[_]], append: SessionMap, rawAppend: Seq[Setting[_]], currentEval: () => Eval)
{ {
assert(currentProject contains currentBuild, "Current build (" + currentBuild + ") not associated with a current project.") assert(currentProject contains currentBuild, "Current build (" + currentBuild + ") not associated with a current project.")
def setCurrent(build: URI, project: String, eval: () => Eval): SessionSettings = copy(currentBuild = build, currentProject = currentProject.updated(build, project), currentEval = eval) def setCurrent(build: URI, project: String, eval: () => Eval): SessionSettings = copy(currentBuild = build, currentProject = currentProject.updated(build, project), currentEval = eval)
def current: ProjectRef = ProjectRef(currentBuild, currentProject(currentBuild)) def current: ProjectRef = ProjectRef(currentBuild, currentProject(currentBuild))
def appendSettings(s: Seq[SessionSetting]): SessionSettings = copy(append = modify(append, _ ++ s)) def appendSettings(s: Seq[SessionSetting]): SessionSettings = copy(append = modify(append, _ ++ s))
def mergeSettings: Seq[Setting[_]] = original ++ merge(append) def appendRaw(ss: Seq[Setting[_]]): SessionSettings = copy(rawAppend = rawAppend ++ ss)
def clearExtraSettings: SessionSettings = copy(append = Map.empty) def mergeSettings: Seq[Setting[_]] = original ++ merge(append) ++ rawAppend
def clearExtraSettings: SessionSettings = copy(append = Map.empty, rawAppend = Nil)
private[this] def merge(map: SessionMap): Seq[Setting[_]] = map.values.toSeq.flatten[SessionSetting].map(_._1) private[this] def merge(map: SessionMap): Seq[Setting[_]] = map.values.toSeq.flatten[SessionSetting].map(_._1)
private[this] def modify(map: SessionMap, onSeq: Endo[Seq[SessionSetting]]): SessionMap = private[this] def modify(map: SessionMap, onSeq: Endo[Seq[SessionSetting]]): SessionMap =