Last active
October 23, 2019 08:05
-
-
Save jrudolph/190eb628b16fa3bc1e6de42f3835be96 to your computer and use it in GitHub Desktop.
sbt camel case and dot expanding testOnly see https://asciinema.org/a/276464?t=20 for a demo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// copy into project | |
import sbt._ | |
import Keys._ | |
import Def._ | |
import sbt.Def | |
import sbt.Defaults.allTestGroupsTask | |
import sbt.Defaults.loadForParser | |
import sbt.Project.inConfig | |
import sbt.internal.util.complete.DefaultParsers | |
import sbt.internal.util.complete.Parser | |
import sbt.librarymanagement.Configurations.Test | |
import sjsonnew.BasicJsonProtocol._ | |
object BetterTestOnly extends AutoPlugin { | |
override def trigger: PluginTrigger = allRequirements | |
override def projectSettings: Seq[Def.Setting[_]] = inConfig(Test) { | |
Seq( | |
testOnly := inputTests(testOnly).evaluated | |
) | |
} | |
def inputTests(key: InputKey[_]): Initialize[InputTask[Unit]] = | |
inputTests0.mapReferenced(Def.mapScope(_ in key.key)) | |
private[this] lazy val inputTests0: Initialize[InputTask[Unit]] = { | |
val parser = loadForParser(definedTestNames)((s, i) => testOnlyParser(s, i getOrElse Nil)) | |
Def.inputTaskDyn { | |
val (selected, frameworkOptions) = parser.parsed | |
val s = streams.value | |
val filter = testFilter.value | |
val config = testExecution.value | |
implicit val display = Project.showContextKey(state.value) | |
val modifiedOpts = Tests.Filters(filter(selected)) +: Tests.Argument(frameworkOptions: _*) +: config.options | |
val newConfig = config.copy(options = modifiedOpts) | |
val output = allTestGroupsTask( | |
s, | |
loadedTestFrameworks.value, | |
testLoader.value, | |
testGrouping.value, | |
newConfig, | |
fullClasspath.value, | |
testForkedParallel.value, | |
javaOptions.value | |
) | |
val taskName = display.show(Keys.resolvedScoped.value) | |
val trl = testResultLogger.value | |
val processed = output.map(out => trl.run(s.log, out, taskName)) | |
processed | |
} | |
} | |
def testOnlyParser: (State, Seq[String]) => Parser[(Seq[String], Seq[String])] = { | |
(state, tests) => | |
import DefaultParsers._ | |
val selectTests = distinctParser(tests.toSet, false) | |
val options = (token(Space) ~> token("--") ~> spaceDelimited("<option>")) ?? Nil | |
selectTests ~ options | |
} | |
private def distinctParser(exs: Set[String], raw: Boolean): Parser[Seq[String]] = { | |
import DefaultParsers._, Parser.and | |
def filterQuery(query: String): String => Boolean = { | |
val reg = | |
query | |
.replaceAll("([A-Z])", "[^A-Z]*$1") | |
.replaceAll("\\.", "[^.]*\\\\.") | |
println(s"regexp: [$reg]") | |
ex => reg.r.findAllMatchIn(ex).nonEmpty | |
} | |
val base = token(Space) ~> token(NotSpaceClass.+.map(_.mkString) examples exs) <~ Space | |
base flatMap { ex => | |
println(s"Looking for [$ex]") | |
val matching = if (ex.length >= 3) exs.filter(filterQuery(ex)) else Nil | |
if (matching.nonEmpty) { | |
println(s"Found: $matching") | |
val next = matching.map(m => token(Parser.literal("(") ~> m <~ ")")).reduce(_ | _) | |
next.map(_ :: Nil) | |
} else | |
Parser.failure("No matching test found") | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment