Guest User

Untitled

a guest
Apr 26th, 2018
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.19 KB | None | 0 0
  1. package sbt.inc
  2.  
  3. import java.io.File
  4. import java.nio.file.Path
  5.  
  6. import sbt.io.syntax._
  7. import sbt.internal.util.complete.Parser
  8. import sbt.internal.util.complete.Parser._
  9. import sbt.internal.util.complete.Parsers._
  10. import sbt.io.{AllPassFilter, NameFilter}
  11. import bloop.config.{Config, ConfigDecoders}
  12. import metaconfig.{Conf, Configured}
  13. import org.langmeta.inputs.Input
  14.  
  15. object ScriptedMain {
  16. def main(args: Array[String]): Unit = {
  17. val workingDirectory = file(System.getProperty("user.dir"))
  18. val scripted = configFromFile(workingDirectory./(".bloop")./("zincScripted-test.json"))
  19. val zinc = configFromFile(workingDirectory./(".bloop")./("zinc.json"))
  20. val sourceDir = zinc.project.directory.resolve("src").resolve("sbt-test")
  21. val fullClasspath = scripted.project.classesDir :: scripted.project.classpath.toList
  22. val parser = scriptedParser(sourceDir.toFile)
  23. Parser.parse(args.headOption.map(s => s" $s").getOrElse(""), parser) match {
  24. case Left(error) => System.err.println(s"Parser error: $error")
  25. case Right(scriptedArgs) =>
  26. runScripted(fullClasspath, sourceDir, args, true)
  27. }
  28. }
  29.  
  30. private def configFromFile(config: File): Config.File = {
  31. import metaconfig.typesafeconfig.typesafeConfigMetaconfigParser
  32. println(s"Loading project from '$config'")
  33. val input = Input.File(config)
  34. val configured = Conf.parseInput(input)(typesafeConfigMetaconfigParser)
  35. ConfigDecoders.allConfigDecoder.read(configured) match {
  36. case Configured.Ok(file) => file
  37. case Configured.NotOk(error) => sys.error(error.toString())
  38. }
  39. }
  40.  
  41. private def scriptedParser(scriptedBase: File): Parser[Seq[String]] = {
  42. case class ScriptedTestPage(page: Int, total: Int)
  43. val scriptedFiles: NameFilter = ("test": NameFilter) | "pending"
  44. val pairs = (scriptedBase * AllPassFilter * AllPassFilter * scriptedFiles).get map {
  45. (f: File) =>
  46. val p = f.getParentFile
  47. (p.getParentFile.getName, p.getName)
  48. }
  49. val pairMap = pairs.groupBy(_._1).mapValues(_.map(_._2).toSet);
  50.  
  51. val id = charClass(c => !c.isWhitespace && c != '/').+.string
  52. val groupP = token(id.examples(pairMap.keySet.toSet)) <~ token('/')
  53.  
  54. // A parser for page definitions
  55. val pageP: Parser[ScriptedTestPage] = ("*" ~ NatBasic ~ "of" ~ NatBasic) map {
  56. case _ ~ page ~ _ ~ total => ScriptedTestPage(page, total)
  57. }
  58.  
  59. // Grabs the filenames from a given test group in the current page definition.
  60. def pagedFilenames(group: String, page: ScriptedTestPage): Seq[String] = {
  61. val files = pairMap(group).toSeq.sortBy(_.toLowerCase)
  62. val pageSize = files.size / page.total
  63. // The last page may loose some values, so we explicitly keep them
  64. val dropped = files.drop(pageSize * (page.page - 1))
  65. if (page.page == page.total) dropped
  66. else dropped.take(pageSize)
  67. }
  68.  
  69. def nameP(group: String) = {
  70. token("*".id | id.examples(pairMap(group)))
  71. }
  72.  
  73. val PagedIds: Parser[Seq[String]] =
  74. for {
  75. group <- groupP
  76. page <- pageP
  77. files = pagedFilenames(group, page)
  78. } yield files map (f => group + '/' + f)
  79.  
  80. val testID = (for (group <- groupP; name <- nameP(group)) yield (group, name))
  81. val testIdAsGroup = matched(testID) map (test => Seq(test))
  82. (token(Space) ~> (PagedIds | testIdAsGroup)).* map (_.flatten)
  83. }
  84.  
  85. type IncScriptedRunner = {
  86. def run(resourceBaseDirectory: File, bufferLog: Boolean, tests: Array[String]): Unit
  87. }
  88.  
  89. import sbt.internal.inc.classpath.ClasspathUtilities
  90. def runScripted(classpath: Seq[Path], source: Path, args: Seq[String], buffer: Boolean): Unit = {
  91. println(s"About to run tests: ${args.mkString("\n * ", "\n * ", "\n")}")
  92. // Force Log4J to not use a thread context classloader otherwise it throws a CCE
  93. sys.props(org.apache.logging.log4j.util.LoaderUtil.IGNORE_TCCL_PROPERTY) = "true"
  94. val loader = ClasspathUtilities.toLoader(classpath.map(_.toFile))
  95. val bridgeClass = Class.forName("sbt.internal.inc.IncScriptedRunner", true, loader)
  96. val bridge = bridgeClass.newInstance.asInstanceOf[IncScriptedRunner]
  97. try bridge.run(source.toFile, buffer, args.toArray)
  98. catch { case ite: java.lang.reflect.InvocationTargetException => throw ite.getCause }
  99. }
  100. }
Add Comment
Please, Sign In to add comment