UNPKG

@plugjs/plug

Version:
74 lines (73 loc) 2.18 kB
// utils/walk.ts import { basename, join } from "node:path"; import { opendir, stat } from "../fs.mjs"; import { $p, log } from "../logging.mjs"; import { resolveAbsolutePath } from "../paths.mjs"; import { match } from "./match.mjs"; function walk(directory, globs, options = {}) { const { maxDepth = Infinity, followSymlinks = true, allowNodeModules = false, ...opts } = options; const onDirectory = (dir) => { if (dir === directory) return true; const name = basename(dir); if (name === "node_modules") return !!allowNodeModules; if (name.startsWith(".")) return !!opts.dot; return true; }; const positiveMatcher = match(globs, opts); log.debug("Walking directory", $p(directory), { globs, options }); return walker({ directory, relative: "", matcher: positiveMatcher, onDirectory, followSymlinks, maxDepth, depth: 0 }); } async function* walker(args) { const { directory, relative, matcher: positiveMatcher, onDirectory, followSymlinks, maxDepth, depth } = args; const dir = resolveAbsolutePath(directory, relative); if (!onDirectory(dir)) return; log.trace("Reading directory", $p(dir)); let dirents; try { dirents = await opendir(dir); } catch (error) { if (error.code !== "ENOENT") throw error; log.warn("Directory", $p(dir), "not found"); return; } for await (const dirent of dirents) { const path = join(relative, dirent.name); if (dirent.isFile() && positiveMatcher(path)) yield path; else if (dirent.isDirectory() && depth < maxDepth) { const children = walker({ ...args, relative: path, depth: depth + 1 }); for await (const child of children) yield child; } else if (dirent.isSymbolicLink() && followSymlinks) { const info = await stat(join(directory, path)); if (info.isFile() && positiveMatcher(path)) yield path; else if (info.isDirectory() && depth < maxDepth) { const children = walker({ ...args, relative: path, depth: depth + 1 }); for await (const child of children) yield child; } } } } export { walk }; //# sourceMappingURL=walk.mjs.map