From ca81be919a19ddb905b6a37476a742c9f7d42a4c Mon Sep 17 00:00:00 2001 From: nirs Date: Mon, 4 Dec 2017 16:08:31 +0200 Subject: [PATCH] Adding an option to limit the number of files to be deleted at a single operation. The returned Json will only include files deleted. Tests added too. --- README.md | 7 ++++--- find-remove.js | 45 +++++++++++++++++++++++++++++++++++++++++++-- tests/basics.js | 27 +++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b699eea..ab79c61 100644 --- a/README.md +++ b/README.md @@ -59,10 +59,10 @@ var result = findRemoveSync('/temp', {extensions: ['.bak'], ignore: 'haumiblau.b var result = findRemoveSync('/dist', {dir: 'CVS'}) ``` -### 6. delete all jpg files older than one hour +### 6. delete all jpg files older than one hour with limit of 100 files deletion per operation ```javascript -var result = findRemoveSync('/tmp', {age: {seconds: 3600}, extensions: '.jpg'}) +var result = findRemoveSync('/tmp', {age: {seconds: 3600}, extensions: '.jpg', limit: 100}) ``` ### 7. apply filter options only for two levels inside the /temp directory for all tmp files @@ -98,6 +98,7 @@ __arguments__ * `extensions` - this too, can be a string or an array of file extenstions you want to delete within `dir`. * `ignore` - useful to exclude some files. again, can be a string or an array of file names you do NOT want to delete within `dir` * `age.seconds` - can be any float number. findRemoveSync then compares it with the file stats and deletes those with creation times older than `age.seconds` + * `limit` - can be any integer number. Will limit the number of files to be deleted at single operation to be `limit` * `maxLevel` - advanced: limits filtering to a certain level. useful for performance. recommended for crawling huge directory trees. * `test` - advanced: set to true for a test run, meaning it does not delete anything but returns a JSON of files/directories it would have deleted. useful for testing. @@ -107,7 +108,7 @@ the unit tests are good examples on how to use the above arguments. __returns__ -JSON of files/directories that were deleted. +JSON of files/directories that were deleted. For limit option - will only return number of files deleted. ## todo diff --git a/find-remove.js b/find-remove.js index 818b601..fdd3824 100644 --- a/find-remove.js +++ b/find-remove.js @@ -15,6 +15,26 @@ function isOlder(path, ageSeconds) { return now > expirationTime } +function hasLimit(options) { + return options && options.hasOwnProperty('limit') +} + +function getLimit(options) { + return hasLimit(options) ? options.limit : -1 +} + +function hasTotalRemoved(options) { + return options && options.hasOwnProperty('totalRemoved') +} + +function getTotalRemoved(options) { + return hasTotalRemoved(options) ? options.totalRemoved : -2 +} + +function isOverTheLimit(options) { + return getTotalRemoved(options) >= getLimit(options) +} + function hasMaxLevel(options) { return options && options.hasOwnProperty('maxLevel') } @@ -42,6 +62,10 @@ function doDeleteDirectory(currentDir, options, currentLevel) { doDelete = true } + if (doDelete && hasLimit(options)) { + doDelete = !isOverTheLimit(options) + } + if (doDelete && hasMaxLevel(options) && currentLevel > 0) { doDelete = currentLevel <= getMaxLevel(options) } @@ -88,6 +112,10 @@ function doDeleteFile(currentFile, options) { } } + if (doDelete && hasLimit(options)) { + doDelete = !isOverTheLimit(options) + } + if (doDelete && ignore) { if (util.isArray(ignore)) doDelete = !(ignore.indexOf(basename) !== -1) @@ -127,11 +155,15 @@ var findRemoveSync = module.exports = function(currentDir, options, currentLevel var removed = {} - if (fs.existsSync(currentDir)) { + if (!isOverTheLimit(options) && fs.existsSync(currentDir)) { var maxLevel = getMaxLevel(options), deleteDirectory = false + if (hasLimit(options)) { + options.totalRemoved = hasTotalRemoved(options) ? getTotalRemoved(options) : 0 + } + if (currentLevel === undefined) currentLevel = 0 else @@ -160,6 +192,9 @@ var findRemoveSync = module.exports = function(currentDir, options, currentLevel // merge results removed = merge(removed, result) + if (hasTotalRemoved(options)) + options.totalRemoved += Object.keys(result).length + } else { if (doDeleteFile(currentFile, options)) { @@ -167,6 +202,9 @@ var findRemoveSync = module.exports = function(currentDir, options, currentLevel fs.unlinkSync(currentFile) removed[currentFile] = true + if (hasTotalRemoved(options)) + options.totalRemoved ++ + } } }) @@ -177,7 +215,10 @@ var findRemoveSync = module.exports = function(currentDir, options, currentLevel if (!testRun) rimraf.sync(currentDir) - removed[currentDir] = true + if (!hasTotalRemoved(options)) + // for limit of files - we do not want to count the directories + removed[currentDir] = true + } catch (err) { throw err } diff --git a/tests/basics.js b/tests/basics.js index a396bda..1e555ec 100644 --- a/tests/basics.js +++ b/tests/basics.js @@ -703,5 +703,32 @@ module.exports = testCase({ t.done() } + }), + + 'TC 5: limit checks': testCase({ + + setUp: function(cb) { + createFakeDirectoryTree(cb) + }, + tearDown: function(cb) { + destroyFakeDirectoryTree(cb) + }, + + 'findRemoveSync(files older than .0005 sec with limit of 2)': function(t) { + var result = findRemoveSync(rootDirectory, {files: "*.*", age: {seconds: 0.0005}, limit: 2}) + + t.strictEqual(Object.keys(result).length, 2, 'findRemoveSync(files older than .0005 sec) returned 2 entries (out of 11).') + + t.done() + }, + + 'findRemoveSync(files and dirs older than .0005 sec with limit of 5)': function(t) { + var result = findRemoveSync(rootDirectory, {files: "*.*", dir: "*", age: {seconds: 0.0005}, limit: 5}) + + t.strictEqual(Object.keys(result).length, 5, 'findRemoveSync(files older than .0005 sec) returned 5 entries (out of 19).') + + t.done() + } + }) })