fs-walk.js/lib/walk.js

93 lines
2.5 KiB
JavaScript
Raw Normal View History

2011-02-04 06:31:25 +00:00
(function () {
"use strict"
2011-02-04 06:31:25 +00:00
// Array.prototype.forEachAsync(next, item, i, collection)
require('futures/forEachAsync');
2011-02-04 06:57:11 +00:00
function noop() {}
2011-02-04 06:31:25 +00:00
var fs = require('fs'),
EventEmitter = require('events').EventEmitter,
TypeEmitter = require('./node-type-emitter');
// 2010-11-25 jorge@jorgechamorro.com
function create(pathname, cb) {
var emitter = new EventEmitter(),
q = [],
queue = [q],
curpath;
function walk() {
fs.readdir(curpath, function(err, files) {
if (err) {
2011-02-04 06:57:11 +00:00
emitter.emit('directoryError', curpath, { error: err }, noop);
//emitter.emit('error', curpath, { error: err });
}
2011-02-04 06:31:25 +00:00
// XXX bug was here. next() was omitted
if (!files || 0 == files.length) {
return next();
}
2011-02-04 06:57:11 +00:00
var fnodeGroups = TypeEmitter.createNodeGroups();
2011-02-04 06:31:25 +00:00
// TODO could allow user to selectively stat
// and don't stat if there are no stat listeners
2011-02-04 07:14:19 +00:00
emitter.emit('names', curpath, files, noop);
2011-02-04 06:31:25 +00:00
files.forEachAsync(function (cont, file) {
2011-02-04 07:14:19 +00:00
emitter.emit('name', curpath, file, noop);
2011-02-04 06:31:25 +00:00
fs.lstat(curpath + '/' + file, function (err, stat) {
2011-02-04 06:57:11 +00:00
stat = stat || {};
stat.name = file;
2011-02-04 06:31:25 +00:00
if (err) {
2011-02-04 06:57:11 +00:00
stat.error = err;
//emitter.emit('error', curpath, stat);
emitter.emit('nodeError', curpath, stat, noop);
fnodeGroups.errors.push(stat);
2011-02-04 06:31:25 +00:00
cont();
2011-02-04 06:57:11 +00:00
} else {
TypeEmitter.sortFnodesByType(stat, fnodeGroups);
TypeEmitter.emitNodeType(emitter, curpath, stat, cont);
2011-02-04 06:31:25 +00:00
}
});
}).then(function () {
2011-02-04 06:57:11 +00:00
if (fnodeGroups.errors.length) {
emitter.emit('errors', curpath, fnodeGroups.errors);
}
2011-02-04 06:31:25 +00:00
TypeEmitter.emitNodeTypeGroups(emitter, curpath, fnodeGroups, function () {
2011-02-04 06:57:11 +00:00
var dirs = [];
2011-02-04 06:31:25 +00:00
fnodeGroups.directories.forEach(function (stat) {
dirs.push(stat.name);
2010-11-21 05:02:53 +00:00
});
2011-02-04 06:31:25 +00:00
dirs.forEach(fullPath);
queue.push(q = dirs);
next();
2010-11-21 05:02:53 +00:00
});
});
2010-11-21 05:02:53 +00:00
});
}
2011-02-04 06:31:25 +00:00
function next() {
if (q.length) {
curpath = q.pop();
return walk();
}
if (queue.length -= 1) {
q = queue[queue.length-1];
return next();
}
emitter.emit('end');
2011-02-04 06:31:25 +00:00
}
function fullPath(v,i,o) {
o[i]= [curpath, '/', v].join('');
}
curpath = pathname;
walk();
return emitter;
2010-11-21 05:02:53 +00:00
}
2011-02-04 06:31:25 +00:00
module.exports = create;
2010-11-21 05:02:53 +00:00
}());