正如Daniel C. Sobral所述,
parsed和
evaluated是宏,在中定义
InputWrapper。
由于它们是在编译时执行的,并且参数是在运行时检索的,因此它们混合得不好。特别是,args的值仅在运行时才真正定义,并且不能由
evaluated宏检索。
编辑: 与OP聊天之后,我确定他的目标是写作的捷径,
myTask Foo bar而不是
testonly *Foo* ----tests=*bar*,我相应地更新了我的答案。
更新的答案
如前所述,由于您基本上希望编写一个“宏”
myTask Foo bar而不是
testonly *Foo* ----tests=*bar*,因此这是我的解决方案:
val filtersParser = { import complete.DefaultParsers._ (token(Space) ~> token(StringBasic, "<classFilter>")) ~ (token(Space) ~> token(StringBasic, "<methodFilter>"))}lazy val testFiltered = inputKey[Unit]("runs test methods matching *<methodFilter>* within classes matching *<classFilter>*")testFiltered.in(Test) := Def.inputTaskDyn { val (classFilter, methodFilter) = filtersParser.parsed runTestsFiltered(classFilter, methodFilter)}.evaluateddef runTestsFiltered(classFilter: String, methodFilter: String) = Def.taskDyn { (testonly in Test).toTask(s" *$classFilter* -- --tests *$methodFilter*")}更详细
您需要一个自定义解析器来检索您期望的两个参数。这是通过以下代码实现的,该代码基本上定义了两个组,即“切分”两个空格而不记住它们,以及两个
StringBasic参数,它们是解析器的结果(
filtersParser类型为
Parser[(String,String)])
val filtersParser = { import complete.DefaultParsers._ (token(Space) ~> token(StringBasic, "<classFilter>")) ~ (token(Space) ~> token(StringBasic, "<methodFilter>"))}然后,您需要一个输入任务来使用解析器的结果并将其转发到测试框架。这是在下一个代码段中完成的(如果比我更精通的人希望了解使用an的微妙之处
inputTaskDyn,我很乐意为您提供启发:))。请注意任务范围的定义,该范围
.in(Test)授予对测试依赖项的访问权限。
lazy val testFiltered = inputKey[Unit]("runs test methods matching *<methodFilter>* within classes matching *<classFilter>*")testFiltered.in(Test) := Def.inputTaskDyn { val (classFilter, methodFilter) = filtersParser.parsed runTestsFiltered(classFilter, methodFilter)}.evaluated代码的最后一部分只是将参数转发给预先存在的
testOnly任务:
def runTestsFiltered(classFilter: String, methodFilter: String) = Def.taskDyn { (testonly in Test).toTask(s" *$classFilter* -- --tests *$methodFilter*")}先前的答案
但是,您应该能够通过将定义和用法拆分为两个任务来解决它:
import sbt._import complete.DefaultParsers._lazy val loadArgTask = inputKey[Unit]("loads and transforms argument")lazy val runStuff = taskKey[Unit]("Runs some stuff")lazy val loadArgIntoPropertyTask: Def.Initialize[InputTask[Unit]] = Def.inputTask { val myArg = (token(Space) ~> token(StringBasic, "<myArg>")).parsed System.setProperty("myArg", myArg + "foo")}loadArgTask <<= loadArgIntoPropertyTaskrunStuff := { println(System.getProperty("myArg"))}可以如下使用
> loadArgTask orange[success] Total time: 0 s, completed [...]> runStufforangefoo[success] Total time: 0 s, completed [...]



