mirror of https://github.com/sbt/sbt.git
when exporting settings, send the output directly to the console
This commit is contained in:
parent
dde24d5e5a
commit
a263b7e91f
|
|
@ -232,7 +232,8 @@ object Act
|
|||
import Aggregation.evaluatingParser
|
||||
showParser.flatMap { show =>
|
||||
val akp = aggregatedKeyParser(extracted)
|
||||
def evaluate(kvs: Seq[ScopedKey[T]] forSome { type T}): Parser[() => State] = evaluatingParser(state, structure, show)( keyValues(structure)(kvs) )
|
||||
def evaluate(kvs: Seq[ScopedKey[T]] forSome { type T}): Parser[() => State] =
|
||||
evaluatingParser(state, structure, Aggregation.defaultShow(state, show))( keyValues(structure)(kvs) )
|
||||
def reconstruct(arg: String): String = ShowCommand + " " + arg
|
||||
if(show)
|
||||
( akp ~ (token(Space) ~> matched(akp)).* ) flatMap { case (kvs, tail) =>
|
||||
|
|
|
|||
|
|
@ -14,23 +14,25 @@ package sbt
|
|||
sealed trait Aggregation
|
||||
final object Aggregation
|
||||
{
|
||||
final case class ShowConfig(settingValues: Boolean, taskValues: Boolean, print: String => Unit)
|
||||
final case class KeyValue[+T](key: ScopedKey[_], value: T)
|
||||
|
||||
def printSettings[T](xs: Seq[KeyValue[T]], log: Logger)(implicit display: Show[ScopedKey[_]]) =
|
||||
def defaultShow(state: State, showTasks: Boolean): ShowConfig = ShowConfig(settingValues = true, taskValues = showTasks, s => state.log.info(s))
|
||||
def printSettings[T](xs: Seq[KeyValue[T]], print: String => Unit)(implicit display: Show[ScopedKey[_]]) =
|
||||
xs match
|
||||
{
|
||||
case KeyValue(_,x) :: Nil => log.info(x.toString)
|
||||
case _ => xs foreach { case KeyValue(key, value) => log.info(display(key) + "\n\t" + value.toString) }
|
||||
case KeyValue(_,x) :: Nil => print(x.toString)
|
||||
case _ => xs foreach { case KeyValue(key, value) => print(display(key) + "\n\t" + value.toString) }
|
||||
}
|
||||
type Values[T] = Seq[KeyValue[T]]
|
||||
type AnyKeys = Values[_]
|
||||
def seqParser[T](ps: Values[Parser[T]]): Parser[Seq[KeyValue[T]]] = seq(ps.map { case KeyValue(k,p) => p.map(v => KeyValue(k,v) ) })
|
||||
|
||||
def applyTasks[T](s: State, structure: BuildStructure, ps: Values[Parser[Task[T]]], show: Boolean)(implicit display: Show[ScopedKey[_]]): Parser[() => State] =
|
||||
def applyTasks[T](s: State, structure: BuildStructure, ps: Values[Parser[Task[T]]], show: ShowConfig)(implicit display: Show[ScopedKey[_]]): Parser[() => State] =
|
||||
Command.applyEffect(seqParser(ps)) { ts =>
|
||||
runTasks(s, structure, ts, DummyTaskMap(Nil), show)
|
||||
}
|
||||
def runTasksWithResult[T](s: State, structure: BuildStructure, ts: Values[Task[T]], extra: DummyTaskMap, show: Boolean)(implicit display: Show[ScopedKey[_]]): (State, Result[Seq[KeyValue[T]]]) =
|
||||
def runTasksWithResult[T](s: State, structure: BuildStructure, ts: Values[Task[T]], extra: DummyTaskMap, show: ShowConfig)(implicit display: Show[ScopedKey[_]]): (State, Result[Seq[KeyValue[T]]]) =
|
||||
{
|
||||
import EvaluateTask._
|
||||
import std.TaskExtra._
|
||||
|
|
@ -49,25 +51,24 @@ final object Aggregation
|
|||
val log = newS.log
|
||||
|
||||
val success = result match { case Value(_) => true; case Inc(_) => false }
|
||||
try { onResult(result, log) { results => if(show) printSettings(results, log) } }
|
||||
try { onResult(result, log) { results => if(show.taskValues) printSettings(results, show.print) } }
|
||||
finally { printSuccess(start, stop, extracted, success, log) }
|
||||
|
||||
(newS, result)
|
||||
}
|
||||
|
||||
def runTasks[HL <: HList, T](s: State, structure: BuildStructure, ts: Values[Task[T]], extra: DummyTaskMap, show: Boolean)(implicit display: Show[ScopedKey[_]]): State = {
|
||||
runTasksWithResult(s, structure, ts, extra, show)._1
|
||||
}
|
||||
def runTasks[HL <: HList, T](s: State, structure: BuildStructure, ts: Values[Task[T]], extra: DummyTaskMap, show: ShowConfig)(implicit display: Show[ScopedKey[_]]): State = {
|
||||
runTasksWithResult(s, structure, ts, extra, show)._1
|
||||
}
|
||||
|
||||
|
||||
def printSuccess(start: Long, stop: Long, extracted: Extracted, success: Boolean, log: Logger)
|
||||
def printSuccess(start: Long, stop: Long, extracted: Extracted, success: Boolean, log: Logger)
|
||||
{
|
||||
import extracted._
|
||||
lazy val enabled = showSuccess in extracted.currentRef get extracted.structure.data getOrElse true
|
||||
if(enabled)
|
||||
def get(key: SettingKey[Boolean]): Boolean = key in currentRef get structure.data getOrElse true
|
||||
if(get(showSuccess))
|
||||
{
|
||||
val timingEnabled = showTiming in currentRef get structure.data getOrElse true
|
||||
if(timingEnabled)
|
||||
if(get(showTiming))
|
||||
{
|
||||
val msg = timingString(start, stop, "", structure.data, currentRef, log)
|
||||
if(success) log.success(msg) else log.error(msg)
|
||||
|
|
@ -93,7 +94,7 @@ final object Aggregation
|
|||
DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM)
|
||||
}
|
||||
|
||||
def applyDynamicTasks[I](s: State, structure: BuildStructure, inputs: Values[InputTask[I]], show: Boolean)(implicit display: Show[ScopedKey[_]]): Parser[() => State] =
|
||||
def applyDynamicTasks[I](s: State, structure: BuildStructure, inputs: Values[InputTask[I]], show: ShowConfig)(implicit display: Show[ScopedKey[_]]): Parser[() => State] =
|
||||
{
|
||||
val parsers = for(KeyValue(k,it) <- inputs) yield it.parser(s).map(v => KeyValue(k,v))
|
||||
Command.applyEffect(seq(parsers)) { roots =>
|
||||
|
|
@ -102,13 +103,13 @@ final object Aggregation
|
|||
}
|
||||
}
|
||||
|
||||
def evaluatingParser[T](s: State, structure: BuildStructure, show: Boolean)(keys: Seq[KeyValue[T]])(implicit display: Show[ScopedKey[_]]): Parser[() => State] =
|
||||
def evaluatingParser[T](s: State, structure: BuildStructure, show: ShowConfig)(keys: Seq[KeyValue[T]])(implicit display: Show[ScopedKey[_]]): Parser[() => State] =
|
||||
keys.toList match
|
||||
{
|
||||
case Nil => failure("No such setting/task")
|
||||
case xs @ KeyValue(_, _: InputTask[t]) :: _ => applyDynamicTasks(s, structure, xs.asInstanceOf[Values[InputTask[t]]], show)
|
||||
case xs @ KeyValue(_, _: Task[t]) :: _ => applyTasks(s, structure, maps(xs.asInstanceOf[Values[Task[t]]])(x => success(x)), show)
|
||||
case xs => success(() => { printSettings(xs, s.log); s} )
|
||||
case xs => success(() => { if(show.settingValues) printSettings(xs, show.print); s} )
|
||||
}
|
||||
private[this] def maps[T, S](vs: Values[T])(f: T => S): Values[S] =
|
||||
vs map { case KeyValue(k,v) => KeyValue(k, f(v)) }
|
||||
|
|
|
|||
|
|
@ -57,15 +57,19 @@ LastCommand + """
|
|||
|
||||
See also '""" + LastGrepCommand + "'."
|
||||
|
||||
val exportBrief = (ExportCommand, "Displays the equivalent command line(s) for previously executed tasks.")
|
||||
val exportBrief = (ExportCommand + " <tasks>+", "Executes tasks and displays the equivalent command lines.")
|
||||
val exportDetailed =
|
||||
s"""$ExportCommand <task-key>+
|
||||
Prints the approximate command line(s) for the previously executed tasks.
|
||||
s"""$ExportCommand [--last] <task>+
|
||||
Runs the specified tasks and prints the equivalent command lines or other exportable information for those runs.
|
||||
|
||||
NOTE: These command lines are necessarily approximate. Usually tasks do not actually
|
||||
--last
|
||||
Uses information from the previous execution
|
||||
|
||||
NOTES: These command lines are necessarily approximate. Usually tasks do not actually
|
||||
execute the command line and the actual command line program may not be installed or
|
||||
on the PATH. Incremental tasks will typically show the command line for the previous
|
||||
incremental run and not for a full run.
|
||||
on the PATH. Incremental tasks will typically show the command line for an
|
||||
incremental run and not for a full run. Many tasks have no direct command line
|
||||
equivalent and will show nothing at all.
|
||||
"""
|
||||
|
||||
val InspectCommand = "inspect"
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ final case class Extracted(structure: BuildStructure, session: SessionSettings,
|
|||
val rkey = resolve(key.scopedKey)
|
||||
val keys = Aggregation.aggregate(rkey, ScopeMask(), structure.extra)
|
||||
val tasks = Act.keyValues(structure)(keys)
|
||||
Aggregation.runTasks(state, structure, tasks, DummyTaskMap(Nil), show = false )(showKey)
|
||||
Aggregation.runTasks(state, structure, tasks, DummyTaskMap(Nil), show = Aggregation.defaultShow(state,false) )(showKey)
|
||||
}
|
||||
|
||||
private[this] def resolve[T](key: ScopedKey[T]): ScopedKey[T] =
|
||||
|
|
|
|||
|
|
@ -295,8 +295,28 @@ object BuiltinCommands
|
|||
|
||||
val spacedKeyParser = (s: State) => Act.requireSession(s, token(Space) ~> Act.scopedKeyParser(s))
|
||||
val spacedAggregatedParser = (s: State) => Act.requireSession(s, token(Space) ~> Act.aggregatedKeyParser(s))
|
||||
val exportParser: State => Parser[AnyKeys] = (s: State) => spacedAggregatedParser(s).map(x => Act.keyValues(s)(x) )
|
||||
val aggregatedKeyValueParser: State => Parser[Option[AnyKeys]] = s => exportParser(s).?
|
||||
val aggregatedKeyValueParser: State => Parser[Option[AnyKeys]] = (s: State) => spacedAggregatedParser(s).map(x => Act.keyValues(s)(x) ).?
|
||||
|
||||
val exportParser: State => Parser[() => State] = (s: State) => Act.requireSession(s, token(Space) ~> exportParser0(s))
|
||||
private[sbt] def exportParser0(s: State): Parser[() => State] =
|
||||
{
|
||||
val extracted = Project extract s
|
||||
import extracted.{showKey, structure}
|
||||
val keysParser = token(flag("--last" <~ Space)) ~ Act.aggregatedKeyParser(extracted)
|
||||
val show = Aggregation.ShowConfig(settingValues = true, taskValues = false, print = println _)
|
||||
for {
|
||||
lastOnly_keys <- keysParser
|
||||
kvs = Act.keyValues(structure)(lastOnly_keys._2)
|
||||
f <- if(lastOnly_keys._1) success(() => s) else Aggregation.evaluatingParser(s, structure, show)(kvs)
|
||||
} yield () => {
|
||||
def export0(s: State): State = lastImpl(s, kvs, Some("export"))
|
||||
val newS = try f() catch { case e: Exception =>
|
||||
try export0(s)
|
||||
finally { throw e }
|
||||
}
|
||||
export0(newS)
|
||||
}
|
||||
}
|
||||
|
||||
def lastGrepParser(s: State) = Act.requireSession(s, (token(Space) ~> token(NotSpace, "<pattern>")) ~ aggregatedKeyValueParser(s))
|
||||
def last = Command(LastCommand, lastBrief, lastDetailed)(aggregatedKeyValueParser) {
|
||||
|
|
@ -306,9 +326,8 @@ object BuiltinCommands
|
|||
Output.last( logFile, printLast(s) )
|
||||
keepLastLog(s)
|
||||
}
|
||||
def export = Command(ExportCommand, exportBrief, exportDetailed)(exportParser) { (s, sks) =>
|
||||
lastImpl(s, sks, Some("export"))
|
||||
}
|
||||
def export = Command(ExportCommand, exportBrief, exportDetailed)(exportParser)( (s,f) => f() )
|
||||
|
||||
private[this] def lastImpl(s: State, sks: AnyKeys, sid: Option[String]): State =
|
||||
{
|
||||
val (str, ref, display) = extractLast(s)
|
||||
|
|
|
|||
Loading…
Reference in New Issue