paths.js
4.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
var fs = require('fs'),
path = require('path');
/**
* find all files or subdirs (recursive) and pass to callback fn
*
* @param {string} dir directory in which to recurse files or subdirs
* @param {string} type type of dir entry to recurse ('file', 'dir', or 'all', defaults to 'file')
* @param {function(error, <Array.<string>)} callback fn to call when done
* @example
* dir.files(__dirname, function(err, files) {
* if (err) throw err;
* console.log('files:', files);
* });
*/
exports.files = function files(dir, type, callback, /* used internally */ ignoreType) {
var pending,
results = {
files: [],
dirs: []
};
var done = function() {
if (ignoreType || type === 'all') {
callback(null, results);
} else {
callback(null, results[type + 's']);
}
};
var getStatHandler = function(statPath, lstatCalled) {
return function(err, stat) {
if (err) {
if (!lstatCalled) {
return fs.lstat(statPath, getStatHandler(statPath, true));
}
return callback(err);
}
if (stat && stat.isDirectory() && stat.mode !== 17115) {
if (type !== 'file') {
results.dirs.push(statPath);
}
files(statPath, type, function(err, res) {
if (err) return callback(err);
if (type === 'all') {
results.files = results.files.concat(res.files);
results.dirs = results.dirs.concat(res.dirs);
} else if (type === 'file') {
results.files = results.files.concat(res.files);
} else {
results.dirs = results.dirs.concat(res.dirs);
}
if (!--pending) done();
}, true);
} else {
if (type !== 'dir') {
results.files.push(statPath);
}
// should be the last statement in statHandler
if (!--pending) done();
}
};
};
if (typeof type !== 'string') {
ignoreType = callback;
callback = type;
type = 'file';
}
fs.stat(dir, function(err, stat) {
if (err) return callback(err);
if(stat && stat.mode === 17115) return done();
fs.readdir(dir, function(err, list) {
if (err) return callback(err);
pending = list.length;
if (!pending) return done();
for (var file, i = 0, l = list.length; i < l; i++) {
file = path.join(dir, list[i]);
fs.stat(file, getStatHandler(file));
}
});
});
};
/**
* find all files and subdirs in a directory (recursive) and pass them to callback fn
*
* @param {string} dir directory in which to recurse files or subdirs
* @param {boolean} combine whether to combine both subdirs and filepaths into one array (default false)
* @param {function(error, Object.<<Array.<string>, Array.<string>>)} callback fn to call when done
* @example
* dir.paths(__dirname, function (err, paths) {
* if (err) throw err;
* console.log('files:', paths.files);
* console.log('subdirs:', paths.dirs);
* });
* dir.paths(__dirname, true, function (err, paths) {
* if (err) throw err;
* console.log('paths:', paths);
* });
*/
exports.paths = function paths(dir, combine, callback) {
var type;
if (typeof combine === 'function') {
callback = combine;
combine = false;
}
exports.files(dir, 'all', function(err, results) {
if (err) return callback(err);
if (combine) {
callback(null, results.files.concat(results.dirs));
} else {
callback(null, results);
}
});
};
/**
* find all subdirs (recursive) of a directory and pass them to callback fn
*
* @param {string} dir directory in which to find subdirs
* @param {string} type type of dir entry to recurse ('file' or 'dir', defaults to 'file')
* @param {function(error, <Array.<string>)} callback fn to call when done
* @example
* dir.subdirs(__dirname, function (err, paths) {
* if (err) throw err;
* console.log('files:', paths.files);
* console.log('subdirs:', paths.dirs);
* });
*/
exports.subdirs = function subdirs(dir, callback) {
exports.files(dir, 'dir', function(err, subdirs) {
if (err) return callback(err);
callback(null, subdirs);
});
};