walk.js/snippet.js

78 lines
2.1 KiB
JavaScript
Raw Normal View History

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);
});