From f85f5bc9ac224c259582db43a9fab908b79fe75c Mon Sep 17 00:00:00 2001 From: Jakub Szwacz Date: Wed, 15 Mar 2017 19:49:10 +0100 Subject: [PATCH] More performant remove --- lib/remove.js | 61 +++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/lib/remove.js b/lib/remove.js index 232ede7..92e9184 100644 --- a/lib/remove.js +++ b/lib/remove.js @@ -3,7 +3,6 @@ var pathUtil = require('path'); var fs = require('./utils/fs'); var validate = require('./utils/validate'); -var inspect = require('./inspect'); var list = require('./list'); var validateInput = function (methodName, path) { @@ -11,31 +10,29 @@ var validateInput = function (methodName, path) { validate.argument(methodSignature, 'path', path, ['string', 'undefined']); }; -var generateUnknownEtityUnderPathError = function (path) { - return new Error("Can't remove " + path + ' The path is not file nor directory'); -}; - // --------------------------------------------------------- // Sync // --------------------------------------------------------- var removeSync = function (path) { - // First check what we have on given path. - var inspectedFile = inspect.sync(path, { symlinks: 'report' }); - if (inspectedFile === undefined) { - // The path already doesn't exits. Nothing to do here. - } else if (inspectedFile.type === 'dir') { - // Must delete everything inside the directory first. - list.sync(path).forEach(function (filename) { - removeSync(pathUtil.join(path, filename)); - }); - // Everything inside directory has been removed, - // it's safe now do go for the directory itself. - fs.rmdirSync(path); - } else if (inspectedFile.type === 'file' || inspectedFile.type === 'symlink') { + try { + // Assume the path is a file and just try to remove it. fs.unlinkSync(path); - } else { - throw generateUnknownEtityUnderPathError(path); + } catch (err) { + if (err.code === 'EPERM') { + // Must delete everything inside the directory first. + list.sync(path).forEach(function (filename) { + removeSync(pathUtil.join(path, filename)); + }); + // Everything inside directory has been removed, + // it's safe now do go for the directory itself. + fs.rmdirSync(path); + } else if (err.code === 'ENOENT') { + // File already doesn't exist. We're done. + } else { + // Something unexpected happened. Rethrow original error. + throw err; + } } }; @@ -45,13 +42,13 @@ var removeSync = function (path) { var removeAsync = function (path) { return new Promise(function (resolve, reject) { - // First check what we have on given path. - inspect.async(path).then(function (inspectedFile) { - if (inspectedFile === undefined) { - // The path already doesn't exits. Nothing to do here. - resolve(); - } else if (inspectedFile.type === 'dir') { - // Must delete everything inside the directory first. + // Assume the path is a file and just try to remove it. + fs.unlink(path) + .then(resolve) + .catch(function (err) { + if (err.code === 'EPERM') { + // It's not a file, it's a directory. + // Must delete everything inside first. list.async(path).then(function (filenamesInsideDir) { var promises = filenamesInsideDir.map(function (filename) { return removeAsync(pathUtil.join(path, filename)); @@ -60,14 +57,16 @@ var removeAsync = function (path) { }) .then(function () { // Everything inside directory has been removed, - // it's safe now do go for the directory itself. + // it's safe now to go for the directory itself. return fs.rmdir(path); }) .then(resolve, reject); - } else if (inspectedFile.type === 'file' || inspectedFile.type === 'symlink') { - fs.unlink(path).then(resolve, reject); + } else if (err.code === 'ENOENT') { + // File already doesn't exist. We're done. + resolve(); } else { - reject(generateUnknownEtityUnderPathError(path)); + // Something unexpected happened. Rethrow original error. + reject(err); } }); });