Def.inputTaskDyn
returns a value of typeInputTask[T]
and doesn't perform any side effects. The result needs to be bound to anInputKey
, likelastReport
. The return type ofopenLastReport
isUnit
, which means thatopenLastReport
will construct a value that will be discarded, effectively doing nothing useful. Instead, have:def openLastReport(...): InputTask[...] = ... lastReport := openLastReport(...).evaluated
(Or, the implementation of
openLastReport
can be inlined into the right hand side of:=
)You probably don't need
inputTaskDyn
, but justinputTask
. You only needinputTaskDyn
if you need to return a task. Otherwise, useinputTask
and drop theDef.task
.
Filtering tab completion in input task implementation
-
07-10-2022 - |
Pregunta
I'm currently implementing a SBT plugin for Gatling. One of its features will be to open the last generated report in a new browser tab from SBT. As each run can have a different "simulation ID" (basically a simple string), I'd like to offer tab completion on simulation ids.
An example :
Running the Gatling SBT plugin will produce several folders (named from simulationId + date of report generaation) in target/gatling
, for example mysim-20140204234534
, myothersim-20140203124534
and yetanothersim-20140204234534
.
Let's call the task lastReport
.
If someone start typing lastReport my
, I'd like to filter out tab-completion to only suggest mysim
and myothersim
.
Getting the simulation ID is a breeze, but how can help the parser and filter out suggestions so that it only suggest an existing simulation ID ?
To sum up, I'd like to do what testOnly
do, in a way : I only want to suggest things that make sense in my context.
Thanks in advance for your answers,
Pierre
Edit : As I got a bit stuck after my latest tries, here is the code of my inputTask, in it's current state :
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)))
}
}
}
Of course, openReport
is called using the results of allReports
and allSimulationIds
tasks.
I think I'm close to a functioning input task but I'm still missing something...
Solución