Skip to content

Instantly share code, notes, and snippets.

@andrewluetgers
Created October 12, 2012 04:44
Show Gist options
  • Save andrewluetgers/3877347 to your computer and use it in GitHub Desktop.
Save andrewluetgers/3877347 to your computer and use it in GitHub Desktop.
update things in node when files change
var request = require('request');
var fs = require('fs');
// file watches seem fuxed so I have some hacky workarounds in here
/**
* @param url (string) url to get like: "http://www.google.com"
* @param path (string) path to file like: "/tmp/test/myfile.js"
* @param callback(err, stuff)
*/
exports.urlToFile = function(url, path, callback) {
request(url, function(err, response, body) {
if (!err && response.statusCode === 200) {
fs.writeFile(path, body, callback);
} else {
callback(err || "status code: " + response.statusCode, url);
}
});
};
var watching = {};
/**
* @param filePath
* @param callback
* @return fsWatcher with watch.close() method
* the fs.watch is buggy so this sorta fixes it
* can be called multiple times without quing up multiple watcher
* watchers can all be removed with unwatchAll
*/
exports.watch = function(filePath, callback) {
var watch = watching[filePath];
if (watch) {
exports.unwatch(filePath);
}
function changeHandler(err, data) {
console.log("ioUtils REWATCH ----- " + data + " ------ " + filePath);
fs.exists(filePath, function (exists) {
if (exists) {
watching[filePath].close();
setTimeout(function() {
fs.exists(filePath, function (exists) {
if (exists) {
watching[filePath] = fs.watch(filePath, changeHandler);
}
});
}, 300);
}
});
callback(err, data);
}
console.log("ioUtils.watch", filePath);
return watching[filePath] = fs.watch(filePath, changeHandler);
};
exports.unwatch = function(filePath, cb) {
console.log("ioUtils.unwatch", filePath);
var watch = watching[filePath];
if (watch) {
watch.close();
delete watching[filePath];
}
fs.unwatchFile(filePath); // this is probably unnecessary but wtf its a no-op if there is no watch
};
exports.unwatchAll = function() {
$each(watching, function(watch, filePath) {
exports.unwatch(filePath);
});
};
var fs = require('fs'),
io = require("../utils/ioUtils.js"),
viewPath = process.cwd() + "/views/",
viewExtension = "js",
validExtensionRe = new RegExp("^.+\\."+viewExtension+"$"),
viewsList = [];
// testing
// aboutPage examplesPage splashPage supportPage;
// todo traverse folder to get this list
var views = ("headInclude headerInclude indexPage footerInclude bottomInclude "+
"loginPage signupPage accountPage docsPage").split(" ");
var updateView = function(filePath) {
fs.exists(filePath, function(exists) {
if (exists) {
delete require.cache[filePath];
require(filePath);
}
});
};
var updateViews = function(viewPath, cb) {
fs.readdir(viewPath, function(err, files) {
console.log("fs.readdir cb", arguments);
var newViewsList = $filter(files, function(val) {
return val.match(validExtensionRe);
});
var added = $filter(newViewsList, function(val) {
return viewsList.indexOf(val) === -1;
});
var deleted = $filter(viewsList, function(val) {
return newViewsList.indexOf(val) === -1;
});
viewsList = newViewsList;
console.log("updateViews callback", arguments);
console.log("full list", newViewsList, "added", added, "deleted", deleted);
// update the watches for all files in this folder
// todo: support nested folders
$parallel({
unwatchDeleted: function(outerPush) {
$parallel(deleted, function(filePush, fileName) {
io.unwatch(viewPath + fileName);
filePush(null, viewPath + fileName);
}, outerPush);
},
watchAdded: function(outerPush) {
$parallel(added, function(filePush, fileName) {
io.watch(viewPath + fileName, function(err, data) {
console.log("update view");
updateView(viewPath + fileName);
});
updateView(viewPath + fileName);
filePush(null, viewPath + fileName);
}, outerPush);
}
}, cb);
});
};
io.watch(viewPath, function() {
console.log("watch dir");
updateViews(viewPath, function() {
console.log("updateViews callback", arguments);
});
});
updateViews(viewPath, function() {
console.log("updateViews callback", arguments);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment