123 lines
4.5 KiB
JavaScript
123 lines
4.5 KiB
JavaScript
|
var fs = require('fs'),
|
|||
|
path = require('path');
|
|||
|
|
|||
|
/**
|
|||
|
* merge two objects by extending target object with source object
|
|||
|
* @param target object to merge
|
|||
|
* @param source object to merge
|
|||
|
* @param {Boolean} [modify] whether to modify the target
|
|||
|
* @returns {Object} extended object
|
|||
|
*/
|
|||
|
function extend(target, source, modify) {
|
|||
|
var result = target ? modify ? target : extend({}, target, true) : {};
|
|||
|
if (!source) return result;
|
|||
|
for (var key in source) {
|
|||
|
if (source.hasOwnProperty(key) && source[key] !== undefined) {
|
|||
|
result[key] = source[key];
|
|||
|
}
|
|||
|
}
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* determine if a string is contained within an array or matches a regular expression
|
|||
|
* @param {String} str string to match
|
|||
|
* @param {Array|Regex} match array or regular expression to match against
|
|||
|
* @returns {Boolean} whether there is a match
|
|||
|
*/
|
|||
|
function matches(str, match) {
|
|||
|
if (Array.isArray(match)) return match.indexOf(str) > -1;
|
|||
|
return match.test(str);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* read files and call a function with the contents of each file
|
|||
|
* @param {String} dir path of dir containing the files to be read
|
|||
|
* @param {String} encoding file encoding (default is 'utf8')
|
|||
|
* @param {Object} options options hash for encoding, recursive, and match/exclude
|
|||
|
* @param {Function(error, string)} callback callback for each files content
|
|||
|
* @param {Function(error)} complete fn to call when finished
|
|||
|
*/
|
|||
|
function readFiles(dir, options, callback, complete) {
|
|||
|
if (typeof options === 'function') {
|
|||
|
complete = callback;
|
|||
|
callback = options;
|
|||
|
options = {};
|
|||
|
}
|
|||
|
if (typeof options === 'string') options = {
|
|||
|
encoding: options
|
|||
|
};
|
|||
|
options = extend({
|
|||
|
recursive: true,
|
|||
|
encoding: 'utf8',
|
|||
|
doneOnErr: true
|
|||
|
}, options);
|
|||
|
var files = [];
|
|||
|
|
|||
|
var done = function(err) {
|
|||
|
if (typeof complete === 'function') {
|
|||
|
if (err) return complete(err);
|
|||
|
complete(null, files);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
fs.readdir(dir, function(err, list) {
|
|||
|
if (err) {
|
|||
|
if (options.doneOnErr === true) {
|
|||
|
if (err.code === 'EACCES') return done();
|
|||
|
return done(err);
|
|||
|
}
|
|||
|
}
|
|||
|
var i = 0;
|
|||
|
|
|||
|
if (options.reverse === true ||
|
|||
|
(typeof options.sort == 'string' &&
|
|||
|
(/reverse|desc/i).test(options.sort))) {
|
|||
|
list = list.reverse();
|
|||
|
} else if (options.sort !== false) list = list.sort();
|
|||
|
|
|||
|
(function next() {
|
|||
|
var filename = list[i++];
|
|||
|
if (!filename) return done(null, files);
|
|||
|
var file = path.join(dir, filename);
|
|||
|
fs.stat(file, function(err, stat) {
|
|||
|
if (err && options.doneOnErr === true) return done(err);
|
|||
|
if (stat && stat.isDirectory()) {
|
|||
|
if (options.recursive) {
|
|||
|
if (options.matchDir && !matches(filename, options.matchDir)) return next();
|
|||
|
if (options.excludeDir && matches(filename, options.excludeDir)) return next();
|
|||
|
readFiles(file, options, callback, function(err, sfiles) {
|
|||
|
if (err && options.doneOnErr === true) return done(err);
|
|||
|
files = files.concat(sfiles);
|
|||
|
next();
|
|||
|
});
|
|||
|
} else next();
|
|||
|
} else if (stat && stat.isFile()) {
|
|||
|
if (options.match && !matches(filename, options.match)) return next();
|
|||
|
if (options.exclude && matches(filename, options.exclude)) return next();
|
|||
|
if (options.filter && !options.filter(filename)) return next();
|
|||
|
if (options.shortName) files.push(filename);
|
|||
|
else files.push(file);
|
|||
|
fs.readFile(file, options.encoding, function(err, data) {
|
|||
|
if (err) {
|
|||
|
if (err.code === 'EACCES') return next();
|
|||
|
if (options.doneOnErr === true) {
|
|||
|
return done(err);
|
|||
|
}
|
|||
|
}
|
|||
|
if (callback.length > 3)
|
|||
|
if (options.shortName) callback(null, data, filename, next);
|
|||
|
else callback(null, data, file, next);
|
|||
|
else callback(null, data, next);
|
|||
|
});
|
|||
|
}
|
|||
|
else {
|
|||
|
next();
|
|||
|
}
|
|||
|
});
|
|||
|
})();
|
|||
|
|
|||
|
});
|
|||
|
}
|
|||
|
module.exports = readFiles;
|