Skip to content

Instantly share code, notes, and snippets.

@mfix22
Last active March 15, 2017 23:51
Show Gist options
  • Save mfix22/db7c3bc609c686dc193e71a99dba9000 to your computer and use it in GitHub Desktop.
Save mfix22/db7c3bc609c686dc193e71a99dba9000 to your computer and use it in GitHub Desktop.
Recursive file search by pattern
module.exports = function findFilesByPattern (pattern, dir = process.cwd()) {
const check = (name, file) => {
const newFile = path.join(name, file)
return new Promise((resolve, reject) => {
fs.stat(newFile, (err, stats) => {
if (err) return reject(err)
if (stats && stats.isDirectory()) return resolve(readDir(newFile))
if (pattern.exec(newFile)) return resolve(newFile)
return resolve()
})
})
}
const readDir = (name) =>
new Promise((resolve, reject) =>
fs.readdir(name, (err, files) =>
err ? reject(err) : resolve(Promise.all(
files.map(check.bind(null, name))
))))
.then(values =>
values.reduce((x, y) => x.concat(y), [])
.filter(value => value))
return readDir(dir)
}

Recursive file searching can be helpful if you are building a tool like jest or gest. For example, jest searches for files that match /(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$/i, and gest looks for /.*.(query|graphql|gql)$/i. I wanted to test my functional programming abilities and try to tackle this recursive problem as functionally as possible.

Implementation below

Example Usage

const gest = Gest(schema, options)

findFilesByPattern(/.*.(query|graphql|gql)$/i)
  .then(values =>
    Promise.all(values.map(v =>
      readFile(v)
        .then(gest))))
  .catch(console.log)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment