From f182b3a896f0f02786af7f8afe5a29a75026256f Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 25 Jan 2011 22:23:03 -0500 Subject: [PATCH] 'act' command for running tasks --- main/Act.scala | 68 +++++++++++++++++++++++++++++++++++++++++++++++++ main/Main.scala | 5 ++-- 2 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 main/Act.scala diff --git a/main/Act.scala b/main/Act.scala new file mode 100644 index 000000000..43cc3049c --- /dev/null +++ b/main/Act.scala @@ -0,0 +1,68 @@ +/* sbt -- Simple Build Tool + * Copyright 2011 Mark Harrah + */ +package sbt + + import Project.ScopedKey + import CommandSupport.logger + import Load.BuildStructure + import complete.{DefaultParsers, Parser} + import DefaultParsers._ + import java.net.URI + +object Act +{ + // this does not take delegation into account + def scopedKey(index: KeyIndex, currentBuild: URI, currentProject: String, keyMap: Map[String, AttributeKey[_]]): Parser[ScopedKey[_]] = + { + for { + proj <- optProjectRef(index, currentBuild, currentProject) + conf <- configs( index configs proj ) + key <- keyRef( index.keys(proj, conf), keyMap ) } + yield + ScopedKey( Scope( Select(proj), toAxis(conf map ConfigKey.apply, Global), Global, Global), key ) + } + + def toAxis[T](opt: Option[T], ifNone: ScopeAxis[Nothing]): ScopeAxis[T] = + opt match { case Some(t) => Select(t); case None => ifNone } + + def configs(confs: Set[String]) = token( (ID examples confs) <~ ':' ).? + def keyRef(keys: Set[String], keyMap: Map[String, AttributeKey[_]]) = token( ID examples keys flatMap getKey(keyMap) ) + def getKey(keyMap: Map[String, AttributeKey[_]])(keyString: String): Parser[AttributeKey[_]] = + keyMap.get(keyString) match { case Some(k) => success(k); case None => failure("Invalid key: " + keyString)} + + def projectRef(index: KeyIndex, currentBuild: URI): Parser[ProjectRef] = + { + val uris = index.buildURIs + val build = token( '(' ~> Uri(uris).map(uri => Scope.resolveBuild(currentBuild, uri)) <~ ')') ?? currentBuild + def projectID(uri: URI) = token( ID.examples(index projects uri) <~ '/' ) + + for(uri <- build; id <- projectID(uri)) yield + ProjectRef(Some(uri), Some(id)) + } + def optProjectRef(index: KeyIndex, currentBuild: URI, currentProject: String) = + projectRef(index, currentBuild) ?? ProjectRef(Some(currentBuild), Some(currentProject)) + + def valueParser(s: State, structure: BuildStructure)(key: ScopedKey[_]): Parser[() => State] = + structure.data.get(key.scope, key.key) match + { + case None => failure("Invalid setting or task") + case Some(input: InputTask[_]) => applyTask(s, structure, input.parser) + case Some(task: Task[_]) => applyTask(s, structure, success(task)) + case Some(v) => success(() => { logger(s).info(v.toString); s}) + } + def applyTask(s: State, structure: BuildStructure, p: Parser[Task[_]]): Parser[() => State] = + Command.applyEffect(p) { t => + import EvaluateTask._ + processResult(runTask(t)(nodeView(structure, s)), logger(s)) + s + } + def actParser(s: State): Parser[() => State] = + if(s get Project.SessionKey isEmpty) failure("No project loaded") else actParser0(s) + private[this] def actParser0(state: State) = + { + val extracted = Project extract state + import extracted._ + scopedKey(structure.index.keyIndex, curi, cid, structure.index.keyMap) flatMap valueParser(state, structure) + } +} \ No newline at end of file diff --git a/main/Main.scala b/main/Main.scala index b58e71a6a..cdbe4b863 100644 --- a/main/Main.scala +++ b/main/Main.scala @@ -59,7 +59,7 @@ class xMain extends xsbti.AppMain object Commands { def DefaultCommands: Seq[Command] = Seq(ignore, help, reload, read, history, continuous, exit, loadCommands, loadProject, compile, discover, - projects, project, setOnFailure, ifLast, multi, shell, set, get, eval, alias, append, nop) + projects, project, setOnFailure, ifLast, multi, shell, set, get, eval, alias, append, nop, act) def nop = Command.custom(s => success(() => s), Nil) def ignore = Command.command(FailureWall)(identity) @@ -248,7 +248,8 @@ object Commands for(id <- build.defined.keys) log.info("\t" + prefix(id) + id) } - def act = error("TODO") + def act = Command.custom(Act.actParser, Nil) + def projects = Command.command(ProjectsCommand, projectsBrief, projectsDetailed ) { s => val extracted = Project extract s import extracted._