Skip to content

Commit

Permalink
uses scripted framework for testing, instead of process. #25
Browse files Browse the repository at this point in the history
  • Loading branch information
eed3si9n committed Oct 16, 2011
1 parent d8edb0f commit e3fbf2c
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 16 deletions.
8 changes: 5 additions & 3 deletions README.markdown
Expand Up @@ -132,9 +132,11 @@ directory names also participate in template expansion, e.g.
src/main/g8/src/main/scala/$classname$.scala

If you enter sbt's interactive mode in the base directory of a
template project, the action "g8-sbt-test" will apply the template in the
default output directory (under `target/g8`) and run `sbt update test`
for *that* project in a forked process. This is a good sanity
template project, the action "g8-test" will apply the template in the
default output directory (under `target/sbt-test`) and run the scripted
test for *that* project in a forked process.
You can supply the test scripted as `src/test/g8/test`, otherwise `>test`
is used. This is a good sanity
check for templates that are supposed to produce sbt projects.

But what if your template is not for an sbt project?
Expand Down
40 changes: 29 additions & 11 deletions plugin/src/main/scala/giterate-plugin.scala
Expand Up @@ -5,15 +5,18 @@ import sbt._
object Plugin extends sbt.Plugin {
import Keys._
import scala.io.Source
import Scripted._

object G8Keys {
lazy val g8 = TaskKey[Seq[File]]("g8", "Apply default parameters to input templates and write to output.")
lazy val outputPath = SettingKey[File]("g8-output-path")
lazy val propertiesFile = SettingKey[File]("g8-properties-file")
lazy val properties = SettingKey[Map[Any, Any]]("g8-properties")
lazy val sbtTest = TaskKey[Unit]("g8-sbt-test", "Run `sbt test` in output to smoke-test the templates")
lazy val testScript = SettingKey[File]("g8-test-script")
lazy val g8Test = InputKey[Unit]("g8-test", "Run `sbt test` in output to smoke-test the templates")
lazy val g8TestBufferLog = SettingKey[Boolean]("g8-test-buffer-log")
}

import G8Keys._

lazy val baseGiter8Settings: Seq[sbt.Project.Setting[_]] = Seq(
Expand All @@ -32,15 +35,30 @@ object Plugin extends sbt.Plugin {
val p = new java.util.Properties
p.load(new java.io.ByteArrayInputStream(IO.readBytes(f)))
Map((for { k <- p.propertyNames } yield (k.toString, p.getProperty(k.toString))).toSeq:_*)
},
sbtTest <<= (g8, outputPath in g8) map { (g8, outputPath) =>
import Process._
(new java.lang.ProcessBuilder("sbt", "test") directory outputPath)! match {
case 0 => None
case code => error("failed to run `sbt update test` in %s with code %d" format
(outputPath, code))
}
}
)
lazy val giter8Settings: Seq[sbt.Project.Setting[_]] = inConfig(Compile)(baseGiter8Settings)

lazy val giter8TestSettings: Seq[sbt.Project.Setting[_]] = scriptedSettings ++ Seq(
g8Test in Test <<= scriptedTask,
scriptedDependencies <<= (g8 in Test) map { _ => },
g8 in Test <<= (unmanagedSourceDirectories in g8 in Compile,
sources in g8 in Compile, outputPath in g8 in Test,
properties in g8 in Test, testScript in Test, streams) map { (base, srcs, out, props, ts, s) =>
IO.delete(out)
val retval = G8(srcs x relativeTo(base), out, props, s.log)

// copy test script or generate one
val script = new File(out, "test")
if (ts.exists) IO.copyFile(ts, script)
else IO.write(script, """>test""")
retval :+ script
},
sbtTestDirectory <<= (target) { dir => dir / "sbt-test" },
outputPath in g8 in Test <<= (sbtTestDirectory, name) { (dir, name) => dir / name / "scripted" },
testScript <<= (sourceDirectory in Test) { dir => dir / "g8" / "test" },
scriptedBufferLog <<= g8TestBufferLog,
g8TestBufferLog := true
)

lazy val giter8Settings: Seq[sbt.Project.Setting[_]] = inConfig(Compile)(baseGiter8Settings) ++ giter8TestSettings
}
64 changes: 64 additions & 0 deletions plugin/src/main/scala/scripted.scala
@@ -0,0 +1,64 @@
/** copied from https://github.com/harrah/xsbt/blob/0.11/scripted/plugin/ScriptedPlugin.scala.
* since ScriptedPlugin is not within a package, it cannot be reused from a packaged class.
*/

