Skip to content

Instantly share code, notes, and snippets.

@eamelink
Last active August 29, 2015 13:57
Show Gist options
  • Save eamelink/9652084 to your computer and use it in GitHub Desktop.
Save eamelink/9652084 to your computer and use it in GitHub Desktop.
Compiling templates to an object that throws a runtime error. Useful for large refactorings, where you temporarily don't want to be bothered by compilation errors in templates.
import sbt._
import Keys._
import play.Project._
object ApplicationBuild extends Build {
val appName = "fake-templates"
val appVersion = "1.0-SNAPSHOT"
val appDependencies = Seq(
// Add your project dependencies here,
jdbc,
anorm)
val main = play.Project(appName, appVersion, appDependencies).settings(
// Add your own project settings here
sourceGenerators in Compile ~= { (sg) => sg.init },
sourceGenerators in Compile <+= (state, sourceDirectory in Compile, sourceManaged in Compile, templatesTypes, templatesImport) map FakeScalaTemplateCompiler.FakeScalaTemplates)
object FakeScalaTemplateCompiler {
import scalax.file._
import scala.util.parsing.input._
import play.templates._
import play.templates.ScalaTemplateCompiler._
import java.io.File
def FakeScalaTemplates(state: State, sourceDirectory: java.io.File, generatedDir: java.io.File, templateTypes: PartialFunction[String, (String, String)], additionalImports: Seq[String]) = {
import play.templates._
val templateExt: PartialFunction[File, (File, String, String, String)] = {
case p if templateTypes.isDefinedAt(p.name.split('.').last) =>
val extension = p.name.split('.').last
val exts = templateTypes(extension)
(p, extension, exts._1, exts._2)
}
(generatedDir ** "*.template.scala").get.map(GeneratedSource(_)).foreach(_.sync())
try {
(sourceDirectory ** "*.scala.*").get.collect(templateExt).foreach {
case (template, extension, t, format) =>
FakeScalaTemplateCompiler.compile(
template,
sourceDirectory,
generatedDir,
t,
format,
additionalImports.map("import " + _.replace("%format%", extension)).mkString("\n"))
}
} catch {
case TemplateCompilationError(source, message, line, column) => {
throw reportCompilationError(state, TemplateCompilationException(source, message, line, column - 1))
}
}
(generatedDir ** "*.template.scala").get.map(_.getAbsoluteFile)
}
def compile(source: File, sourceDirectory: File, generatedDirectory: File, resultType: String, formatterType: String, additionalImports: String = "") = {
val (templateName, generatedSource) = generatedFile(source, sourceDirectory, generatedDirectory)
if (generatedSource.needRecompilation) {
templateParser.parser(new CharSequenceReader(Path(source).string)) match {
case templateParser.Success(template, rest) if rest.atEnd => {
val templateWithFakeBody = template.copy(content = Seq(ScalaExp(Seq(Simple("""sys.error("This is a fake template!")""")))))
val generated = generateFinalTemplate(source.getAbsolutePath,
Path(source).byteArray,
templateName.dropRight(1).mkString("."),
templateName.takeRight(1).mkString,
templateWithFakeBody,
resultType,
formatterType,
additionalImports)
Path(generatedSource.file).write(generated.toString)
Some(generatedSource.file)
}
case templateParser.Success(_, rest) => {
throw new TemplateCompilationError(source, "Not parsed?", rest.pos.line, rest.pos.column)
}
case templateParser.NoSuccess(message, input) => {
throw new TemplateCompilationError(source, message, input.pos.line, input.pos.column)
}
}
} else None
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment