@ohos-ports/remove 0.1.5-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,72 @@
1
+ # node-remove
2
+
3
+ Sync and async versions of `rm -r`, handling both files and directories (something astonishingly missing from `fs`).
4
+
5
+ ````js
6
+ var remove = require('remove');
7
+
8
+ // Asynchronous
9
+ remove('/home/esr', function(err){
10
+ if (err) console.error(err);
11
+ else console.log('success!');
12
+ });
13
+
14
+ // Synchronous
15
+ try {
16
+ remove.removeSync('/home/esr');
17
+ console.log('success!');
18
+ } catch (err) {
19
+ console.error(err);
20
+ }
21
+ ````
22
+
23
+
24
+ ## Installation
25
+
26
+ Via [npm](http://npmjs.org/):
27
+
28
+ ````sh
29
+ npm install remove
30
+ ````
31
+
32
+ Or if you want to hack on the source:
33
+
34
+ ````sh
35
+ git clone https://github.com/dsc/node-remove.git
36
+ cd node-remove
37
+ npm link
38
+ ````
39
+
40
+
41
+ ## API
42
+
43
+ ### remove(paths, [options], cb) -> void
44
+ ### remove.removeAsync(paths, [options], cb) -> void
45
+
46
+ Asynchronously and recursively remove files and/or directories.
47
+
48
+ - **paths** *String | Array<String>* — Path or paths to remove.
49
+ - **options** *Object* — Options object:
50
+ - **verbose** : `false` *Boolean* — Log all errors and print each path just before it's removed.
51
+ - **sequential** : `false` *Boolean* — If true, remove the supplied paths sequentially, such that an unsuppressed error would short-circuit further deletes.
52
+ - **ignoreErrors** : `false` *Boolean* — If false, halt as soon as possible after an error occurs and invoke the callback. When operating in `sequential` mode, this implies an error removing the first of several paths would halt before touching the rest. If set, `ignoreErrors` overrides `ignoreMissing`.
53
+ - **ignoreMissing** : `false` *Boolean* — Whether to treat missing paths as errors.
54
+ - **callback** *Function* — Completion callback, invoked with null on success and the error on failure.
55
+
56
+
57
+ ### removeSync(paths, [options]) -> void
58
+
59
+ Synchronously and recursively remove files and/or directories.
60
+
61
+ - **paths** *String | Array<String>* — Path or paths to remove.
62
+ - **options** *Object* — Options (all optional):
63
+ - **verbose** : `false` *Boolean* — Log all errors and print each path just before it's removed.
64
+ - **ignoreErrors** : `false` *Boolean* — If false, halt as soon as possible after an error occurs and invoke the callback. This implies an error removing the first of several paths would halt before touching the rest. If set, `ignoreErrors` overrides `ignoreMissing`.
65
+ - **ignoreMissing** : `false` *Boolean* — Whether to treat missing paths as errors.
66
+
67
+
68
+ ## Feedback
69
+
70
+ Find a bug or want to contribute? Open a ticket on [github](http://github.com/dsc/node-remove).
71
+ You're also welcome to send me email at [dsc@less.ly](mailto:dsc@less.ly?subject=node-remove).
72
+
package/index.js ADDED
@@ -0,0 +1 @@
1
+ module.exports = exports = require('./remove');
package/package.co ADDED
@@ -0,0 +1,23 @@
1
+ name : 'remove'
2
+ version : '0.1.5'
3
+ description : 'Sync and async rm -r.'
4
+ homepage : 'http://github.com/dsc/node-remove'
5
+ keywords : <[ util server files fs rm remove delete recursive ]>
6
+ author : 'David Schoonover <dsc@less.ly> (http://less.ly)'
7
+
8
+ # main : './remove'
9
+ # directories : lib: './lib', bin:'./bin', doc:'./doc', man:'./man'
10
+
11
+ dependencies :
12
+ 'seq' : '>= 0.3.5'
13
+ devDependencies :
14
+ 'coco' : '>= 0.7.0'
15
+ 'expresso' : '>= 0.9.2'
16
+ 'mkdirp' : '>= 0.3.2'
17
+
18
+ scripts : test:'expresso'
19
+ repository : type:'git', url:'git://github.com/dsc/node-remove.git'
20
+ bugs : url:'http://github.com/dsc/node-remove/issues'
21
+
22
+ engine : node:'>=0.6.2'
23
+ license : 'MIT'
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@ohos-ports/remove",
3
+ "version": "0.1.5-beta.0",
4
+ "description": "Sync and async rm -r.",
5
+ "homepage": "http://github.com/dsc/node-remove",
6
+ "keywords": [
7
+ "util",
8
+ "server",
9
+ "files",
10
+ "fs",
11
+ "rm",
12
+ "remove",
13
+ "delete",
14
+ "recursive"
15
+ ],
16
+ "author": "David Schoonover <dsc@less.ly> (http://less.ly)",
17
+ "dependencies": {
18
+ "seq": ">= 0.3.5"
19
+ },
20
+ "devDependencies": {
21
+ "coco": ">= 0.7.0",
22
+ "expresso": ">= 0.9.2",
23
+ "mkdirp": ">= 0.3.2"
24
+ },
25
+ "scripts": {
26
+ "test": "expresso"
27
+ },
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "https://github.com/ohos-ports/ohos-ports.git",
31
+ "directory": "ports/remove/0.1.5"
32
+ },
33
+ "bugs": {
34
+ "url": "https://github.com/ohos-ports/ohos-ports/issues"
35
+ },
36
+ "engine": {
37
+ "node": ">=0.6.2"
38
+ },
39
+ "license": "MIT"
40
+ }
package/remove.co ADDED
@@ -0,0 +1,116 @@
1
+ fs = require 'fs'
2
+ path = require 'path'
3
+ {exists, existsSync} = path
4
+
5
+ Seq = require 'seq'
6
+
7
+
8
+
9
+ /**
10
+ * Asynchronously and recursively remove files and/or directories.
11
+ *
12
+ * @param {String|Array<String>} paths Path or paths to remove.
13
+ * @param {Object} [options] Options:
14
+ * @param {Boolean} [options.verbose=false] Log all errors and print each path
15
+ * just before it's removed.
16
+ * @param {Boolean} [options.sequential=false] If true, remove the supplied
17
+ * paths sequentially, such that an unsuppressed error would short-circuit
18
+ * further deletes.
19
+ * @param {Boolean} [options.ignoreErrors=false] If false, halt as soon as
20
+ * possible after an error occurs and invoke the callback. When operating
21
+ * in `sequential` mode, this implies an error removing the first of several
22
+ * paths would halt before touching the rest. If set, `ignoreErrors` overrides
23
+ * `ignoreMissing`.
24
+ * @param {Boolean} [options.ignoreMissing=false] Whether to treat missing
25
+ * paths as errors.
26
+ * @param {Function} cb Completion callback, invoked with null on success
27
+ * and the error on failure.
28
+ * @returns {void}
29
+ */
30
+ removeAsync = module.exports = exports = \
31
+ function removeAsync (paths=[], options, cb)
32
+ paths = [paths] if typeof paths is 'string'
33
+ if typeof options is 'function'
34
+ [cb, options] = [options, {}]
35
+ if typeof cb is not 'function'
36
+ throw new Error 'Callback must be a function!'
37
+ options = {verbose, ignoreErrors, ignoreMissing} =
38
+ ({-verbose, -sequential, -ignoreErrors, -ignoreMissing} import options)
39
+ # TODO: recurisve? maxdepth?
40
+
41
+ stepMethod = if options.sequential then 'seqEach_' else 'parEach_'
42
+ Seq(paths)[stepMethod] (next_path, p) ->
43
+ console.log "rm -rv #p" if verbose
44
+ Seq()
45
+ .seq fs.lstat, p, Seq
46
+ .seq (stats) ->
47
+ # Files/links can be removed right away, and then move on to the next path
48
+ if stats.isSymbolicLink() or not stats.isDirectory()
49
+ fs.unlink p, next_path
50
+ else
51
+ # ...But directories need to be empty
52
+ fs.readdir p, this
53
+ # Remove children with the same options
54
+ .seq (contents) -> removeAsync contents.map(-> path.join p, it), options, this
55
+ # Finally, kill it
56
+ .seq fs.rmdir, p, Seq
57
+ # And terminate the async chain
58
+ .seq next_path.ok
59
+ # Propagate errors
60
+ .catch (err) -> next_path err
61
+
62
+ # Notify callback!
63
+ .seq -> cb null
64
+ .catch (err) ->
65
+ console.error err if verbose
66
+ return @ok() if ignoreErrors or (ignoreMissing and err.code is 'ENOENT')
67
+ cb err
68
+
69
+ void
70
+
71
+ exports.removeAsync = removeAsync
72
+
73
+
74
+ /**
75
+ * Synchronously and recursively remove files and/or directories.
76
+ *
77
+ * @param {String|Array<String>} paths Path or paths to remove.
78
+ * @param {Object} [options] Options:
79
+ * @param {Boolean} [options.verbose=false] Log all errors and print each path
80
+ * just before it's removed.
81
+ * @param {Boolean} [options.ignoreErrors=false] If false, halt as soon as
82
+ * possible after an error occurs and invoke the callback. This implies an error
83
+ * removing the first of several paths would halt before touching the rest. If
84
+ * set, `ignoreErrors` overrides `ignoreMissing`.
85
+ * @param {Boolean} [options.ignoreMissing=false] Whether to treat missing
86
+ * paths as errors.
87
+ * @returns {void}
88
+ */
89
+ removeSync = exports.removeSync = \
90
+ function removeSync(paths=[], options={})
91
+ paths = [paths] if typeof paths is 'string'
92
+ options = {verbose, ignoreErrors, ignoreMissing} =
93
+ ({-verbose, -ignoreErrors, -ignoreMissing} import options)
94
+
95
+ for p of paths
96
+ console.log "rm -rv #p" if verbose
97
+ try
98
+ stats = fs.lstatSync p
99
+
100
+ # files can be removed right away
101
+ if stats.isSymbolicLink() or not stats.isDirectory()
102
+ fs.unlinkSync p
103
+ else
104
+ # directories need to be empty
105
+ fs.readdirSync p .forEach -> removeSync path.join(p,it), options
106
+
107
+ # finally, kill it
108
+ fs.rmdirSync p
109
+ catch err
110
+ console.error err if verbose
111
+ if ignoreErrors or (ignoreMissing and err.code is 'ENOENT')
112
+ continue
113
+ else
114
+ throw err
115
+ void
116
+
package/remove.js ADDED
@@ -0,0 +1,144 @@
1
+ var fs, path, exists, existsSync, Seq, exports, removeAsync, removeSync;
2
+ fs = require('fs');
3
+ path = require('path');
4
+ exists = path.exists, existsSync = path.existsSync;
5
+ Seq = require('seq');
6
+ /**
7
+ * Asynchronously and recursively remove files and/or directories.
8
+ *
9
+ * @param {String|Array<String>} paths Path or paths to remove.
10
+ * @param {Object} [options] Options:
11
+ * @param {Boolean} [options.verbose=false] Log all errors and print each path
12
+ * just before it's removed.
13
+ * @param {Boolean} [options.sequential=false] If true, remove the supplied
14
+ * paths sequentially, such that an unsuppressed error would short-circuit
15
+ * further deletes.
16
+ * @param {Boolean} [options.ignoreErrors=false] If false, halt as soon as
17
+ * possible after an error occurs and invoke the callback. When operating
18
+ * in `sequential` mode, this implies an error removing the first of several
19
+ * paths would halt before touching the rest. If set, `ignoreErrors` overrides
20
+ * `ignoreMissing`.
21
+ * @param {Boolean} [options.ignoreMissing=false] Whether to treat missing
22
+ * paths as errors.
23
+ * @param {Function} cb Completion callback, invoked with null on success
24
+ * and the error on failure.
25
+ * @returns {void}
26
+ */
27
+ removeAsync = module.exports = exports = (function(){
28
+ function removeAsync(paths, options, cb){
29
+ var verbose, ignoreErrors, ignoreMissing, stepMethod, __ref;
30
+ paths == null && (paths = []);
31
+ if (typeof paths === 'string') {
32
+ paths = [paths];
33
+ }
34
+ if (typeof options === 'function') {
35
+ __ref = [options, {}], cb = __ref[0], options = __ref[1];
36
+ }
37
+ if (typeof cb !== 'function') {
38
+ throw new Error('Callback must be a function!');
39
+ }
40
+ options = (__ref = __import({
41
+ verbose: false,
42
+ sequential: false,
43
+ ignoreErrors: false,
44
+ ignoreMissing: false
45
+ }, options), verbose = __ref.verbose, ignoreErrors = __ref.ignoreErrors, ignoreMissing = __ref.ignoreMissing, __ref);
46
+ stepMethod = options.sequential ? 'seqEach_' : 'parEach_';
47
+ Seq(paths)[stepMethod](function(next_path, p){
48
+ if (verbose) {
49
+ console.log("rm -rv " + p);
50
+ }
51
+ return Seq().seq(fs.lstat, p, Seq).seq(function(stats){
52
+ if (stats.isSymbolicLink() || !stats.isDirectory()) {
53
+ return fs.unlink(p, next_path);
54
+ } else {
55
+ return fs.readdir(p, this);
56
+ }
57
+ }).seq(function(contents){
58
+ return removeAsync(contents.map(function(it){
59
+ return path.join(p, it);
60
+ }), options, this);
61
+ }).seq(fs.rmdir, p, Seq).seq(next_path.ok)['catch'](function(err){
62
+ if (ignoreErrors || (ignoreMissing && err.code === 'ENOENT')) {
63
+ return next_path.ok();
64
+ }
65
+ return next_path(err);
66
+ });
67
+ }).seq(function(){
68
+ return cb(null);
69
+ })['catch'](function(err){
70
+ if (verbose) {
71
+ console.error(err);
72
+ }
73
+ if (ignoreErrors || (ignoreMissing && err.code === 'ENOENT')) {
74
+ return cb(null);
75
+ }
76
+ return cb(err);
77
+ });
78
+ }
79
+ return removeAsync;
80
+ }());
81
+ exports.removeAsync = removeAsync;
82
+ /**
83
+ * Synchronously and recursively remove files and/or directories.
84
+ *
85
+ * @param {String|Array<String>} paths Path or paths to remove.
86
+ * @param {Object} [options] Options:
87
+ * @param {Boolean} [options.verbose=false] Log all errors and print each path
88
+ * just before it's removed.
89
+ * @param {Boolean} [options.ignoreErrors=false] If false, halt as soon as
90
+ * possible after an error occurs and invoke the callback. This implies an error
91
+ * removing the first of several paths would halt before touching the rest. If
92
+ * set, `ignoreErrors` overrides `ignoreMissing`.
93
+ * @param {Boolean} [options.ignoreMissing=false] Whether to treat missing
94
+ * paths as errors.
95
+ * @returns {void}
96
+ */
97
+ removeSync = exports.removeSync = (function(){
98
+ function removeSync(paths, options){
99
+ var verbose, ignoreErrors, ignoreMissing, p, stats, __ref, __i, __len;
100
+ paths == null && (paths = []);
101
+ options == null && (options = {});
102
+ if (typeof paths === 'string') {
103
+ paths = [paths];
104
+ }
105
+ options = (__ref = __import({
106
+ verbose: false,
107
+ ignoreErrors: false,
108
+ ignoreMissing: false
109
+ }, options), verbose = __ref.verbose, ignoreErrors = __ref.ignoreErrors, ignoreMissing = __ref.ignoreMissing, __ref);
110
+ for (__i = 0, __len = paths.length; __i < __len; ++__i) {
111
+ p = paths[__i];
112
+ if (verbose) {
113
+ console.log("rm -rv " + p);
114
+ }
115
+ try {
116
+ stats = fs.lstatSync(p);
117
+ if (stats.isSymbolicLink() || !stats.isDirectory()) {
118
+ fs.unlinkSync(p);
119
+ } else {
120
+ fs.readdirSync(p).forEach(__fn);
121
+ fs.rmdirSync(p);
122
+ }
123
+ } catch (err) {
124
+ if (verbose) {
125
+ console.error(err);
126
+ }
127
+ if (ignoreErrors || (ignoreMissing && err.code === 'ENOENT')) {
128
+ continue;
129
+ } else {
130
+ throw err;
131
+ }
132
+ }
133
+ }
134
+ function __fn(it){
135
+ return removeSync(path.join(p, it), options);
136
+ }
137
+ }
138
+ return removeSync;
139
+ }());
140
+ function __import(obj, src){
141
+ var own = {}.hasOwnProperty;
142
+ for (var key in src) if (own.call(src, key)) obj[key] = src[key];
143
+ return obj;
144
+ }
package/test.co ADDED
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env coco
2
+ fs = require 'fs'
3
+ path = require 'path'
4
+ Seq = require 'seq'
5
+ mkdirp = require 'mkdirp'
6
+
7
+ {removeAsync, removeSync} = require 'remove'
8
+
9
+
10
+ touch = (f, cb) ->
11
+ return cb null if path.existsSync f
12
+ fs.writeFile f, '', 'utf8', cb
13
+
14
+ setup_tests = (cb) ->
15
+ Seq()
16
+ .seq mkdirp, 'tmp/d1', 8r755, Seq
17
+ .set <[ tmp/f1 tmp/f2 tmp/d1/f3 tmp/d1/f4 ]>
18
+ .parEach -> touch it, this
19
+ .seq mkdirp, 'tmp/d2/d3', 8r755, Seq
20
+ .set <[ tmp/d2/f5 tmp/d2/f6 tmp/d2/d3/f7 tmp/d2/d3/f8 ]>
21
+ .parEach -> touch it, this
22
+ .seq mkdirp, 'tmp/d4/d5/d6', 8r755, Seq
23
+ .set <[ tmp/d4/d5/d6/f9 tmp/d4/d5/d6/f10 tmp/d4/d5/d6/f11 tmp/d4/d5/d6/f12 ]>
24
+ .parEach -> touch it, this
25
+ .seq mkdirp, 'tmp/d7', 8r755, Seq
26
+ .seq -> cb()
27
+
28
+
29
+ ###
30
+
31
+ console.log '\n### removeSync Tests ###'
32
+ <- setup_tests
33
+
34
+ console.log "\nremoveSync <[ tmp/f1 tmp/d1 tmp/f2 ]>"
35
+ removeSync <[ tmp/f1 tmp/d1 tmp/f2 ]>, {+verbose}
36
+
37
+ console.log "\nremoveSync 'tmp/d2'"
38
+ removeSync 'tmp/d2', {+verbose}
39
+
40
+ console.log "\nremoveSync <[ tmp/d4 tmp/d7 ]>"
41
+ removeSync <[ tmp/d4 tmp/d7 ]>, {+verbose}
42
+
43
+ contents <- fs.readdir 'tmp'
44
+ throw new Error("Failed to remove all files: #{contents.join ', '}") if contents?.length
45
+
46
+
47
+ ###
48
+
49
+ console.log '\n### removeAsync Tests ###'
50
+ <- setup_tests
51
+
52
+ console.log "\nremoveAsync <[ tmp/f1 tmp/d1 tmp/f2 ]>"
53
+ err <- removeAsync <[ tmp/f1 tmp/d1 tmp/f2 ]>, {+verbose}
54
+ throw err if err
55
+
56
+ console.log "\nremoveAsync 'tmp/d2'"
57
+ err <- removeAsync 'tmp/d2', {+verbose}
58
+ throw err if err
59
+
60
+ console.log "\nremoveAsync <[ tmp/d4 tmp/d7 ]>"
61
+ err <- removeAsync <[ tmp/d4 tmp/d7 ]>, {+verbose}
62
+ throw err if err
63
+
64
+ contents <- fs.readdir 'tmp'
65
+ throw new Error("Failed to remove all files: #{contents.join ', '}") if contents?.length
66
+