filesearcher
I'm working on some learning projects, aka reimplementing stuff that could be done easier by piping a bunch of shell utilities together. A few lessons from DIY sewing:
- Give it permission to look weird.
- No, you're (probably) not going to reach the same level of speed and efficiency as a sweatshop with 300 years of technological automation.
- Knowing how it works is priceless.
import util from 'node:util'
import * as fsWalk from '@nodelib/fs.walk'
// https://www.npmjs.com/package/@nodelib/fs.walk
const errorFilter = (error) => error.code === 'EACCES' || 'EPERM'
const ignoreDirs = [/[.]git[/]/, /[/]node_modules[/]/]
/**
* Filter predicate to determine if a directory should be
* ignored or not.
* @param {fsWalk.Entry} entry Entry to match against.
* @param {Regexp[]} ignoreDirs List of RegExps to match directories to ignore.
* @returns {Boolean}
*/
const ignore = function (entry, ignoreDirs) {
for (let i in ignoreDirs) {
let dr = new RegExp(ignoreDirs[i])
if (dr.test(entry.path)) {
return true
}
}
return false
}
/**
* Run a search query and return a list of matching fsWalk entries.
* @param {String} searchStr Regexp or string to match against target path.
* @param {String} path Source path from which to start searching.
* @param {String[]} ignoreDirs List matching dirs to ignore.
* @returns
*/
const runGlob = function (searchStr, path, ignoreDirs) {
// todo ramda might make this easier
const searchThis = (entry) => {
if (ignore(entry, ignoreDirs)) {
return false
} else {
return true
}
}
const searchReg = new RegExp(searchStr)
// Transform a function that uses a callback into one that returns a promise.
const walk = util.promisify(fsWalk.walk)
return walk(path ?? '.', { deepFilter: searchThis, errorFilter: errorFilter }).then((response) =>
response.filter((entry) => searchReg.test(entry.path))
)
}
export { runGlob, ignore }
Lessons learned:
- A large number of my files are ephemera from the development process, so having a way to exclude
.git,venv, andnode_moduleswill dramatically cut down the time. (As much as 90%.) - I spent way too much time trying to fit that for loop into a ramda expression.
- I'm having much better luck working with vite compared to webpack/babel.
Things I need to learn:
- The concepts under other people's boilerplate.
- How to test async functionality in jest/vitest.
EDIT: Updated to fix some string-matching and logic errors.