sbt/main/pending/OutputTasks.scala

121 lines
3.5 KiB
Scala

/* sbt -- Simple Build Tool
* Copyright 2010 Mark Harrah
*/
package sbt
import std._
import Path._
import TaskExtra._
import Types._
import OutputUtil._
import java.io.{BufferedReader,File}
import java.util.regex.Pattern
trait PrintTask
{
def input: Task[Input]
def context: Task[Transform.Context[Project]]
lazy val show = (input, context) flatMap { case in :+: ctx :+: HNil =>
val taskStrings = in.splitArgs map { name =>
val selected = taskForName(ctx, name)
selected.merge.map {
case Seq() => "No result for " + name
case Seq( (conf, v) ) => name + ": " + v.toString
case confs => confs map { case (conf, v) => conf + ": " + v } mkString(name + ":\n\t", "\n\t", "\n")
}
}
taskStrings.join.map { _ foreach println }
}
}
trait LastOutput
{
def input: Task[Input]
def streams: Task[TaskStreams]
def context: Task[Transform.Context[Project]]
lazy val last = (streams, input, context) flatMap { case s :+: i :+: ctx :+: HNil =>
mapLast(s, ctx, i.arguments) { reader =>
val out = s.text()
foreachLine(reader) { line =>
out.println(line)
println(line)
}
}
}
lazy val grepLast = (streams, input, context) flatMap { case s :+: i :+: ctx :+: HNil =>
val i2 = new Input(i.arguments, None)
val pattern = Pattern.compile(i2.arguments)
mapLast(s, ctx, i2.name) { reader =>
val out = s.text()
foreachLine(reader) { line =>
showMatches(pattern, line) foreach { line =>
out.println(line)
println(line)
}
}
}
}
}
object OutputUtil
{
def showMatches(pattern: Pattern, line: String): Option[String] =
{
val matcher = pattern.matcher(line)
if(ConsoleLogger.formatEnabled)
{
val highlighted = matcher.replaceAll(scala.Console.RED + "$0" + scala.Console.RESET)
if(highlighted == line) None else Some(highlighted)
}
else if(matcher.find)
Some(line)
else
None
}
def mapLast[T](s: TaskStreams, ctx: Transform.Context[Project], taskName: String)(f: BufferedReader => T): Task[Task.Cross[T]] =
{
val task = taskForName(ctx, taskName)
s.readText( task, update = false ).map( f ).merge
}
def foreachLine(reader: BufferedReader)(f: String => Unit)
{
def readL()
{
val line = reader.readLine()
if(line ne null) {
f(line)
readL()
}
}
readL()
}
def taskForName(ctx: Transform.Context[Project], name: String): Task[_] =
ctx.static(ctx.rootOwner, MultiProject.transformName(name)).getOrElse(error("No task '" + name + "'"))
}
trait Exec
{
def input: Task[Input]
def streams: Task[TaskStreams]
def fork(p: Seq[String], log: Logger): Unit = fork(Process(p), log)
def fork(p: ProcessBuilder, log: Logger): Unit =
{
val exitValue = p ! log
if(exitValue != 0) error("Nonzero exit value: " + exitValue)
}
def forkWithCode(p: ProcessBuilder, log: Logger): Task[Int] = streams map { s => p ! log }
lazy val sh = (input, streams) map { case in :+: s :+: HNil => fork("sh" :: "-c" :: in.arguments :: Nil, s.log) }
lazy val exec = (input, streams) map { case in :+: s :+: HNil => fork( Process(in.splitArgs), s.log ) }
}
trait Javap extends Exec
{
def javapTask(classpath: Task[Seq[File]], scalaInstance: Task[ScalaInstance]): Task[Unit] =
javapTask( (classpath, scalaInstance) map { case cp :+: si :+: HNil => cp ++ si.jars } )
def javapTask(classpath: Task[Seq[File]]): Task[Unit] =
(input, classpath, streams) map { case in :+: cp :+: s :+: HNil =>
val args = in.splitArgs
val argsWithClasspath = if(cp.isEmpty) args else "-classpath" +: Path.makeString(cp) +: args
fork("javap" +: argsWithClasspath, s.log)
}
}