UNPKG

2.61 kBJavaScriptView Raw
1(function () {
2 "use strict"
3
4 // Array.prototype.forEachAsync(next, item, i, collection)
5 require('futures/forEachAsync');
6
7 function noop() {}
8
9 var fs = require('fs'),
10 EventEmitter = require('events').EventEmitter,
11 TypeEmitter = require('./node-type-emitter');
12
13 // 2010-11-25 jorge@jorgechamorro.com
14 function create(pathname, cb) {
15 var emitter = new EventEmitter(),
16 q = [],
17 queue = [q],
18 curpath;
19
20 function walk() {
21 fs.readdir(curpath, function(err, files) {
22 if (err) {
23 emitter.emit('directoryError', curpath, { error: err }, noop);
24 //emitter.emit('error', curpath, { error: err });
25 }
26 // XXX bug was here. next() was omitted
27 if (!files || 0 == files.length) {
28 return next();
29 }
30
31 var fnodeGroups = TypeEmitter.createNodeGroups();
32
33 // TODO could allow user to selectively stat
34 // and don't stat if there are no stat listeners
35 emitter.emit('names', curpath, files, noop);
36 files.forEachAsync(function (cont, file) {
37 emitter.emit('name', curpath, file, noop);
38 fs.lstat(curpath + '/' + file, function (err, stat) {
39 stat = stat || {};
40 stat.name = file;
41 if (err) {
42 stat.error = err;
43 //emitter.emit('error', curpath, stat);
44 emitter.emit('nodeError', curpath, stat, noop);
45 fnodeGroups.errors.push(stat);
46 cont();
47 } else {
48 TypeEmitter.sortFnodesByType(stat, fnodeGroups);
49 TypeEmitter.emitNodeType(emitter, curpath, stat, cont);
50 }
51 });
52 }).then(function () {
53 if (fnodeGroups.errors.length) {
54 emitter.emit('errors', curpath, fnodeGroups.errors, noop);
55 }
56 TypeEmitter.emitNodeTypeGroups(emitter, curpath, fnodeGroups, function () {
57 var dirs = [];
58 fnodeGroups.directories.forEach(function (stat) {
59 dirs.push(stat.name);
60 });
61 dirs.forEach(fullPath);
62 queue.push(q = dirs);
63 next();
64 });
65 });
66 });
67 }
68
69 function next() {
70 if (q.length) {
71 curpath = q.pop();
72 return walk();
73 }
74 if (queue.length -= 1) {
75 q = queue[queue.length-1];
76 return next();
77 }
78 emitter.emit('end');
79 }
80
81 function fullPath(v,i,o) {
82 o[i]= [curpath, '/', v].join('');
83 }
84
85 curpath = pathname;
86 walk();
87
88 return emitter;
89 }
90
91 module.exports = create;
92}());