From 9c1306ff6e49b1ca93a39efc656989deec70eca1 Mon Sep 17 00:00:00 2001 From: Artyom Olshevskiy Date: Mon, 25 Apr 2011 15:27:32 +0300 Subject: [PATCH] Included scripted plugin into core Xsbt --- project/build/XSbt.scala | 6 +- scripted/plugin/Scripted.scala | 129 --------------------------- scripted/plugin/ScriptedPlugin.scala | 58 ++++++++++++ 3 files changed, 61 insertions(+), 132 deletions(-) delete mode 100644 scripted/plugin/Scripted.scala create mode 100644 scripted/plugin/ScriptedPlugin.scala diff --git a/project/build/XSbt.scala b/project/build/XSbt.scala index d51892b2d..a924753bb 100644 --- a/project/build/XSbt.scala +++ b/project/build/XSbt.scala @@ -75,8 +75,7 @@ class XSbt(info: ProjectInfo) extends ParentProject(info) with NoCrossPaths val discoverySub = project(compilePath / "discover", "Discovery", new DiscoveryProject(_), compileIncrementalSub, apiSub) val scriptedBaseSub = project("scripted" / "base", "Scripted Framework", new TestProject(_), ioSub, processSub) - val scriptedSbtSub = baseProject("scripted" / "sbt", "Scripted sbt", ioSub, logSub, processSub, scriptedBaseSub, launchInterfaceSub /*should really be a 'provided' dependency*/) - val scriptedPluginSub = project("scripted" / "plugin", "Scripted Plugin", new Scripted(_)) + val scriptedSbtSub = baseProject("scripted" / "sbt", "Scripted sbt", ioSub, logSub, processSub, scriptedBaseSub, launchInterfaceSub /*should really be a 'provided' dependency*/) // Standard task system. This provides map, flatMap, join, and more on top of the basic task model. val stdTaskSub = testedBase(tasksPath / "standard", "Task System", taskSub, collectionSub, logSub, ioSub, processSub) @@ -91,6 +90,7 @@ class XSbt(info: ProjectInfo) extends ParentProject(info) with NoCrossPaths // technically, we need a dependency on all of mainSub's dependencies, but we don't do that since this is strictly an integration project // with the sole purpose of providing certain identifiers without qualification (with a package object) val sbtSub = project(sbtPath, "Simple Build Tool", new Sbt(_), mainSub) + val scriptedPluginSub = project("scripted" / "plugin", "Scripted Plugin", new Scripted(_), sbtSub, classpathSub) /** following modules are not updated for 2.8 or 0.9 */ /* @@ -272,7 +272,7 @@ class XSbt(info: ProjectInfo) extends ParentProject(info) with NoCrossPaths { override def componentID = None } - class Scripted(info: ProjectInfo) extends PluginProject(info) with Licensed + class Scripted(info: ProjectInfo) extends DefaultProject(info) { override def managedStyle = ManagedStyle.Ivy override def scratch = true diff --git a/scripted/plugin/Scripted.scala b/scripted/plugin/Scripted.scala deleted file mode 100644 index 6c414759c..000000000 --- a/scripted/plugin/Scripted.scala +++ /dev/null @@ -1,129 +0,0 @@ -/* sbt -- Simple Build Tool - * Copyright 2008, 2009 Mark Harrah - */ -package sbt.test - -import Scripted._ -import FileUtilities.wrapNull -import java.io.File -import java.net.URLClassLoader -import xsbt.ScalaInstance - -trait ScalaScripted extends BasicScalaProject with Scripted with MavenStyleScalaPaths -{ - def sbtTests = sourcePath / SbtTestDirectoryName - def scriptedDependencies = compile :: Nil - lazy val scripted = scriptedTask(scriptedDependencies : _*) - lazy val testNoScripted = super.testAction - override def testAction = testNoScripted dependsOn(scripted) - - lazy val scriptedOnly = scriptedMethodTask(scriptedDependencies : _*) -} -trait SbtScripted extends ScalaScripted -{ - override def scriptedDependencies = publishLocal :: Nil -} -final case class ScriptedTest(group: String, name: String) extends NotNull -{ - override def toString = group + "/" + name -} -trait Scripted extends BasicManagedProject with MultiTaskProject -{ - def scriptedCompatibility = CompatibilityLevel.Minimal - def scriptedBuildVersions = CompatibilityLevel.defaultVersions(scriptedCompatibility) - def scriptedDefScala = buildScalaVersion - def scriptedSbt = projectVersion.value.toString - def scriptedBufferLog = true - - lazy val scriptedConf = config("sbt-scripted") - lazy val scriptedSbtDep = "org.scala-tools.sbt" % ("scripted-sbt_" + buildScalaVersion) % version.toString % scriptedConf.toString - def scriptedClasspath = configurationClasspath(scriptedConf) - - def sbtTests: Path - def scriptedTask(dependencies: ManagedTask*) = dynamic(scriptedTests(listTests)) dependsOn(dependencies : _*) - def scriptedMethodTask(dependencies: ManagedTask*) = multiTask(listTests.map(_.toString).toList) { (args, includeFunction) => - try { scriptedTests(listTests.filter(test => includeFunction(test.toString)), dependencies : _*) } - catch { case e: TestSetupException => task { Some(e.getMessage) } named("test-setup") } - } - def listTests = (new ListTests(sbtTests.asFile, include _, log)).listTests - def scriptedTests(tests: Seq[ScriptedTest], dependencies: ManagedTask*) = - { - val runner = Scripted.makeScripted(buildScalaInstance, scriptedClasspath)(sbtTests.asFile, scriptedBufferLog, scriptedSbt, scriptedDefScala, scriptedBuildVersions) - - val startTask = task { None } named("scripted-test-start") dependsOn(dependencies : _*) - def scriptedTest(test: ScriptedTest) = - task { Scripted.runScripted(runner, test.group, test.name, log) } named test.toString dependsOn(startTask) - val testTasks = tests.map(scriptedTest) - task {None} named("scripted-test-complete") dependsOn(testTasks : _*) - } - private def unwrapOption[T](s: T): Option[T] = if(s == null) None else Some(s) - - def include(test: ScriptedTest) = true -} -import scala.collection.mutable -private[test] object Scripted -{ - val SbtTestDirectoryName = "sbt-test" - def list(directory: File, filter: java.io.FileFilter) = wrapNull(directory.listFiles(filter)) - - def makeScripted(scalaI: ScalaInstance, cp: PathFinder)(directory: File, buffer: Boolean, sbtVersion: String, defScalaVersion: String, buildScalaVersions: String): AnyRef = - { - val loader = ClasspathUtilities.toLoader(cp, scalaI.loader) - val c = Class.forName("sbt.test.ScriptedTests", true, loader) - val con = c.getConstructor(classOf[File], classOf[Boolean], classOf[String], classOf[String], classOf[String]) - con.newInstance(directory, buffer: java.lang.Boolean, sbtVersion, defScalaVersion, buildScalaVersions).asInstanceOf[AnyRef] - } - def runScripted(runner: AnyRef, group: String, name: String, log: xsbti.Logger): Option[String] = - { - try { runner.getClass.getMethod("scriptedTest", classOf[String], classOf[String], classOf[xsbti.Logger]).invoke(runner, group, name, log); None } - catch { case x if x.getClass.getName == "xsbt.test.TestException" => Some(x.toString) } - } -} -private[test] final class ListTests(baseDirectory: File, accept: ScriptedTest => Boolean, log: Logger) extends NotNull -{ - def filter = DirectoryFilter -- HiddenFileFilter - def listTests: Seq[ScriptedTest] = - { - list(baseDirectory, filter) flatMap { group => - val groupName = group.getName - listTests(group).map(ScriptedTest(groupName, _)) - } - } - private[this] def listTests(group: File): Set[String] = - { - val groupName = group.getName - val allTests = list(group, filter) - if(allTests.isEmpty) - { - log.warn("No tests in test group " + groupName) - Set.empty - } - else - { - val (included, skipped) = allTests.toList.partition(test => accept(ScriptedTest(groupName, test.getName))) - if(included.isEmpty) - log.warn("Test group " + groupName + " skipped.") - else if(!skipped.isEmpty) - { - log.warn("Tests skipped in group " + group.getName + ":") - skipped.foreach(testName => log.warn(" " + testName.getName)) - } - Set( included.map(_.getName) : _*) - } - } -} - -object CompatibilityLevel extends Enumeration -{ - val Full, Basic, Minimal, Minimal27, Minimal28 = Value - - def defaultVersions(level: Value) = - level match - { - case Full => "2.7.4 2.7.7 2.8.0 2.8.1 2.9.0.RC1" - case Basic => "2.7.7 2.7.4 2.8.1" - case Minimal => "2.7.7 2.8.1" - case Minimal27 => "2.7.7" - case Minimal28 => "2.8.1" - } -} \ No newline at end of file diff --git a/scripted/plugin/ScriptedPlugin.scala b/scripted/plugin/ScriptedPlugin.scala new file mode 100644 index 000000000..937c14c3d --- /dev/null +++ b/scripted/plugin/ScriptedPlugin.scala @@ -0,0 +1,58 @@ +import sbt._ + +import Project.Initialize +import Keys._ +import classpath.ClasspathUtilities +import java.lang.reflect.Method +import java.util.Properties + +object ScriptedPlugin extends Plugin { + def scriptedConf = config("scripted-sbt") + + val scriptedSbt = SettingKey[String]("scripted-sbt") + val sbtLauncher = SettingKey[File]("sbt-launcher") + val sbtTestDirectory = SettingKey[File]("sbt-test-directory") + val scriptedBufferLog = SettingKey[Boolean]("scripted-buffer-log") + final case class ScriptedScalas(build: String, versions: String) + val scriptedScalas = SettingKey[ScriptedScalas]("scripted-scalas") + + val scriptedClasspath = TaskKey[PathFinder]("scripted-classpath") + val scriptedTests = TaskKey[AnyRef]("scripted-tests") + val scriptedRun = TaskKey[Method]("scripted-run") + 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[String], classOf[String], classOf[String], classOf[Array[String]], classOf[File]) + } + + def scriptedTask: Initialize[InputTask[Unit]] = InputTask(_ => complete.Parsers.spaceDelimited("")) { result => + (scriptedDependencies, scriptedTests, scriptedRun, sbtTestDirectory, scriptedBufferLog, scriptedSbt, scriptedScalas, sbtLauncher, result) map { + (deps, m, r, testdir, bufferlog, version, scriptedScalas, launcher, args) => + try { r.invoke(m, testdir, bufferlog: java.lang.Boolean, version.toString, scriptedScalas.build, scriptedScalas.versions, args.toArray, launcher) } + catch { case e: java.lang.reflect.InvocationTargetException => throw e.getCause } + } + } + + val scriptedSettings = Seq( + ivyConfigurations += scriptedConf, + scriptedSbt <<= (appConfiguration)(_.provider.id.version), + libraryDependencies <<= (libraryDependencies, scriptedSbt) {(deps, version) => deps :+ "org.scala-tools.sbt" %% "scripted-sbt" % version % scriptedConf.toString }, + sbtLauncher <<= (appConfiguration)(app => IO.classLocationFile(app.provider.scalaProvider.launcher.getClass)), + sbtTestDirectory <<= sourceDirectory / "sbt-test", + scriptedBufferLog := true, + scriptedScalas <<= (scalaInstance) { (scala) => ScriptedScalas(scala.version, scala.version) }, + scriptedClasspath <<= (classpathTypes, update) map { (ct, report) => Path.finder(Classpaths.managedJars(scriptedConf, ct, report).map(_.data)) }, + scriptedTests <<= scriptedTestsTask, + scriptedRun <<= scriptedRunTask, + scriptedDependencies <<= (compile in Test, publishLocal) map { (analysis, pub) => Unit }, + scripted <<= scriptedTask + ) +}