在输入任务实现中过滤选项卡完成

时间:2014-02-04 20:55:00

标签: sbt tab-completion

我目前正在为Gatling实施一个SBT插件。 其功能之一是在SBT的新浏览器选项卡中打开上次生成的报告。 由于每次运行可以有不同的“模拟ID”(基本上是一个简单的字符串),我想在模拟ID上提供标签完成。

一个例子:

运行Gatling SBT插件将在target/gatling中生成多个文件夹(以simulationId +报告生成日期命名),例如mysim-20140204234534myothersim-20140203124534yetanothersim-20140204234534。< / p>

让我们调用任务lastReport。 如果有人开始输入lastReport my,我想过滤掉标签完成功能,只建议mysimmyothersim

获取模拟ID是一件轻而易举的事,但是如何帮助解析器并过滤掉建议,以便它只建议现有​​的模拟ID?

总而言之,我想以某种方式做testOnly所做的事情:我只想提出在我的背景下有意义的事情。

提前感谢您的回答,

皮尔

编辑:因为我在最近的尝试后有点卡住,这是我的inputTask的代码,在它的当前状态:

package io.gatling.sbt

import sbt._
import sbt.complete.{ DefaultParsers, Parser }

import io.gatling.sbt.Utils._

object GatlingTasks {

val lastReport = inputKey[Unit]("Open last report in browser")

val allSimulationIds = taskKey[Set[String]]("List of simulation ids found in reports folder")

val allReports = taskKey[List[Report]]("List of all reports by simulation id and timestamp")

def findAllReports(reportsFolder: File): List[Report] = {
    val allDirectories = (reportsFolder ** DirectoryFilter.&&(new PatternFilter(reportFolderRegex.pattern))).get
    allDirectories.map(file => (file, reportFolderRegex.findFirstMatchIn(file.getPath).get)).map {
        case (file, regexMatch) => Report(file, regexMatch.group(1), regexMatch.group(2))
    }.toList
}

def findAllSimulationIds(allReports: Seq[Report]): Set[String] = allReports.map(_.simulationId).distinct.toSet

def openLastReport(allReports: List[Report], allSimulationIds: Set[String]): Unit = {
    def simulationIdParser(allSimulationIds: Set[String]): Parser[Option[String]] =
        DefaultParsers.ID.examples(allSimulationIds, check = true).?

    def filterReportsIfSimulationIdSelected(allReports: List[Report], simulationId: Option[String]): List[Report] =
        simulationId match {
            case Some(id) => allReports.filter(_.simulationId == id)
            case None => allReports
        }

    Def.inputTaskDyn {
        val selectedSimulationId = simulationIdParser(allSimulationIds).parsed
        val filteredReports = filterReportsIfSimulationIdSelected(allReports, selectedSimulationId)
        val reportsSortedByDate = filteredReports.sorted.map(_.path)
        Def.task(reportsSortedByDate.headOption.foreach(file => openInBrowser((file / "index.html").toURI)))
    }
}

}

当然,使用openReportallReports任务的结果调用allSimulationIds。 我认为我接近一个正常运作的输入任务,但我仍然缺少一些东西......

1 个答案:

答案 0 :(得分:1)

  1. Def.inputTaskDyn返回InputTask[T]类型的值,不执行任何副作用。结果需要绑定到InputKey,例如lastReportopenLastReport的返回类型为Unit,这意味着openLastReport将构造一个将被丢弃的值,实际上没有任何用处。相反,有:

    def openLastReport(...): InputTask[...] = ...
    
    lastReport := openLastReport(...).evaluated
    

    (或者openLastReport的实施可以内联到:=的右侧

  2. 您可能不需要inputTaskDyn,只需要inputTask。如果需要返回任务,则只需要inputTaskDyn。否则,请使用inputTask并放弃Def.task

相关问题