80 lines
1.9 KiB
JavaScript
80 lines
1.9 KiB
JavaScript
|
(function () {
|
||
|
"use strict"
|
||
|
|
||
|
// Array.prototype.forEachAsync(next, item, i, collection)
|
||
|
require('futures/forEachAsync');
|
||
|
|
||
|
var fs = require('fs'),
|
||
|
EventEmitter = require('events').EventEmitter;
|
||
|
|
||
|
// 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) {
|
||
|
emitter.emit('error', curpath, err);
|
||
|
}
|
||
|
// XXX bug was here. next() was omitted
|
||
|
if (!files || 0 == files.length) {
|
||
|
return next();
|
||
|
}
|
||
|
var stats = [];
|
||
|
emitter.emit('names', curpath, files, stats);
|
||
|
files.forEachAsync(function (cont, file) {
|
||
|
emitter.emit('name', curpath, file);
|
||
|
fs.lstat(curpath + '/' + file, function (err, stat) {
|
||
|
if (err) {
|
||
|
emitter.emit('error', curpath, err);
|
||
|
}
|
||
|
if (stat) {
|
||
|
stat.name = file;
|
||
|
stats.push(stat);
|
||
|
emitter.emit('stat', curpath, file, stat);
|
||
|
}
|
||
|
cont();
|
||
|
});
|
||
|
}).then(function () {
|
||
|
var dirs = []
|
||
|
emitter.emit('stats', curpath, files, stats);
|
||
|
stats.forEach(function (stat) {
|
||
|
if (stat.isDirectory()) {
|
||
|
dirs.push(stat.name);
|
||
|
}
|
||
|
});
|
||
|
dirs.forEach(fullPath);
|
||
|
queue.push(q = dirs);
|
||
|
next();
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
|
||
|
function next() {
|
||
|
if (q.length) {
|
||
|
curpath = q.pop();
|
||
|
return walk();
|
||
|
}
|
||
|
if (queue.length -= 1) {
|
||
|
q = queue[queue.length-1];
|
||
|
return next();
|
||
|
}
|
||
|
emitter.emit('end');
|
||
|
}
|
||
|
|
||
|
function fullPath(v,i,o) {
|
||
|
o[i]= [curpath, '/', v].join('');
|
||
|
}
|
||
|
|
||
|
curpath = pathname;
|
||
|
walk();
|
||
|
|
||
|
return emitter;
|
||
|
}
|
||
|
|
||
|
module.exports = create;
|
||
|
}());
|