2020-12-09 22:58:53 +00:00
|
|
|
/**
|
|
|
|
* @license
|
|
|
|
* walk.js - fs.walk for node.js (a port of Go's filepath.Walk)
|
|
|
|
*
|
|
|
|
* Written in 2020 by AJ ONeal <coolaj86@gmail.com>
|
|
|
|
* To the extent possible under law, the author(s) have dedicated all copyright
|
|
|
|
* and related and neighboring rights to this software to the public domain
|
|
|
|
* worldwide. This software is distributed without any warranty.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the CC0 Public Domain Dedication along with
|
|
|
|
* this software. If not, see <https://creativecommons.org/publicdomain/zero/1.0/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
async function walk(pathname, walkFunc, dirent) {
|
|
|
|
const fs = require("fs").promises;
|
|
|
|
const path = require("path");
|
|
|
|
const _pass = (err) => err;
|
|
|
|
|
2020-12-09 11:48:55 +00:00
|
|
|
let err;
|
|
|
|
|
2020-12-09 22:58:53 +00:00
|
|
|
// special case: walk the very first file or folder
|
|
|
|
if (!dirent) {
|
|
|
|
let filename = path.basename(path.resolve(pathname));
|
|
|
|
dirent = await fs.lstat(pathname).catch(_pass);
|
|
|
|
if (dirent instanceof Error) {
|
|
|
|
err = dirent;
|
2020-12-09 11:48:55 +00:00
|
|
|
} else {
|
2020-12-09 22:58:53 +00:00
|
|
|
dirent.name = filename;
|
2020-12-09 11:48:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// run the user-supplied function and either skip, bail, or continue
|
2020-12-09 22:58:53 +00:00
|
|
|
err = await walkFunc(err, pathname, dirent).catch(_pass);
|
2020-12-09 11:48:55 +00:00
|
|
|
if (false === err) {
|
2020-12-09 22:58:53 +00:00
|
|
|
// walkFunc can return false to skip
|
2020-12-09 11:48:55 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (err instanceof Error) {
|
2020-12-09 22:58:53 +00:00
|
|
|
// if walkFunc throws, we throw
|
2020-12-09 11:48:55 +00:00
|
|
|
throw err;
|
|
|
|
}
|
|
|
|
|
|
|
|
// "walk does not follow symbolic links"
|
2020-12-09 22:58:53 +00:00
|
|
|
// (doing so could cause infinite loops)
|
|
|
|
if (!dirent.isDirectory()) {
|
2020-12-09 11:48:55 +00:00
|
|
|
return;
|
|
|
|
}
|
2020-12-09 22:58:53 +00:00
|
|
|
let result = await fs.readdir(pathname, { withFileTypes: true }).catch(_pass);
|
2020-12-09 11:48:55 +00:00
|
|
|
if (result instanceof Error) {
|
2020-12-09 22:58:53 +00:00
|
|
|
// notify on directory read error
|
|
|
|
return walkFunc(result, pathname, dirent);
|
2020-12-09 11:48:55 +00:00
|
|
|
}
|
2020-12-09 22:58:53 +00:00
|
|
|
for (let entity of result) {
|
|
|
|
await walk(path.join(pathname, entity.name), walkFunc, entity);
|
2020-12-09 11:48:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-09 22:58:53 +00:00
|
|
|
// Example Usage:
|
|
|
|
const path = require("path");
|
2020-12-09 11:48:55 +00:00
|
|
|
walk("./", function (err, pathname, dirent) {
|
|
|
|
if (dirent.name.startsWith(".")) {
|
|
|
|
return Promise.resolve(false);
|
|
|
|
}
|
|
|
|
|
2020-12-09 22:58:53 +00:00
|
|
|
var typ = "-";
|
|
|
|
if (dirent.isFile()) {
|
|
|
|
typ = "f";
|
|
|
|
} else if (dirent.isDirectory()) {
|
|
|
|
typ = "d";
|
|
|
|
} else if (dirent.isSymbolicLink()) {
|
|
|
|
typ = "@";
|
|
|
|
}
|
|
|
|
console.info(typ, path.resolve(pathname));
|
2020-12-09 11:48:55 +00:00
|
|
|
return Promise.resolve(true);
|
|
|
|
});
|