Here you can find the source of fs_find(dir, options, prefix, level, finish)
var FS = require("fs"); var PATH = require("path"); function defaults(args, defs) { var ret = {}; for (var i in defs) ret[i] = args.hasOwnProperty(i) ? args[i] : defs[i]; return ret;//from w w w.j a v a 2 s.co m }; function shallow_copy(src, dest) { if (dest == null) dest = {}; for (var i in src) dest[i] = src[i]; return dest; }; // filesystem operations function fs_ensure_directory(dir, callback) { dir = PATH.normalize(dir); try { if (FS.statSync(dir).isDirectory()) return callback(null, dir); else callback(new Error("fs_ensure_directory: " + dir + " exists and is not a directory!")); } catch(ex) { fs_ensure_directory(PATH.dirname(dir), function(err){ if (err) return callback(err); FS.mkdirSync(dir, 0755); callback(null, dir); }); } }; function fs_copylist(files, dest, callback) { function cont(err) { if (err) return callback(err); if (++copied == files.length) callback(); }; var copied = 0; for (var i = files.length; --i >= 0;) fs_copy(files[i], dest, cont); }; var copy_in_progress = 0; function fs_copy(source, dest, callback) { // we have to place some limit on the max number of files we copy // at once, to avoid the "EMFILE" error. // // http://stackoverflow.com/questions/8965606/node-and-error-emfile-too-many-open-files // // tried "graceful-fs" but it doesn't really work.. if (copy_in_progress >= 150) { setTimeout(function(){ fs_copy(source, dest, callback); }, 10); } else { ++copy_in_progress; _fs_do_copy(source, dest, function(){ --copy_in_progress; return callback.apply(this, arguments); }); } } function _fs_do_copy(source, dest, callback) { if (source instanceof Array) return fs_copylist(source, dest, callback); fs_ensure_directory(PATH.dirname(dest), function(err){ if (err) return callback(err); FS.lstat(source, function(err, stat){ if (err) return callback(err); else if (stat.isDirectory()) { dest = PATH.join(dest, PATH.basename(source)); return fs_ensure_directory(dest, function(){ fs_copytree(source, dest, callback); }); } else if (stat.isSymbolicLink()) { FS.readlink(source, function(err, data){ if (err) return callback(err); FS.lstat(dest, function(err, stat){ if (err && err.code != "ENOENT") return callback(err); if (!err && stat.isDirectory()) { dest = PATH.join(dest, PATH.basename(source)); } FS.symlink(data, dest, callback); }); }); } else FS.readFile(source, function(err, data){ if (err) return callback(err); FS.stat(dest, function(err, stat){ if (err && err.code != "ENOENT") return callback(err); if (!err && stat.isDirectory()) { dest = PATH.join(dest, PATH.basename(source)); } FS.writeFile(dest, data, callback); }); }); }); }); }; function fs_copytree(source, dest, options) { if (!options) options = {}; if (typeof options == "function") options = { callback: options }; if (!options.callback) options.callback = function(err) { if (err) throw err; }; var finished = false, count = 0; var args = { callback: function(err, f) { if (err) return options.callback(err); if (!f.stat.isDirectory()) { ++count; fs_copy(f.full, PATH.join(dest, f.rel), function(err){ if (err) return options.callback(err); --count; if (finished && count == 0) options.callback(); }); } }, filter: options.filter, recurse: options.recurse, finish: function() { finished = true; } }; fs_find(source, args); }; function is_vcs_dir(name) { return (/^(\.git|\.hg|\.bzr|SVN|CVS|_darcs)$/.test(name)); }; function fs_find(dir, options, prefix, level, finish) { if (dir == null) dir = process.cwd(); if (prefix == null) prefix = "."; if (level == null) { level = 0; finish = options.finish || function(){}; } FS.readdir(dir, function(err, ret){ if (err) return options.callback(err); var async_calls = ret.length; if (async_calls == 0) { finish(); return; } ret.forEach(function(name){ var fullname = PATH.join(dir, name); FS.stat(fullname, function(err, stat){ if (err) { options.callback(err); } else { var rel = PATH.join(prefix, name); var f = { name : name, full : fullname, stat : stat, dir : dir, rel : rel }; if (!options.filter || options.filter(f)) options.callback(null, f); if (stat.isDirectory() && (!options.recurse || options.recurse(f)) && (!options.skip_vcs || !is_vcs_dir(fullname))) { fs_find(fullname, options, rel, level + 1, function(){ if (--async_calls == 0) finish(); }); return; } } if (--async_calls == 0) finish(); }); }); }); }; function fs_rmpath(dir, callback, deep) { FS.stat(dir, function(err, stat){ if (err) return deep ? callback(err) : callback(); if (stat.isDirectory()) { FS.readdir(dir, function(err, entries){ if (err) return callback(err); function cont() { FS.rmdir(dir, function(err){ if (err) return callback(err); callback(); }); }; var n = entries.length; if (n == 0) cont(); else entries.forEach(function(e){ fs_rmpath(PATH.join(dir, e), function(err){ if (err) return callback(err); if (--n == 0) cont(); }, true); }); }); } else { FS.unlink(dir, function(err){ if (err) return callback(err); callback(); }); } }); }; function fs_rmpathSync(x) { var stat = FS.statSync(x); if (!stat.isDirectory()) { FS.unlinkSync(x); } else { FS.readdirSync(x).forEach(function(file){ fs_rmpathSync(PATH.join(x, file)); }); FS.rmdirSync(x); } };