walk.js/walk.js

51 lines
1.2 KiB
JavaScript
Raw Permalink Normal View History

2020-12-09 22:58:53 +00:00
"use strict";
const fs = require("fs").promises;
const path = require("path");
2020-12-09 11:10:56 +00:00
const skipDir = new Error("skip this directory");
2020-12-09 22:58:53 +00:00
const _withFileTypes = { withFileTypes: true };
2020-12-09 11:10:56 +00:00
const pass = (err) => err;
// a port of Go's filepath.Walk
2020-12-09 11:48:55 +00:00
const walk = async (pathname, walkFunc, _dirent) => {
2020-12-09 11:10:56 +00:00
let err;
// special case of the very first run
if (!_dirent) {
2020-12-09 11:48:55 +00:00
let _name = path.basename(path.resolve(pathname));
_dirent = await fs.lstat(pathname).catch(pass);
2020-12-09 11:10:56 +00:00
if (_dirent instanceof Error) {
err = _dirent;
} else {
_dirent.name = _name;
}
}
// run the user-supplied function and either skip, bail, or continue
2020-12-09 11:48:55 +00:00
err = await walkFunc(err, pathname, _dirent).catch(pass);
2020-12-09 11:10:56 +00:00
if (false === err || skipDir === err) {
return;
}
if (err instanceof Error) {
throw err;
}
// "walk does not follow symbolic links"
if (!_dirent.isDirectory()) {
return;
}
2020-12-09 11:48:55 +00:00
let result = await fs.readdir(pathname, _withFileTypes).catch(pass);
2020-12-09 11:10:56 +00:00
if (result instanceof Error) {
2020-12-09 11:48:55 +00:00
return walkFunc(result, pathname, _dirent);
2020-12-09 11:10:56 +00:00
}
for (let dirent of result) {
2020-12-09 11:48:55 +00:00
await walk(path.join(pathname, dirent.name), walkFunc, dirent);
2020-12-09 11:10:56 +00:00
}
};
2020-12-09 22:58:53 +00:00
module.exports = {
2020-12-09 11:10:56 +00:00
walk,
skipDir,
};