You must have a Parser that will analyze the data entered. When you have input, you can convert (runMain in Compile).toTask and submit the input to the task.
TL; DR; build.sbt
import sbt.complete._ import complete.DefaultParsers._ lazy val myRunTask = inputKey[Unit]("Runs actual tests") lazy val FullQualifiedClassName = (charClass(c => isScalaIDChar(c) || (c == '.'), "class name")).+.string def commaDelimited(display: String) = token(Space) ~> repsep(token(FullQualifiedClassName, display), token(",")) lazy val testClassArgs: Parser[Seq[String]] = commaDelimited("<full qualified test class name>").map { xs: Seq[String] => xs.map(e => s" -s $e ") } myRunTask := Def.inputTaskDyn { val classes = testClassArgs.parsed runMainInCompile(classes) }.evaluated def runMainInCompile(classes: Seq[String]) = Def.taskDyn { (runMain in Compile).toTask(s" org.scalatest.tools.Runner -P1 -C reporter.TestReporter -o ${classes.mkString}") }
Parser
Let's start with the analyzer. The parser should take a space, followed by your classes, separated by commas.
First, we define a parser that parses the fully qualified class name:
lazy val FullQualifiedClassName = (charClass(c => isScalaIDChar(c) || (c == '.'), "class name")).+.string
Once we get the parser, we can combine it with another parser. We need to create a parser that separates the comma-separated fully qualified class names:
def commaDelimited(display: String) = token(Space) ~> repsep(token(FullQualifiedClassName, display), token(","))
The operator ~> means that the input to its left will be discarded. The value returned from the analyzer is Seq[String] for all qualified class names.
Judging by your question, you want your classes to have the -s prefix. You can do this later, but to show another feature of the parsers, I just do it here.
You can draw the output of the analyzer and convert it to another output using map .
lazy val testClassArgs: Parser[Seq[String]] = commaDelimited("<full qualified test class name>").map { xs: Seq[String] => xs.map(e => s" -s $e ") }
OK, we're almost there.
Run an InputTask with arguments combined with a static string
We can define a new key for the input task. I chose myRunTask because otherwise it will encounter a runTask that already exists.
Define a method that takes a sequence of classes (already a prefix with -s ) as an argument and returns a Task from InputTask .
def runMainInCompile(classes: Seq[String]) = Def.taskDyn { (runMain in Compile).toTask(s" org.scalatest.tools.Runner -P1 -C reporter.TestReporter -o ${classes.mkString}") }
Now let me combine all the elements in one task:
myRunTask := Def.inputTaskDyn { val classes = testClassArgs.parsed runMainInCompile(classes) }.evaluated