-
-
Save AdamPflug/2830614 to your computer and use it in GitHub Desktop.
desc('Continously monitors the javascript and less files for the project, and rebuilds them as necessary'); | |
task('watch', ['build'], function () { | |
// Recursively watch files with a callback | |
var fs = require('fs'); | |
var files = []; | |
var findFilesAndWatch = function (path) { | |
fs.stat(path, function (err, stats) { | |
if (err) { | |
return false; | |
} | |
if (stats.isFile()) { | |
files.push(path); | |
fs.watchFile(path, changeCallbackFactory(path)); | |
} | |
else if (stats.isDirectory()) { | |
fs.readdir(path, function (err, dirListing) { | |
if (err) { | |
return log.fatal(err); | |
} | |
for (var f in dirListing) { | |
findFilesAndWatch(path + '/' + dirListing[f]); | |
} | |
}); | |
} | |
}); | |
}; | |
var changeCallbackFactory = function (file) { | |
return function (cur, prev) { | |
if (cur.mtime > prev.mtime) { | |
stopWatch(); | |
var fileTask = jake.Task[file]; | |
if (fileTask) { | |
fileTask.modTime = cur.mtime; | |
} | |
jake.Task['build'].reenable(true); | |
jake.Task['build'].invoke(); | |
startWatch(); | |
} | |
}; | |
}; | |
var startWatch = function () { | |
for (var i = 0; i < files.length; i++) { | |
fs.watchFile(files[i], changeCallbackFactory(files[i])); | |
} | |
}; | |
var stopWatch = function () { | |
for (var i = 0; i < files.length; i++) { | |
fs.unwatchFile(files[i]); | |
} | |
}; | |
findFilesAndWatch('themes'); | |
}, {async: true}); |
The more I think about it, the more it makes sense to do it so you can set up file tasks as dependencies for the watch task. Then I could have it just walk the dependency tree so any files those tasks depend on get watched automatically.
The one issue I've thought of is that if any of those tasks fail (e.g. a LESS/RequireJS compilation task fails because of a syntax error), then the process exits because of the uncaught exception rather than just printing the error and continuing to run. Should I just modify Program.handleErr
so it emits an event that you can subscribe to, and if a listener returns true then cancel the exit process?
Once I get a solution to that problem figured out I think I'll merge everything into a nice generic solution.
If you're talking about child processes, have a look at the new createExec stuff. It pretty much does exactly what you're describing. :)
Gotcha. The obvious path here is to make Tasks even more evented. Right now they fire "complete" when done, and errors are handled by a generic uncaughtException handler. I can add a "error" event, which can be handled by a specific handler or fall back to the generic one if nothing is set. Would that fix you up?
All right, this is in master. Just do someTask.addListener('error', function (e) {}); and call via invoke
. If you don't set an explicit listener, it's handled the way it's always been. Let me know if this works for you.
Pretty much the same as this issue: jakejs/jake#122
There is code in the Geddy framework that does this and it well tested. Could you take a look at that and merge this work? I would love to have this in Jake core. :)