package giter8

import sbt._

import Project.Initialize
import Keys._
import classpath.ClasspathUtilities
import java.lang.reflect.Method
import java.util.Properties

object Scripted {
def scriptedConf = config("g8-scripted-sbt") hide

val scriptedSbt = SettingKey[String]("_g8-scripted-sbt")
val sbtLauncher = SettingKey[File]("_g8-sbt-launcher")
val sbtTestDirectory = SettingKey[File]("_g8-sbt-test-directory")
val scriptedBufferLog = SettingKey[Boolean]("_g8-scripted-buffer-log")
final case class ScriptedScalas(build: String, versions: String)
val scriptedScalas = SettingKey[ScriptedScalas]("_g8-scripted-scalas")

val scriptedClasspath = TaskKey[PathFinder]("_g8-scripted-classpath")
val scriptedTests = TaskKey[AnyRef]("_g8-scripted-tests")
val scriptedRun = TaskKey[Method]("_g8-scripted-run")
val scriptedDependencies = TaskKey[Unit]("_g8-scripted-dependencies")

This comment has been minimized.

Copy link
@n8han

n8han Oct 16, 2011

indentation slip

val scripted = InputKey[Unit]("_g8-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("<arg>")) { 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 }
}
}

lazy val scriptedSettings: Seq[sbt.Project.Setting[_]] = Seq(
ivyConfigurations += scriptedConf,
scriptedSbt <<= (appConfiguration)(_.provider.id.version),
scriptedScalas <<= (scalaVersion) { (scala) => ScriptedScalas(scala, scala) },
libraryDependencies <<= (libraryDependencies, scriptedScalas, scriptedSbt) {(deps, scalas, version) => deps :+ "org.scala-tools.sbt" % ("scripted-sbt_" + scalas.build) % version % scriptedConf.toString },
sbtLauncher <<= (appConfiguration)(app => IO.classLocationFile(app.provider.scalaProvider.launcher.getClass)),
sbtTestDirectory <<= sourceDirectory / "sbt-test",
scriptedBufferLog := true,
scriptedClasspath <<= (classpathTypes, update) map { (ct, report) => PathFinder(Classpaths.managedJars(scriptedConf, ct, report).map(_.data)) },
scriptedTests <<= scriptedTestsTask,
scriptedRun <<= scriptedRunTask,
scriptedDependencies <<= (compile in Test, publishLocal) map { (analysis, pub) => Unit },
scripted <<= scriptedTask
)
}
7 changes: 5 additions & 2 deletions project/build.scala
Expand Up @@ -38,8 +38,11 @@ object Builds extends sbt.Build {
lazy val plugin = Project("giter8-plugin", file("plugin"),
settings = buildSettings ++ Seq(
sbtPlugin := true,
libraryDependencies <++= (sbtDependency) { sd =>
Seq(sd, "org.antlr" % "stringtemplate" % "3.2.1")
libraryDependencies <++= (sbtDependency, sbtVersion) { (sd, sv) =>
Seq(sd,
"org.antlr" % "stringtemplate" % "3.2.1",
"org.scala-tools.sbt" %% "scripted-plugin" % sv
)
}
))
}

0 comments on commit e3fbf2c

Please sign in to comment.