I want to hava a SBT task which takes comma-separated list of test classes given by their fully qualified name as input from command line. Now that I run the task with hard-coded value but I want to get it from command line. Can someone help me in writing a task like this.
lazy val runTask = inputKey[Unit]("custom run")
runTask := {
val one = (runMain in Compile).fullInput(" org.scalatest.tools.Runner -P1 -C reporter.TestReporter -o -s testcase.GetAccountInfo -s testcase.GetProfileInfo").evaluated
}
Something like this,
sbt runTask testcase.GetProfileInfo,testcase.GetAccountInfo
Thanks in advance.
you can access your Scala command-line arguments using the args array, which is made available to you implicitly when you extend App . As an example, your code will look like this: object Foo extends App { if (args. length == 0) { println("dude, i need at least one parameter") } val filename = args(0) ... }
You have to have a Parser, which will parse the input given to the task. Once you have the input, you can convert (runMain in Compile).toTask
, and feed the input to the task.
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}")
}
Let's start with a parser. The parser must take a space, followed by your classes separated by comma.
Let's first defined a parser, which parses full qualified class name:
lazy val FullQualifiedClassName =
(charClass(c => isScalaIDChar(c) || (c == '.'), "class name")).+.string
Once we have the parser, we can combine it together with another parser. We need to create a parser, which takes comma separated full qualified class names:
def commaDelimited(display: String) =
token(Space) ~> repsep(token(FullQualifiedClassName, display), token(","))
The ~>
operator means that the input on the left of it will be discarded. The value returned from the parser is a Seq[String]
of the full qualified class names.
Judging from your question, you want your classes to be prefixed with -s
. You could do it later, but just to show one more feature of parsers, I'll just do it here.
You can take an output of a parser 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.
We can define a new input task key. I'll chose myRunTask
, because otherwise it will collide with runTask
, which already exists.
Let's define a method which takes a sequence of classes (already prefixed with -s
) as an argument, and which returns a Task
obtained from an 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's combine all elements in one task:
myRunTask := Def.inputTaskDyn {
val classes = testClassArgs.parsed
runMainInCompile(classes)
}.evaluated
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With