delete-empty
Advanced tools
Comparing version 0.1.3 to 1.0.0
155
index.js
/*! | ||
* delete-empty <https://github.com/jonschlinkert/delete-empty> | ||
* | ||
* Copyright (c) 2015, Jon Schlinkert. | ||
* Licensed under the MIT License. | ||
* Copyright (c) 2015, 2017, Jon Schlinkert. | ||
* Released under the MIT License. | ||
*/ | ||
@@ -10,41 +10,69 @@ | ||
var fs = require('fs'); | ||
var path = require('path'); | ||
var utils = require('./utils'); | ||
var relative = require('relative'); | ||
var series = require('async-each-series'); | ||
var rimraf = require('rimraf'); | ||
var ok = require('log-ok'); | ||
function deleteEmpty(cwd, options, cb) { | ||
if(cb === undefined) { | ||
cb = options; | ||
function deleteEmpty(cwd, options, done) { | ||
if (typeof options === 'function') { | ||
done = options; | ||
options = {}; | ||
} | ||
if (utils.emptySync(cwd)) { | ||
utils.del(cwd, options, function(err) { | ||
if (err) return cb(err); | ||
return cb(null, [cwd]); | ||
}); | ||
return; | ||
if (typeof done !== 'function') { | ||
throw new TypeError('expected callback to be a function'); | ||
} | ||
utils.glob('**/', {cwd: cwd}, function(err, files) { | ||
if (err) { | ||
err.code = 'glob'; | ||
return cb(err); | ||
var dirname = path.resolve(cwd); | ||
var opts = Object.assign({filter: keep}, options); | ||
var acc = []; | ||
function remove(filepath, cb) { | ||
var dir = path.resolve(filepath); | ||
if (dir.indexOf(dirname) !== 0) { | ||
cb(); | ||
return; | ||
} | ||
utils.async.reduceRight(files, [], function(acc, filename, next) { | ||
var dir = path.join(cwd, filename); | ||
utils.empty(dir, function(err, isEmpty) { | ||
if (err) return next(err); | ||
if (!isEmpty) { | ||
return next(null, acc); | ||
} | ||
if (!isDirectory(dir)) { | ||
cb(); | ||
return; | ||
} | ||
utils.del(dir, options, function(err) { | ||
if (err) return next(err); | ||
fs.readdir(dir, function(err, files) { | ||
if (err) { | ||
cb(err); | ||
return; | ||
} | ||
acc.push(dir); | ||
next(null, acc); | ||
if (isEmpty(files, opts.filter)) { | ||
rimraf(dir, function(err) { | ||
if (err) { | ||
cb(err); | ||
return; | ||
} | ||
// display relative path for readability | ||
var rel = relative(dir); | ||
if (opts.silent !== true) { | ||
ok('deleted:', rel); | ||
} | ||
acc.push(rel); | ||
remove(path.dirname(dir), cb); | ||
}); | ||
}); | ||
}, cb); | ||
} else { | ||
series(files, function(file, next) { | ||
remove(path.resolve(dir, file), next); | ||
}, cb); | ||
} | ||
}); | ||
} | ||
remove(dirname, function(err) { | ||
done(err, acc); | ||
}); | ||
@@ -54,21 +82,64 @@ } | ||
deleteEmpty.sync = function(cwd, options) { | ||
if (utils.emptySync(cwd)) { | ||
utils.del.sync(cwd, options); | ||
return [cwd]; | ||
} | ||
var dirname = path.resolve(cwd); | ||
var opts = Object.assign({filter: keep}, options); | ||
var acc = []; | ||
var dirs = utils.glob.sync('**/', {cwd: cwd}); | ||
var len = dirs.length; | ||
var res = []; | ||
function remove(filepath) { | ||
var dir = path.resolve(filepath); | ||
if (dir.indexOf(dirname) !== 0) return; | ||
while (len--) { | ||
var dir = path.join(cwd, dirs[len]); | ||
if (utils.emptySync(dir)) { | ||
utils.del.sync(dir, options); | ||
res.push(dir); | ||
if (isDirectory(dir)) { | ||
var files = fs.readdirSync(dir); | ||
if (isEmpty(files, opts.filter)) { | ||
rimraf.sync(dir); | ||
var rel = relative(dir); | ||
if (opts.silent !== true) { | ||
ok('deleted:', rel); | ||
} | ||
acc.push(rel); | ||
remove(path.dirname(dir)); | ||
} else { | ||
for (var i = 0; i < files.length; i++) { | ||
remove(path.resolve(dir, files[i])); | ||
} | ||
} | ||
} | ||
} | ||
return res; | ||
remove(dirname); | ||
return acc; | ||
}; | ||
function isDirectory(filepath) { | ||
var stat = tryStat(filepath); | ||
if (stat) { | ||
return stat.isDirectory(); | ||
} | ||
} | ||
function tryStat(filepath) { | ||
try { | ||
return fs.statSync(filepath); | ||
} catch (err) {} | ||
} | ||
function isEmpty(files, fn) { | ||
try { | ||
return files.filter(fn).length === 0; | ||
} catch (err) { | ||
if (err & err.code === 'ENOENT') { | ||
return false; | ||
} | ||
throw err; | ||
} | ||
} | ||
function keep(filename) { | ||
return !/(?:Thumbs\.db|\.DS_Store)$/i.test(filename); | ||
} | ||
/** | ||
@@ -75,0 +146,0 @@ * Expose deleteEmpty |
{ | ||
"name": "delete-empty", | ||
"version": "0.1.3", | ||
"description": "Recursively delete all empty folders in a directory and child directories.", | ||
"version": "1.0.0", | ||
"homepage": "https://github.com/jonschlinkert/delete-empty", | ||
"author": "Jon Schlinkert (https://github.com/jonschlinkert)", | ||
"contributors": [ | ||
"Jon Schlinkert <jon.schlinkert@sellside.com> (http://twitter.com/jonschlinkert)", | ||
"Sven Schoenung (http://sven.schoenung.org)", | ||
"Vittorio Palmisano (http://c3lab.poliba.it/index.php/VittorioPalmisano)" | ||
], | ||
"repository": "jonschlinkert/delete-empty", | ||
@@ -13,6 +18,9 @@ "bugs": { | ||
"files": [ | ||
"index.js", | ||
"utils.js" | ||
"bin", | ||
"index.js" | ||
], | ||
"main": "index.js", | ||
"bin": { | ||
"delete-empty": "bin/cli.js" | ||
}, | ||
"engines": { | ||
@@ -25,10 +33,11 @@ "node": ">=0.10.0" | ||
"dependencies": { | ||
"async": "^1.5.0", | ||
"delete": "^0.3.2", | ||
"lazy-cache": "^2.0.1", | ||
"matched": "^0.4.1" | ||
"async-each-series": "^1.1.0", | ||
"log-ok": "^0.1.1", | ||
"relative": "^3.0.2", | ||
"rimraf": "^2.6.0" | ||
}, | ||
"devDependencies": { | ||
"gulp-format-md": "^0.1.7", | ||
"mocha": "^2.4.5" | ||
"gulp-format-md": "^0.1.11", | ||
"matched": "^0.4.4", | ||
"mocha": "^3.2.0" | ||
}, | ||
@@ -35,0 +44,0 @@ "keywords": [ |
@@ -1,2 +0,2 @@ | ||
# delete-empty [![NPM version](https://img.shields.io/npm/v/delete-empty.svg?style=flat)](https://www.npmjs.com/package/delete-empty) [![NPM downloads](https://img.shields.io/npm/dm/delete-empty.svg?style=flat)](https://npmjs.org/package/delete-empty) [![Build Status](https://img.shields.io/travis/jonschlinkert/delete-empty.svg?style=flat)](https://travis-ci.org/jonschlinkert/delete-empty) | ||
# delete-empty [![NPM version](https://img.shields.io/npm/v/delete-empty.svg?style=flat)](https://www.npmjs.com/package/delete-empty) [![NPM monthly downloads](https://img.shields.io/npm/dm/delete-empty.svg?style=flat)](https://npmjs.org/package/delete-empty) [![NPM total downloads](https://img.shields.io/npm/dt/delete-empty.svg?style=flat)](https://npmjs.org/package/delete-empty) [![Linux Build Status](https://img.shields.io/travis/jonschlinkert/delete-empty.svg?style=flat&label=Travis)](https://travis-ci.org/jonschlinkert/delete-empty) | ||
@@ -10,3 +10,3 @@ > Recursively delete all empty folders in a directory and child directories. | ||
```sh | ||
$ npm install delete-empty --save | ||
$ npm install --save delete-empty | ||
``` | ||
@@ -27,11 +27,10 @@ | ||
└─┬ a/ | ||
- ├── aa/ | ||
├─┬ bb/ | ||
- ├── aa/ | ||
├── bb/ | ||
│ └─┬ bbb/ | ||
│ ├── one.txt | ||
│ └── two.txt | ||
- ├─┬ cc/ | ||
- │ └── ccc/ | ||
- ├ b/ | ||
- └ c/ | ||
- ├── cc/ | ||
- ├ b/ | ||
- └ c/ | ||
``` | ||
@@ -62,38 +61,42 @@ | ||
## Related projects | ||
## About | ||
You might also be interested in these projects: | ||
### Related projects | ||
* [copy](https://www.npmjs.com/package/copy): Copy files or directories using globs. | [homepage](https://github.com/jonschlinkert/copy) | ||
* [delete](https://www.npmjs.com/package/delete): Delete files and folders and any intermediate directories if they exist (sync and async). | [homepage](https://github.com/jonschlinkert/delete) | ||
* [fs-utils](https://www.npmjs.com/package/fs-utils): fs extras and utilities to extend the node.js file system module. Used in Assemble and… [more](https://www.npmjs.com/package/fs-utils) | [homepage](https://github.com/assemble/fs-utils) | ||
* [matched](https://www.npmjs.com/package/matched): Adds array support to node-glob, sync and async. Also supports tilde expansion (user home) and… [more](https://www.npmjs.com/package/matched) | [homepage](https://github.com/jonschlinkert/matched) | ||
* [copy](https://www.npmjs.com/package/copy): Copy files or directories using globs. | [homepage](https://github.com/jonschlinkert/copy "Copy files or directories using globs.") | ||
* [delete](https://www.npmjs.com/package/delete): Delete files and folders and any intermediate directories if they exist (sync and async). | [homepage](https://github.com/jonschlinkert/delete "Delete files and folders and any intermediate directories if they exist (sync and async).") | ||
* [fs-utils](https://www.npmjs.com/package/fs-utils): fs extras and utilities to extend the node.js file system module. Used in Assemble and… [more](https://github.com/assemble/fs-utils) | [homepage](https://github.com/assemble/fs-utils "fs extras and utilities to extend the node.js file system module. Used in Assemble and many other projects.") | ||
* [matched](https://www.npmjs.com/package/matched): Adds array support to node-glob, sync and async. Also supports tilde expansion (user home) and… [more](https://github.com/jonschlinkert/matched) | [homepage](https://github.com/jonschlinkert/matched "Adds array support to node-glob, sync and async. Also supports tilde expansion (user home) and resolving to global npm modules.") | ||
## Contributing | ||
### Contributing | ||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/delete-empty/issues/new). | ||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). | ||
## Building docs | ||
### Contributors | ||
Generate readme and API documentation with [verb](https://github.com/verbose/verb): | ||
| **Commits** | **Contributor** | | ||
| --- | --- | | ||
| 17 | [jonschlinkert](https://github.com/jonschlinkert) | | ||
| 1 | [svenschoenung](https://github.com/svenschoenung) | | ||
| 1 | [vpalmisano](https://github.com/vpalmisano) | | ||
```sh | ||
$ npm install verb && npm run docs | ||
``` | ||
### Building docs | ||
Or, if [verb](https://github.com/verbose/verb) is installed globally: | ||
_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_ | ||
To generate the readme, run the following command: | ||
```sh | ||
$ verb | ||
$ npm install -g verbose/verb#dev verb-generate-readme && verb | ||
``` | ||
## Running tests | ||
### Running tests | ||
Install dev dependencies: | ||
Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command: | ||
```sh | ||
$ npm install -d && npm test | ||
$ npm install && npm test | ||
``` | ||
## Author | ||
### Author | ||
@@ -103,11 +106,11 @@ **Jon Schlinkert** | ||
* [github/jonschlinkert](https://github.com/jonschlinkert) | ||
* [twitter/jonschlinkert](http://twitter.com/jonschlinkert) | ||
* [twitter/jonschlinkert](https://twitter.com/jonschlinkert) | ||
## License | ||
### License | ||
Copyright © 2016, [Jon Schlinkert](https://github.com/jonschlinkert). | ||
Released under the [MIT license](https://github.com/jonschlinkert/delete-empty/blob/master/LICENSE). | ||
Copyright © 2017, [Jon Schlinkert](https://github.com/jonschlinkert). | ||
Released under the [MIT License](LICENSE). | ||
*** | ||
_This file was generated by [verb](https://github.com/verbose/verb), v0.9.0, on March 24, 2016._ | ||
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.4.2, on February 24, 2017._ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
10027
131
0
112
2
3
1
+ Addedasync-each-series@^1.1.0
+ Addedlog-ok@^0.1.1
+ Addedrelative@^3.0.2
+ Addedrimraf@^2.6.0
+ Addedansi-green@0.1.1(transitive)
+ Addedansi-wrap@0.1.0(transitive)
+ Addedasync-each-series@1.1.0(transitive)
+ Addedisarray@1.0.0(transitive)
+ Addedisobject@2.1.0(transitive)
+ Addedlog-ok@0.1.1(transitive)
+ Addedrelative@3.0.2(transitive)
+ Addedsuccess-symbol@0.1.0(transitive)
- Removedasync@^1.5.0
- Removeddelete@^0.3.2
- Removedlazy-cache@^2.0.1
- Removedmatched@^0.4.1
- Removedarr-union@3.1.0(transitive)
- Removedasync@1.5.2(transitive)
- Removedasync-array-reduce@0.2.1(transitive)
- Removedbluebird@3.7.2(transitive)
- Removeddelete@0.3.2(transitive)
- Removedexpand-tilde@1.2.2(transitive)
- Removedextend-shallow@2.0.1(transitive)
- Removedfs-exists-sync@0.1.0(transitive)
- Removedglobal-modules@0.2.3(transitive)
- Removedglobal-prefix@0.1.5(transitive)
- Removedhas-glob@0.1.1(transitive)
- Removedhomedir-polyfill@1.0.3(transitive)
- Removedini@1.3.8(transitive)
- Removedis-buffer@1.1.6(transitive)
- Removedis-extendable@0.1.1(transitive)
- Removedis-extglob@1.0.0(transitive)
- Removedis-glob@2.0.1(transitive)
- Removedis-valid-glob@0.3.0(transitive)
- Removedis-windows@0.2.0(transitive)
- Removedisexe@2.0.0(transitive)
- Removedkind-of@3.2.2(transitive)
- Removedlazy-cache@1.0.42.0.2(transitive)
- Removedmatched@0.4.4(transitive)
- Removedos-homedir@1.0.2(transitive)
- Removedparse-passwd@1.0.0(transitive)
- Removedresolve-dir@0.1.1(transitive)
- Removedset-getter@0.1.1(transitive)
- Removedto-object-path@0.3.0(transitive)
- Removedwhich@1.3.1(transitive)