-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcompiler.coffee
84 lines (79 loc) · 2.74 KB
/
compiler.coffee
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
fs = require "fs-extra"
path = require "path"
acorn = require "acorn"
coffee = require "coffee-script"
src = path.resolve(__dirname, "./src")
lib = path.resolve(__dirname, "./lib")
lastModified = {}
replaceExpression = (js, expr, cb) ->
indexOffset = 0
while (indexOffset = js.indexOf(expr+"(",indexOffset)) > -1
node = acorn.parseExpressionAt(js, indexOffset)
if node.type == "SequenceExpression"
node = node.expressions[0]
try
js = cb(js, node)
catch e
console.error e
indexOffset++
return js
changing = {}
compile = (file) ->
unless changing[file]
folder = path.dirname(file).replace(src,lib)
try
fs.mkdirSync(folder)
outFile = path.resolve(folder, path.basename(file,".coffee"))+".js"
changing[file] = true
setTimeout (-> changing[file] = false), 1000
fs.readFile file, 'utf8'
.then (sourceCoffee) ->
sourceJS = coffee.compile sourceCoffee,
filename: file,
bare: true,
generatedFile: outFile
tests = 0
sourceJS = replaceExpression sourceJS, "test", (js, node) ->
tests++
return js.substr(0,node.start) + js.substr(node.end)
fs.writeFile outFile, sourceJS
.then ->
changing[file] = false
console.log "compiled #{file} to #{outFile} - #{tests} tests removed"
if process.argv[2] == "--watch"
chokidar = require "chokidar"
chokidar.watch src
.on "add", compile
.on "change", compile
else
processDir = (src, lib) ->
Promise.all [fs.readdir(src), fs.readdir(lib)]
.then ([srcEntries, libEntries]) ->
workers = []
srcEntries.forEach (srcEntry) ->
srcFilename = path.resolve(src,srcEntry)
promise = fs.lstat(srcFilename)
.then (stats) ->
if stats.isDirectory()
libFilename = path.resolve(lib,srcEntry)
fs.ensureDir(libFilename)
.then -> processDir(srcFilename,libFilename)
else if stats.isFile() and (libEntries.indexOf(srcEntry.replace(".coffee",".js")) < 0 or not lastModified[srcFilename] or lastModified[srcFilename] != stats.mtime.getTime())
compile(srcFilename)
.then ->
lastModified[srcFilename] = stats.mtime.getTime()
workers.push promise
for libEntry in libEntries
if srcEntries.indexOf(libEntry.replace(".js",".coffee")) < 0
workers.push fs.remove(path.resolve(lib, libEntry))
Promise.all workers
start = Date.now()
fs.readJson("./_lastModified")
.then (obj) ->
lastModified = obj
.catch (e) -> return null
.then -> processDir(src, lib)
.then -> fs.writeJson("./_lastModified", lastModified)
.then ->
console.log "compilation took: "+(Date.now()-start)+"ms"
.catch (e) -> console.log e