mirror of https://github.com/sbt/sbt.git
command logging through Streams, 'last' without a key to redisplay it
This commit is contained in:
parent
f34c3b5837
commit
1de086755b
|
|
@ -86,7 +86,7 @@ object Command
|
|||
case Right(s) => s() // apply command. command side effects happen here
|
||||
case Left((msg,pos)) =>
|
||||
val errMsg = commandError(command, msg, pos)
|
||||
logger(state).info(errMsg)
|
||||
logger(state).error(errMsg)
|
||||
state.fail
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,10 +46,11 @@ EvalCommand + """ <expression>
|
|||
|
||||
val lastGrepBrief = (LastGrepCommand + " <pattern> <key>", "Shows lines from the last output for 'key' that match 'pattern'.")
|
||||
val lastGrepDetailed =
|
||||
LastGrepCommand + """ <pattern> <key>
|
||||
LastGrepCommand + """ <pattern> [key]
|
||||
|
||||
<pattern> is a regular expression interpreted by java.util.Pattern.
|
||||
Lines that match 'pattern' from the last streams output associated with the key are displayed.
|
||||
If no key is specified, the global streams output is used.
|
||||
See also """ + LastCommand + "."
|
||||
|
||||
val lastBrief = (LastCommand + " <key>", "Prints the last output associated with 'key'.")
|
||||
|
|
@ -57,6 +58,7 @@ LastGrepCommand + """ <pattern> <key>
|
|||
LastCommand + """ <key>
|
||||
|
||||
Redisplays the last streams output associated with the key (typically a task key).
|
||||
If no key is specified, the global streams output is displayed.
|
||||
See also """ + LastGrepCommand + "."
|
||||
|
||||
val InspectCommand = "inspect"
|
||||
|
|
|
|||
|
|
@ -247,13 +247,14 @@ object BuiltinCommands
|
|||
s
|
||||
}
|
||||
def lastGrep = Command(LastGrepCommand, lastGrepBrief, lastGrepDetailed)(lastGrepParser) { case (s,(pattern,sk)) =>
|
||||
Output.lastGrep(sk.scope, sk.key, Project.structure(s).streams, pattern)
|
||||
Output.lastGrep(sk, Project.structure(s).streams, pattern)
|
||||
s
|
||||
}
|
||||
val spacedKeyParser = (s: State) => Act.requireSession(s, token(Space) ~> Act.scopedKeyParser(s))
|
||||
def lastGrepParser(s: State) = Act.requireSession(s, (token(Space) ~> token(NotSpace, "<pattern>")) ~ spacedKeyParser(s))
|
||||
def last = Command(LastCommand, lastBrief, lastDetailed)(spacedKeyParser) { (s,sk) =>
|
||||
Output.last(sk.scope, sk.key, Project.structure(s).streams)
|
||||
val optSpacedKeyParser = (s: State) => spacedKeyParser(s).?
|
||||
def lastGrepParser(s: State) = Act.requireSession(s, (token(Space) ~> token(NotSpace, "<pattern>")) ~ optSpacedKeyParser(s))
|
||||
def last = Command(LastCommand, lastBrief, lastDetailed)(optSpacedKeyParser) { (s,sk) =>
|
||||
Output.last(sk, Project.structure(s).streams)
|
||||
s
|
||||
}
|
||||
|
||||
|
|
@ -334,6 +335,7 @@ object BuiltinCommands
|
|||
case _ =>
|
||||
log.trace(e)
|
||||
log.error(e.toString)
|
||||
log.error("Use 'last' for the full log.")
|
||||
}
|
||||
s.fail
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,14 +23,16 @@ object Output
|
|||
None
|
||||
}
|
||||
|
||||
def last(scope: Scope, key: AttributeKey[_], mgr: Streams): Unit =
|
||||
printLines(lastLines(ScopedKey(scope,key), mgr))
|
||||
def last(key: Option[ScopedKey[_]], mgr: Streams): Unit =
|
||||
printLines(lastLines(key, mgr))
|
||||
def printLines(lines: Seq[String]) = lines foreach println
|
||||
def lastGrep(scope: Scope, key: AttributeKey[_], mgr: Streams, patternString: String)
|
||||
def lastGrep(key: Option[ScopedKey[_]], mgr: Streams, patternString: String)
|
||||
{
|
||||
val pattern = Pattern.compile(patternString)
|
||||
printLines(lastLines(ScopedKey(scope,key), mgr).flatMap(showMatches(pattern)) )
|
||||
printLines(lastLines(key, mgr).flatMap(showMatches(pattern)) )
|
||||
}
|
||||
def lastLines(key: Option[ScopedKey[_]], mgr: Streams): Seq[String] =
|
||||
lastLines(key getOrElse Project.globalLoggerKey, mgr)
|
||||
def lastLines(key: ScopedKey[_], mgr: Streams): Seq[String] =
|
||||
mgr.use(key) { s => IO.readLines(s.readText( Project.fillTaskAxis(key) )) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ package sbt
|
|||
import java.io.File
|
||||
import java.net.URI
|
||||
import Project._
|
||||
import Keys.{appConfiguration, buildStructure, commands, configuration, historyPath, projectCommand, sessionSettings, shellPrompt, thisProject, thisProjectRef, watch}
|
||||
import Keys.{appConfiguration, buildStructure, commands, configuration, historyPath, logged, projectCommand, sessionSettings, shellPrompt, streams, thisProject, thisProjectRef, watch}
|
||||
import Scope.{GlobalScope,ThisScope}
|
||||
import CommandSupport.logger
|
||||
|
||||
|
|
@ -88,9 +88,10 @@ object Project extends Init[Scope]
|
|||
updateCurrent(newState.runExitHooks())
|
||||
}
|
||||
def current(state: State): ProjectRef = session(state).current
|
||||
def updateCurrent(s: State): State =
|
||||
def updateCurrent(s0: State): State =
|
||||
{
|
||||
val structure = Project.structure(s)
|
||||
val structure = Project.structure(s0)
|
||||
val s = installGlobalLogger(s0, structure)
|
||||
val ref = Project.current(s)
|
||||
val project = Load.getProject(structure.units, ref.build, ref.project)
|
||||
logger(s).info("Set current project to " + ref.project + " (in build " + ref.build +")")
|
||||
|
|
@ -225,6 +226,13 @@ object Project extends Init[Scope]
|
|||
val extracted = Project.extract(state)
|
||||
EvaluateTask.evaluateTask(extracted.structure, taskKey, state, extracted.currentRef, checkCycles, maxWorkers)
|
||||
}
|
||||
def globalLoggerKey = fillTaskAxis(ScopedKey(GlobalScope, streams.key))
|
||||
def installGlobalLogger(s: State, structure: Load.BuildStructure): State =
|
||||
{
|
||||
val str = structure.streams(globalLoggerKey)
|
||||
str.open()
|
||||
s.put(logged, str.log).addExitHook { str.close() }
|
||||
}
|
||||
}
|
||||
|
||||
trait ProjectConstructors
|
||||
|
|
|
|||
|
|
@ -41,8 +41,10 @@ trait StateOps {
|
|||
def + (newCommand: Command): State
|
||||
def get[T](key: AttributeKey[T]): Option[T]
|
||||
def put[T](key: AttributeKey[T], value: T): State
|
||||
def remove(key: AttributeKey[_]): State
|
||||
def baseDir: File
|
||||
def runExitHooks(): State
|
||||
def addExitHook(f: => Unit): State
|
||||
}
|
||||
object State
|
||||
{
|
||||
|
|
@ -63,8 +65,9 @@ object State
|
|||
def reboot(full: Boolean) = throw new xsbti.FullReload(s.remainingCommands.toArray, full)
|
||||
def reload = setNext(Next.Reload)
|
||||
def exit(ok: Boolean) = setNext(if(ok) Next.Done else Next.Fail)
|
||||
def get[T](key: AttributeKey[T]) = s.attributes.get(key)
|
||||
def get[T](key: AttributeKey[T]) = s.attributes get key
|
||||
def put[T](key: AttributeKey[T], value: T) = s.copy(attributes = s.attributes.put(key, value))
|
||||
def remove(key: AttributeKey[_]) = s.copy(attributes = s.attributes remove key)
|
||||
def fail =
|
||||
{
|
||||
val remaining = s.remainingCommands.dropWhile(_ != FailureWall)
|
||||
|
|
@ -80,6 +83,8 @@ object State
|
|||
case None => noHandler
|
||||
}
|
||||
|
||||
def addExitHook(act: => Unit): State =
|
||||
s.copy(exitHooks = s.exitHooks + ExitHook(act))
|
||||
def runExitHooks(): State = {
|
||||
ExitHooks.runExitHooks(s.exitHooks.toSeq)
|
||||
s.copy(exitHooks = Set.empty)
|
||||
|
|
|
|||
|
|
@ -4,13 +4,15 @@
|
|||
package sbt
|
||||
|
||||
/** Defines a function to call as sbt exits.*/
|
||||
trait ExitHook extends NotNull
|
||||
trait ExitHook
|
||||
{
|
||||
/** Provides a name for this hook to be used to provide feedback to the user. */
|
||||
def name: String
|
||||
/** Subclasses should implement this method, which is called when this hook is executed. */
|
||||
def runBeforeExiting(): Unit
|
||||
}
|
||||
object ExitHook
|
||||
{
|
||||
def apply(f: => Unit): ExitHook = new ExitHook { def runBeforeExiting() = f }
|
||||
}
|
||||
|
||||
object ExitHooks
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
/* sbt -- Simple Build Tool
|
||||
* Copyright 2008, 2009, 2010 Mark Harrah
|
||||
* Copyright 2008, 2009, 2010, 2011 Mark Harrah
|
||||
*/
|
||||
package sbt
|
||||
|
||||
import java.io.{PrintStream, PrintWriter}
|
||||
import java.io.{BufferedWriter, PrintStream, PrintWriter}
|
||||
|
||||
object ConsoleLogger
|
||||
{
|
||||
|
|
@ -17,8 +17,14 @@ object ConsoleLogger
|
|||
def printWriterOut(out: PrintWriter): ConsoleOut = new ConsoleOut {
|
||||
val lockObject = out
|
||||
def print(s: String) = out.print(s)
|
||||
def println(s: String) = out.println(s)
|
||||
def println() = out.println()
|
||||
def println(s: String) = { out.println(s); out.flush() }
|
||||
def println() = { out.println(); out.flush() }
|
||||
}
|
||||
def bufferedWriterOut(out: BufferedWriter): ConsoleOut = new ConsoleOut {
|
||||
val lockObject = out
|
||||
def print(s: String) = out.write(s)
|
||||
def println(s: String) = { out.write(s); println() }
|
||||
def println() = { out.newLine(); out.flush() }
|
||||
}
|
||||
|
||||
val formatEnabled =
|
||||
|
|
|
|||
Loading…
Reference in New Issue