-
Notifications
You must be signed in to change notification settings - Fork 0
/
traverser.js
executable file
·99 lines (89 loc) · 2.73 KB
/
traverser.js
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
#!/usr/bin/env node
'use strict';
var fs = require('fs');
var path = require('path');
// function traverse(rootPath)
function traverse(list, fileList) {
return new Promise(
function (resolve) {
// a params overload trick
if (typeof list === 'string') {
list = [ list ];
}
fileList = fileList || [];
// dequeue a item
var current = list.shift();
if (current) {
resolve(task(current, list, fileList));
} else {
// no more path in target list, resolve final result
resolve(fileList);
}
}
)
}
// convert promise style api to callback style
function traverse_callback(filePath, returnCallback) {
traverse([ filePath ]).then(returnCallback.bind(null, null), returnCallback);
}
function task (current, list, fileList) {
return check(current)
.then(function (type){
if ('dir' === type){
// if current path is subdir, list this subdir
return list_subdir(current)
.then(function(paths){
list = list.concat(paths);
return traverse(list, fileList);
});
} else {
// add file path to result list.
fileList.push(current);
return traverse(list, fileList);
}
});
}
// wrap a constructed promise
function check(filePath) {
return new Promise(
function(resolve, reject) {
fs.lstat(filePath, function (err, stats) {
if (err) reject(err);
// return file type
else resolve(stats.isDirectory() ? 'dir' : 'file');
});
}
)
}
// wrap a thenable
function list_subdir(dirPath) {
return Promise.resolve({
then(resolve, reject){
fs.readdir(dirPath, function (err, files){
if (err) {
reject(err);
} else {
// list and resolve all file path in sub dir.
var paths = files.map(function (item) {
return path.resolve(dirPath, item);
});
// return
resolve(paths);
}
});
}
});
}
/* call traverse */
/* promise api */
traverse(process.argv[2])
.then(function(res) {
console.log(res.length + '\n' + JSON.stringify(res));
})
.catch(function(err) {
console.error('Catch Error:', err);
});
/* callback api */
// traverse_callback(process.argv[2], function(err, res){
// console.log(res.length + '\n' + JSON.stringify(res));
// });