@plugjs/plug
Version:
PlugJS Build System ===================
74 lines (73 loc) • 2.18 kB
JavaScript
// 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