forked from sbt/zinc
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
These are the improvements that I've added to scripted: 1. Scripted is now parallel and does batch execution. 2. Scripted logs to both a file and the console (if `bufferLog == true`). All the logs can be inspected locally by going to a directory in `/tmp`. This directory is shown to the user at the end of the execution. 3. Scripted UI has been improved. 3.1. Colors are used for `+` and `x`. 3.1. It shows the command that actually failed, not `Command failed {line 1}`. 3.2. It trims the stack traces of the wrapping exceptions (corresponding to the scripted infrastructure). Only the stack traces of the causing exceptions are shown (which are the ones we're interested in and are usually assertion errors). I think these improvements enhance the current dev workflow considerably. I invite you to give them a try. This change combined with sbt#429, gives a really fast execution of scripted. Testing just one test is under 7 seconds in my machine (note that in those 7 seconds we have to fetch the bridge, etc).
- Loading branch information
Showing
5 changed files
with
376 additions
and
10 deletions.
There are no files selected for viewing
64 changes: 64 additions & 0 deletions
64
internal/zinc-scripted/src/test/scala/sbt/internal/inc/BatchScriptRunner.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package sbt.internal.inc | ||
|
||
import org.scalatest.exceptions.TestFailedException | ||
import sbt.internal.inc | ||
import sbt.internal.scripted._ | ||
import sbt.internal.inc.BatchScriptRunner.States | ||
|
||
/** Defines an alternative script runner that allows batch execution. */ | ||
private[sbt] class BatchScriptRunner extends ScriptRunner { | ||
|
||
/** Defines a method to run batched execution. | ||
* | ||
* @param statements The list of handlers and statements. | ||
* @param states The states of the runner. In case it's empty, inherited apply is called. | ||
*/ | ||
def apply(statements: List[(StatementHandler, Statement)], states: States): Unit = { | ||
if (states.isEmpty) super.apply(statements) | ||
else statements.foreach(st => processStatement(st._1, st._2, states)) | ||
} | ||
|
||
def initStates(states: States, handlers: Seq[StatementHandler]): Unit = | ||
handlers.foreach(handler => states(handler) = handler.initialState) | ||
|
||
def cleanUpHandlers(handlers: Seq[StatementHandler], states: States): Unit = { | ||
for (handler <- handlers; state <- states.get(handler)) { | ||
try handler.finish(state.asInstanceOf[handler.State]) | ||
catch { case _: Exception => () } | ||
} | ||
} | ||
|
||
import BatchScriptRunner.PreciseScriptedError | ||
def processStatement(handler: StatementHandler, statement: Statement, states: States): Unit = { | ||
val state = states(handler).asInstanceOf[handler.State] | ||
val nextState = | ||
try { Right(handler(statement.command, statement.arguments, state)) } catch { | ||
case e: Exception => Left(e) | ||
} | ||
nextState match { | ||
case Left(err) => | ||
if (statement.successExpected) { | ||
err match { | ||
case t: TestFailed => | ||
val errorMessage = s"${t.getMessage} produced by" | ||
throw new PreciseScriptedError(statement, errorMessage, null) | ||
case _ => throw new PreciseScriptedError(statement, "Command failed", err) | ||
} | ||
} else () | ||
case Right(s) => | ||
if (statement.successExpected) states(handler) = s | ||
else throw new PreciseScriptedError(statement, "Expecting error at", null) | ||
} | ||
} | ||
} | ||
|
||
private[sbt] object BatchScriptRunner { | ||
import scala.collection.mutable | ||
type States = mutable.HashMap[StatementHandler, Any] | ||
|
||
// Should be used instead of sbt.internal.scripted.TestException that doesn't show failed command | ||
final class PreciseScriptedError(st: Statement, msg: String, e: Throwable) | ||
extends RuntimeException(s"$msg: '${st.command} ${st.arguments.mkString(" ")}'", e) { | ||
override def fillInStackTrace = e | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.