diff --git a/main/Defaults.scala b/main/Defaults.scala index 0202aad8a..847d5e4be 100644 --- a/main/Defaults.scala +++ b/main/Defaults.scala @@ -45,6 +45,8 @@ object Defaults extends BuildCommon def globalCore: Seq[Setting[_]] = inScope(GlobalScope)(Seq( pollInterval :== 500, logBuffered :== false, + trapExit :== false, + trapExit in run :== true, logBuffered in testOnly :== true, logBuffered in test :== true, traceLevel in console :== Int.MaxValue, @@ -83,7 +85,8 @@ object Defaults extends BuildCommon )) def projectCore: Seq[Setting[_]] = Seq( name <<= thisProject(_.id), - version :== "0.1" + version :== "0.1", + runnerSetting ) def paths = Seq( baseDirectory <<= thisProject(_.base), @@ -357,12 +360,12 @@ object Defaults extends BuildCommon } def runnerSetting = - runner <<= (scalaInstance, baseDirectory, javaOptions, outputStrategy, fork, javaHome) { (si, base, options, strategy, forkRun, javaHomeDir) => + runner <<= (scalaInstance, baseDirectory, javaOptions, outputStrategy, fork, javaHome, trapExit) { (si, base, options, strategy, forkRun, javaHomeDir, trap) => if(forkRun) { new ForkRun( ForkOptions(scalaJars = si.jars, javaHome = javaHomeDir, outputStrategy = strategy, runJVMOptions = options, workingDirectory = Some(base)) ) } else - new Run(si) + new Run(si, trap) } def docTask: Initialize[Task[File]] = diff --git a/main/Keys.scala b/main/Keys.scala index da02ee977..997027707 100644 --- a/main/Keys.scala +++ b/main/Keys.scala @@ -143,6 +143,7 @@ object Keys val runMain = InputKey[Unit]("run-main", "Runs the main class selected by the first argument, passing the remaining arguments to the main method.") val discoveredMainClasses = TaskKey[Seq[String]]("discovered-main-classes", "Auto-detects main classes.") val runner = SettingKey[ScalaRun]("runner", "Implementation used to run a main class.") + val trapExit = SettingKey[Boolean]("trap-exit", "If true, enables exit trapping and thread management for 'run'-like tasks. This is currently only suitable for serially-executed 'run'-like tasks.") val fork = SettingKey[Boolean]("fork", "If true, forks a new JVM when running. If false, runs in the same JVM as the build.") val outputStrategy = SettingKey[Option[sbt.OutputStrategy]]("output-strategy", "Selects how to log output when running a main class.") diff --git a/run/Run.scala b/run/Run.scala index d92dd8538..afb04eadb 100644 --- a/run/Run.scala +++ b/run/Run.scala @@ -31,7 +31,7 @@ class ForkRun(config: ForkScalaRun) extends ScalaRun Some("Nonzero exit code returned from " + label + ": " + exitCode) } } -class Run(instance: ScalaInstance) extends ScalaRun +class Run(instance: ScalaInstance, trapExit: Boolean) extends ScalaRun { /** Runs the class 'mainClass' using the given classpath and options using the scala runner.*/ def run(mainClass: String, classpath: Seq[File], options: Seq[String], log: Logger) = @@ -41,8 +41,9 @@ class Run(instance: ScalaInstance) extends ScalaRun def execute = try { run0(mainClass, classpath, options, log) } catch { case e: java.lang.reflect.InvocationTargetException => throw e.getCause } + def directExecute = try { execute; None } catch { case e: Exception => log.trace(e); Some(e.toString) } - Run.executeTrapExit( execute, log ) + if(trapExit) Run.executeTrapExit( execute, log ) else directExecute } private def run0(mainClassName: String, classpath: Seq[File], options: Seq[String], log: Logger) {