-
Notifications
You must be signed in to change notification settings - Fork 9
/
fun
executable file
·120 lines (104 loc) · 3.04 KB
/
fun
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
110
111
112
113
114
115
116
117
118
119
120
#!/usr/bin/env node
var fs = require('fs'),
util = require('util'),
http = require('http'),
path = require('path'),
optimist = require('optimist'),
map = require('std/map'),
pckg = require('../package'),
exec = require('child_process').exec,
curry = require('std/curry'),
socketIo = require('socket.io'),
colors = require('colors')
/* Commandline options
*********************/
var commandline = optimist.usage('Usage: fun [compile] path/to/app.fun [--port=8080 --normalize.css=false --minify=true]'),
argv = commandline.argv,
line = argv._,
compile = line[0] == 'compile',
filenameRaw = (compile ? line[1] : line[0]),
filename = filenameRaw && filenameRaw[0] == '/' ? filenameRaw : path.join(process.cwd(), filenameRaw)
var opts = {
'minify': argv['minify'] == 'true',
'normalize.css': argv['normalize.css'] != 'false'
}
if (compile) {
loadCompiler().compileFile(filename, opts, function(err, htmlFile) {
if (err) {
console.log(err)
return process.exit(-1)
}
util.puts(htmlFile)
return process.exit(0)
})
} else if (argv.v || argv.version) {
console.log("fun", pckg.version)
return process.exit(0)
} else if (!filename) {
console.error(commandline.help())
return process.exit(-1)
} else {
// dev environment
var port = argv.port || 8080
try {
var stat = fs.statSync(filename)
} catch(e) {
console.error('Error:', e.message ? e.message : e.toString())
return process.exit(-1)
}
if (!stat.isFile()) {
console.error('Error:', filename, 'is not a file.')
return process.exit(-1)
}
var ideServer = http.createServer(function(req, res) {
if (req.url == '/favicon.ico') {
return send404(res)
} else {
fs.readFile(path.join(__dirname, '../src/dev-client.html'), curry(respond, res))
}
})
var ideServerIo = socketIo.listen(ideServer)
ideServerIo.set('log level', 0)
ideServer.listen(port)
var sockets = []
ideServerIo.sockets.on('connection', function(socket) {
console.log("Dev client connected")
sockets.push(socket)
loadCompiler().compileFile(filename, opts, function broadcast(err, appHtml) {
socket.emit('change', { error:err, html:appHtml })
})
})
fs.watch(filename, { persisten:true }, function(event, changedFilename) {
loadCompiler().compileFile(filename, opts, function broadcast(err, appHtml) {
ideServerIo.sockets.emit('change', { error:err, html:appHtml })
})
})
console.log('Fun!'.magenta, 'Serving', filenameRaw.green, 'on', ('localhost:'+port).cyan, 'with these options:\n', opts)
}
function send404(res) {
res.writeHead(404)
res.end()
}
function loadCompiler() {
for (var key in require.cache) {
delete require.cache[key]
}
return require('../src/compiler')
}
function respond(res, e, content) {
if (e) {
res.writeHead(500)
res.end(errorHtmlResponse(e))
} else {
res.writeHead(200)
res.end(content.toString())
}
}
function errorHtmlResponse(e) {
return ['<!doctype html>','<body>',
'<button ontouchstart="location.reload();" onclick="location.reload()">Reload</button>',
'<pre>',
e.stack ? e.stack : e.message ? e.message : e.toString(),
'</pre>'
].join('\n')
}