Skip to content

Instantly share code, notes, and snippets.

@Phoenix35
Last active July 24, 2019 00:25
Show Gist options
  • Save Phoenix35/26aa316bd52c743021eab457ab4ee07d to your computer and use it in GitHub Desktop.
Save Phoenix35/26aa316bd52c743021eab457ab4ee07d to your computer and use it in GitHub Desktop.
"use strict";
const fs = require("fs"),
fsP = fs.promises;
const path = require("path");
const { chdir, cwd } = process;
async function removeEVERYTHING (targetDir) {
const oldDir = cwd();
chdir(targetDir);
try {
const pathsStack = ["."];
while (pathsStack.length) {
const currentPath = pathsStack[pathsStack.length - 1];
const files = await fsP.readdir( // eslint-disable-line no-await-in-loop
currentPath,
{ withFileTypes: true },
);
if (files.length === 0) {
// Directory is empty, no need to live on the stack anymore
pathsStack.pop();
if (currentPath === ".")
break;
// Await is needed for the length check to work on following iterations
// (i.e. when you remove the last subfolder of a folder)
await fsP.rmdir(currentPath); // eslint-disable-line no-await-in-loop
} else {
const unlinkOperations = [];
for (const file of files) {
const fullPath = path.join(currentPath, file.name);
if (file.isFile())
unlinkOperations.push(fsP.unlink(fullPath));
else if (file.isDirectory())
pathsStack.push(fullPath);
}
// Same reasoning as for folders
await Promise.all(unlinkOperations); // eslint-disable-line no-await-in-loop
}
}
chdir(oldDir);
await fsP.rmdir(targetDir);
} catch (err) {
console.error(err);
}
}
module.exports = (filePath) => {
fs.access(filePath, fs.constants.F_OK | fs.constants.W_OK, (err) => {
if (err) {
console.error(`${filePath} ${
err.code === "ENOENT"
? "does not exist"
: "cannot be deleted"
}`);
return;
}
removeEVERYTHING(filePath);
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment