Created
June 14, 2012 11:51
-
-
Save reduxdj/2929835 to your computer and use it in GitHub Desktop.
WatcherUtil
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fs = require 'fs' | |
fileUtil = require 'file' | |
path = require 'path' | |
nodeWatch = require 'nodewatch' | |
child_process = require 'child_process' | |
_ = require 'underscore' | |
glob = require 'glob' | |
util = require 'util' | |
exec = require('child_process').exec | |
class Watcher | |
constructor: (@options, @templates) -> | |
@paths = @options?.paths | |
watch: -> | |
@runCompass @options.compass if @options.compass | |
console.log root | |
@watchOutputTree @options.client | |
@log 'running' | |
watchOutputTree: (root) -> | |
console.log 'WatcherUtil.watchTree' | |
console.log "Watching for changes under root : "+root+"\n" | |
nodeWatch.add(root,true) | |
@startListening() | |
startListening: => | |
console.log 'Watcher.startListening' | |
nodeWatch.onChange (file, prev, curr, action) => | |
console.log 'Watcher :: nodeWatch.onChange:' | |
console.log 'action: '+action | |
console.log 'detecting change to:'+file | |
console.log prev.mtime.getTime() | |
console.log curr.mtime.getTime() | |
nodeWatch.clearListeners() | |
@handleFile(file) | |
package: -> | |
console.log 'packaging files' | |
@compileTemplates() | |
runCompass: (config) -> | |
console.log "Starting compass with config file '#{config}'" | |
@spawn 'compass', ['watch', '-c', config] | |
spawn: (command, args, callback) -> | |
child = child_process.spawn command, args | |
child.stdout.on 'data', (data) => | |
@log "stdout from '#{command}': #{data}" | |
child.stderr.on 'data', (data) => | |
console.error "stderr from '#{command}': #{data}" | |
child.on 'exit', (code) => | |
@log "'#{command}' exited with code #{code}" | |
callback?(code) | |
findMatch: (file) -> | |
@log _.detect @paths, (value, pattern) => @globToRegExp(pattern).test file | |
_.detect @paths, (value, pattern) => @globToRegExp(pattern).test file | |
handleFile: (file) => | |
options = @findMatch file | |
pathName = path.dirname(file) | |
@log @options.client | |
@log pathName.indexOf @options.client | |
if pathName.indexOf @options.client isnt -1 | |
pathName = pathName.replace @options.client, '' | |
options.out = options.out + pathName | |
@log 'pathName->'+pathName | |
@processFile file, options | |
globToRegExp: (glob) -> | |
regex = glob.replace /\./g, '\\.' # escape dots | |
regex = regex.replace /\?/g, '.' # replace ? with dots | |
regex = regex.replace /\*/g, '.*' # replace * with .* | |
regex = regex.replace /\.\*\.\*\//g, '(.*\/)*' # replace .*.*/ (which used to be **/) with (.*/)* | |
new RegExp regex | |
processFile: (file, options) -> | |
#success = (=> @packageFiles(file) if options.package) | |
if options.type is 'coffee' | |
@compileCoffee file, options, success | |
_.delay (->@packageFiles), 1000 | |
compileCoffee: (file, options, callback) -> | |
@log "compileCoffee: '#{file}': #{options.out}" | |
@spawn 'coffee', ['-c','-o', file, options.out ], callback | |
compileTemplates: -> | |
@log "Compiling all templates" | |
@processTemplatePattern(pattern, value) for pattern, value of @paths | |
deleteFile: (file, callback) -> | |
fs.unlink file, (err) => | |
return @log "Couldn't delete file '#{file}': #{JSON.stringify err}" if err | |
console.log "Calling callback #{callback}" | |
callback?() | |
processTemplatePattern: (pattern, value) -> | |
return if value.type != 'template' | |
glob pattern, (err, matches) => | |
return console.log "#{err}" if err | |
for match in matches | |
@compileTemplate match, 'create', value.out | |
compileTemplate: (file, out, callback) -> | |
templateName = path.basename file, path.extname(file) | |
@writeTemplateHeader() | |
@log "Compiling template file '#{file}' to '#{out}' and adding it to templates object '#{templateName}' " | |
fs.readFile file, 'utf8', (err, data) => | |
return console.log(err) if err | |
compiled = _.template data | |
@templates[templateName] = compiled | |
@writeTemplate(templateName, compiled, out, callback,data) if out | |
writeTemplateHeader: ()-> | |
fs.createWriteStream("public/js/templates.js", | |
flags: "w" | |
encoding: "utf8" | |
mode: 0666 | |
).write "window.templates || (window.templates = {});\n" | |
fs.createWriteStream("dependencies/templates/templates.js", | |
flags: "w" | |
encoding: "utf8" | |
mode: 0666 | |
).write "window.templates || (window.templates = {});\n" | |
outFile: (outDir, filename, ext) -> | |
console.log ("#{filename}.#{ext}") | |
path.join(outDir, "#{filename}.#{ext}") | |
escapeHTML: (string) -> | |
if string is null or typeof string is "undefined" | |
string = "" | |
else | |
string = String(string) | |
string.replace /[&<>"'\/`]/g, @htmlReplacer | |
templateSettings: -> | |
evaluate: /<%([\s\S]+?)%>/g | |
interpolate: /<%-([\s\S]+?)%>/g | |
autoEscape: /<%=([\s\S]+?)%>/g | |
HTML_CHARS: -> | |
"&": "&" | |
"<": "<" | |
">": ">" | |
"\"": """ | |
"'": "'" | |
"/": "/" | |
"`": "`" | |
_htmlReplacer = (match) -> | |
@HTML_CHARS[match] | |
template: (str, data) -> | |
c = @templateSettings | |
tmpl = "var __p=[],__e=_.escapeHTML,print=function(){__p.push.apply(__p,arguments);};" + "with(obj||{}){__p.push('" + str.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(c.autoEscape, (match, code) -> | |
"',__e(" + code.replace(/\\'/g, "'") + "),'" | |
).replace(c.interpolate, (match, code) -> | |
"'," + code.replace(/\\'/g, "'") + ",'" | |
).replace(c.evaluate or null, (match, code) -> | |
"');" + code.replace(/\\'/g, "'").replace(/[\r\n\t]/g, " ") + "__p.push('" | |
).replace(/\r/g, "\\r").replace(/\n/g, "\\n").replace(/\t/g, "\\t") + "');}return __p.join('');" | |
return tmpl | |
writeTemplate: (templateName, compiled, out, callback,data) -> | |
asString = compiled.toString().replace('function anonymous', "window.templates || (window.templates = {});\nwindow.templates['#{templateName}'] = function") + ';' | |
if templateName is 'index' | |
fileUtil.mkdirs out, 0755, => | |
fs.writeFile @outFile(out, templateName, 'js'), asString, 'utf8', callback | |
return | |
fs.createWriteStream("public/js/templates.js", | |
flags: "a" | |
encoding: "utf8" | |
mode: 0666 | |
).write "window.templates['#{templateName}'] = function(obj){"+@template(data)+"};\n" | |
fs.createWriteStream("dependencies/templates/templates.js", | |
flags: "a" | |
encoding: "utf8" | |
mode: 0666 | |
).write "window.templates['#{templateName}'] = function(obj){"+@template(data)+"};\n" | |
onDoneAssets: (msg) => | |
@log 'File Copied' | |
packageFiles: () -> | |
@log 'Packaging files using jammit->'[email protected] | |
@spawn 'jammit', ['-c', @options.package, '-o', @options.packageOut] | |
fs.copy = (src, dst, cb) -> | |
copy = (err) -> | |
is_ = undefined | |
os = undefined | |
fs.stat src, (err) -> | |
return cb(err) if err | |
is_ = fs.createReadStream(src) | |
os = fs.createWriteStream(dst) | |
util.pump is_, os, cb | |
fs.stat dst, copy | |
@log 'public/js/assets.js' + " to " + @options.assetsOut | |
@startListening() | |
#fs.copy 'public/js/assets.js', @options.assetsOut+'assets.js', @onDoneAssets | |
log: (message) -> | |
console.log message if @options?.verbose | |
exports?.watcher = Watcher |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment