You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

54 lines
1.8 KiB

// walks a set of directories recursively, and returns
// the list of files that match the filter, if one is
// provided.
module.exports = find
var fs = require("graceful-fs")
, asyncMap = require("slide").asyncMap
, path = require("path")
function find (dir, filter, depth, cb) {
if (typeof cb !== "function") cb = depth, depth = Infinity
if (typeof cb !== "function") cb = filter, filter = null
if (filter instanceof RegExp) filter = reFilter(filter)
if (typeof filter === "string") filter = strFilter(filter)
if (!Array.isArray(dir)) dir = [dir]
if (!filter) filter = nullFilter
asyncMap(dir, findDir(filter, depth), cb)
}
function findDir (filter, depth) { return function (dir, cb) {
fs.lstat(dir, function (er, stats) {
// don't include missing files, but don't abort either
if (er) return cb()
if (!stats.isDirectory()) return findFile(dir, filter, depth)("", cb)
var found = []
if (!filter || filter(dir, "dir")) found.push(dir+"/")
if (depth <= 0) return cb(null, found)
cb = (function (cb) { return function (er, f) {
cb(er, found.concat(f))
}})(cb)
fs.readdir(dir, function (er, files) {
if (er) return cb(er)
asyncMap(files, findFile(dir, filter, depth - 1), cb)
})
})
}}
function findFile (dir, filter, depth) { return function (f, cb) {
f = path.join(dir, f)
fs.lstat(f, function (er, s) {
// don't include missing files, but don't abort either
if (er) return cb(null, [])
if (s.isDirectory()) return find(f, filter, depth, cb)
if (!filter || filter(f, "file")) cb(null, f)
else cb(null, [])
})
}}
function reFilter (re) { return function (f, type) {
return nullFilter(f, type) && f.match(re)
}}
function strFilter (s) { return function (f, type) {
return nullFilter(f, type) && f.indexOf(s) === 0
}}
function nullFilter (f, type) { return type === "file" && f }