mirror of https://github.com/sbt/sbt.git
130 lines
5.4 KiB
Scala
130 lines
5.4 KiB
Scala
/* sbt -- Simple Build Tool
|
|
* Copyright 2011 Artyom Olshevskiy
|
|
*/
|
|
package sbt
|
|
|
|
import Def.Initialize
|
|
import Keys._
|
|
import complete.{ Parser, DefaultParsers }
|
|
import classpath.ClasspathUtilities
|
|
import java.lang.reflect.{ InvocationTargetException, Method }
|
|
import java.util.Properties
|
|
import CrossVersion.binarySbtVersion
|
|
|
|
object ScriptedPlugin extends Plugin {
|
|
def scriptedConf = config("scripted-sbt") hide
|
|
def scriptedLaunchConf = config("scripted-sbt-launch") hide
|
|
|
|
val scriptedSbt = SettingKey[String]("scripted-sbt")
|
|
val sbtLauncher = TaskKey[File]("sbt-launcher")
|
|
|
|
val sbtTestDirectory = SettingKey[File]("sbt-test-directory")
|
|
val scriptedBufferLog = SettingKey[Boolean]("scripted-buffer-log")
|
|
|
|
val scriptedClasspath = TaskKey[PathFinder]("scripted-classpath")
|
|
val scriptedTests = TaskKey[AnyRef]("scripted-tests")
|
|
val scriptedRun = TaskKey[Method]("scripted-run")
|
|
val scriptedLaunchOpts = SettingKey[Seq[String]]("scripted-launch-opts", "options to pass to jvm launching scripted tasks")
|
|
val scriptedDependencies = TaskKey[Unit]("scripted-dependencies")
|
|
val scripted = InputKey[Unit]("scripted")
|
|
|
|
def scriptedTestsTask: Initialize[Task[AnyRef]] = (scriptedClasspath, scalaInstance) map {
|
|
(classpath, scala) =>
|
|
val loader = ClasspathUtilities.toLoader(classpath, scala.loader)
|
|
ModuleUtilities.getObject("sbt.test.ScriptedTests", loader)
|
|
}
|
|
|
|
def scriptedRunTask: Initialize[Task[Method]] = (scriptedTests) map {
|
|
(m) =>
|
|
m.getClass.getMethod("run", classOf[File], classOf[Boolean], classOf[Array[String]], classOf[File], classOf[Array[String]])
|
|
}
|
|
|
|
import DefaultParsers._
|
|
case class ScriptedTestPage(page: Int, total: Int)
|
|
|
|
private[sbt] def scriptedParser(scriptedBase: File): Parser[Seq[String]] =
|
|
{
|
|
|
|
val scriptedFiles: NameFilter = ("test": NameFilter) | "pending"
|
|
val pairs = (scriptedBase * AllPassFilter * AllPassFilter * scriptedFiles).get map { (f: File) =>
|
|
val p = f.getParentFile
|
|
(p.getParentFile.getName, p.getName)
|
|
}
|
|
val pairMap = pairs.groupBy(_._1).mapValues(_.map(_._2).toSet);
|
|
|
|
val id = charClass(c => !c.isWhitespace && c != '/').+.string
|
|
val groupP = token(id.examples(pairMap.keySet.toSet)) <~ token('/')
|
|
|
|
// A parser for page definitions
|
|
val pageP: Parser[ScriptedTestPage] = ("*" ~ NatBasic ~ "of" ~ NatBasic) map {
|
|
case _ ~ page ~ _ ~ total => ScriptedTestPage(page, total)
|
|
}
|
|
// Grabs the filenames from a given test group in the current page definition.
|
|
def pagedFilenames(group: String, page: ScriptedTestPage): Seq[String] = {
|
|
val files = pairMap(group).toSeq.sortBy(_.toLowerCase)
|
|
val pageSize = files.size / page.total
|
|
// The last page may loose some values, so we explicitly keep them
|
|
val dropped = files.drop(pageSize * (page.page - 1))
|
|
if (page.page == page.total) dropped
|
|
else dropped.take(pageSize)
|
|
}
|
|
def nameP(group: String) = {
|
|
token("*".id | id.examples(pairMap(group)))
|
|
}
|
|
val PagedIds: Parser[Seq[String]] =
|
|
for {
|
|
group <- groupP
|
|
page <- pageP
|
|
files = pagedFilenames(group, page)
|
|
// TODO - Fail the parser if we don't have enough files for the given page size
|
|
//if !files.isEmpty
|
|
} yield files map (f => group + '/' + f)
|
|
|
|
val testID = (for (group <- groupP; name <- nameP(group)) yield (group, name))
|
|
val testIdAsGroup = matched(testID) map (test => Seq(test))
|
|
//(token(Space) ~> matched(testID)).*
|
|
(token(Space) ~> (PagedIds | testIdAsGroup)).* map (_.flatten)
|
|
}
|
|
|
|
def scriptedTask: Initialize[InputTask[Unit]] = Def.inputTask {
|
|
val args = scriptedParser(sbtTestDirectory.value).parsed
|
|
val prereq: Unit = scriptedDependencies.value
|
|
try {
|
|
scriptedRun.value.invoke(
|
|
scriptedTests.value, sbtTestDirectory.value, scriptedBufferLog.value: java.lang.Boolean,
|
|
args.toArray, sbtLauncher.value, scriptedLaunchOpts.value.toArray)
|
|
} catch { case e: java.lang.reflect.InvocationTargetException => throw e.getCause }
|
|
}
|
|
|
|
val scriptedSettings = Seq(
|
|
ivyConfigurations ++= Seq(scriptedConf, scriptedLaunchConf),
|
|
scriptedSbt := (sbtVersion in pluginCrossBuild).value,
|
|
sbtLauncher <<= getJars(scriptedLaunchConf).map(_.get.head),
|
|
sbtTestDirectory := sourceDirectory.value / "sbt-test",
|
|
libraryDependencies ++= {
|
|
binarySbtVersion(scriptedSbt.value) match {
|
|
case "0.13" =>
|
|
Seq(
|
|
"org.scala-sbt" % "scripted-sbt" % scriptedSbt.value % scriptedConf.toString,
|
|
"org.scala-sbt" % "sbt-launch" % scriptedSbt.value % scriptedLaunchConf.toString
|
|
)
|
|
case sv if sv startsWith "1.0." =>
|
|
Seq(
|
|
"org.scala-sbt" %% "scripted-sbt" % scriptedSbt.value % scriptedConf.toString,
|
|
"org.scala-sbt" % "sbt-launch" % scriptedSbt.value % scriptedLaunchConf.toString
|
|
)
|
|
}
|
|
},
|
|
scriptedBufferLog := true,
|
|
scriptedClasspath := getJars(scriptedConf).value,
|
|
scriptedTests <<= scriptedTestsTask,
|
|
scriptedRun <<= scriptedRunTask,
|
|
scriptedDependencies <<= (compile in Test, publishLocal) map { (analysis, pub) => Unit },
|
|
scriptedLaunchOpts := Seq(),
|
|
scripted <<= scriptedTask
|
|
)
|
|
private[this] def getJars(config: Configuration): Initialize[Task[PathFinder]] = Def.task {
|
|
PathFinder(Classpaths.managedJars(config, classpathTypes.value, update.value).map(_.data))
|
|
}
|
|
}
|