This repository has been archived by the owner on Feb 9, 2019. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 161
/
DustTasks.scala
109 lines (83 loc) · 3.78 KB
/
DustTasks.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package com.typesafe.plugin
import java.io.File
import java.io.FileInputStream
import java.io.InputStreamReader
import org.apache.commons.io.FilenameUtils
import org.mozilla.javascript.tools.shell.Global
import org.mozilla.javascript.Context
import org.mozilla.javascript.JavaScriptException
import org.mozilla.javascript.Scriptable
import org.mozilla.javascript.ScriptableObject
import sbt._
import PlayProject._
trait DustTasks extends DustKeys {
def compile(name: String, source: String): Either[(String, Int, Int), String] = {
import org.mozilla.javascript._
import org.mozilla.javascript.tools.shell._
import com.typesafe.plugin.DustKeys;
import scala.collection.JavaConversions._
import java.io._
val ctx = Context.enter
val global = new Global; global.init(ctx)
val scope = ctx.initStandardObjects(global)
ctx.evaluateReader(
scope,
new InputStreamReader(this.getClass.getClassLoader.getResource("dust-full-0.6.0.js").openConnection().getInputStream()),
"dust.js",
1, null)
ScriptableObject.putProperty(scope, "rawSource", source)
ScriptableObject.putProperty(scope, "name", name)
try {
Right(ctx.evaluateString(scope, "(dust.compile(rawSource, name))", "JDustCompiler", 0, null).toString)
} catch {
case e: JavaScriptException => {
val jsError = e.getValue.asInstanceOf[Scriptable]
val message = ScriptableObject.getProperty(jsError, "message").toString
// dust.js has weird error reporting where the line/column are part of the message, so we have to use a Regex to find them
val DustCompileError = ".* At line : (\\d+), column : (\\d+)".r
message match {
case DustCompileError(line, column) => Left(message, line.toInt, column.toInt)
case _ => Left(message, 0, 0) // Some other weird error, we have no line/column info now.
}
}
}
}
protected def templateName(sourceFile: String, assetsDir: String): String = {
val sourceFileWithForwardSlashes = FilenameUtils.separatorsToUnix(sourceFile)
val assetsDirWithForwardSlashes = FilenameUtils.separatorsToUnix(assetsDir)
FilenameUtils.removeExtension(
sourceFileWithForwardSlashes.replace(assetsDirWithForwardSlashes + "/", "")
)
}
import Keys._
lazy val DustCompiler = (sourceDirectory in Compile, resourceManaged in Compile, cacheDirectory, dustFileRegexFrom, dustFileRegexTo, dustAssetsDir, dustAssetsGlob) map {
(src, resources, cache, fileReplaceRegexp, fileReplaceWith, assetsDir, files) =>
val cacheFile = cache / "dust"
def naming(name: String) = name.replaceAll(fileReplaceRegexp, fileReplaceWith)
val currentInfos = files.get.map(f => f -> FileInfo.lastModified(f)).toMap
val (previousRelation, previousInfo) = Sync.readInfo(cacheFile)(FileInfo.lastModified.format)
val previousGeneratedFiles = previousRelation._2s
if (previousInfo != currentInfos) {
previousGeneratedFiles.foreach(IO.delete)
val generated = (files x relativeTo(assetsDir)).flatMap {
case (sourceFile, name) => {
val msg = compile(templateName(sourceFile.getPath, assetsDir.getPath), IO.read(sourceFile)).left.map {
case (msg, line, column) => throw AssetCompilationException(Some(sourceFile),
msg,
line,
column)
}.right.get
val out = new File(resources, "public/" + naming(name))
IO.write(out, msg)
Seq(sourceFile -> out)
}
}
Sync.writeInfo(cacheFile,
Relation.empty[java.io.File, java.io.File] ++ generated,
currentInfos)(FileInfo.lastModified.format)
generated.map(_._2).distinct.toList
} else {
previousGeneratedFiles.toSeq
}
}
}