rimraf 2.7.1 → 3.0.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.
Files changed (3) hide show
  1. package/bin.js +41 -23
  2. package/package.json +2 -2
  3. package/rimraf.js +67 -71
package/bin.js CHANGED
@@ -1,11 +1,24 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- var rimraf = require('./')
3
+ const rimraf = require('./')
4
4
 
5
- var help = false
6
- var dashdash = false
7
- var noglob = false
8
- var args = process.argv.slice(2).filter(function(arg) {
5
+ const path = require('path')
6
+
7
+ const isRoot = arg => /^(\/|[a-zA-Z]:\\)$/.test(path.resolve(arg))
8
+ const filterOutRoot = arg => {
9
+ const ok = preserveRoot === false || !isRoot(arg)
10
+ if (!ok) {
11
+ console.error(`refusing to remove ${arg}`)
12
+ console.error('Set --no-preserve-root to allow this')
13
+ }
14
+ return ok
15
+ }
16
+
17
+ let help = false
18
+ let dashdash = false
19
+ let noglob = false
20
+ let preserveRoot = true
21
+ const args = process.argv.slice(2).filter(arg => {
9
22
  if (dashdash)
10
23
  return !!arg
11
24
  else if (arg === '--')
@@ -16,35 +29,40 @@ var args = process.argv.slice(2).filter(function(arg) {
16
29
  noglob = false
17
30
  else if (arg.match(/^(-+|\/)(h(elp)?|\?)$/))
18
31
  help = true
32
+ else if (arg === '--preserve-root')
33
+ preserveRoot = true
34
+ else if (arg === '--no-preserve-root')
35
+ preserveRoot = false
19
36
  else
20
37
  return !!arg
21
- })
38
+ }).filter(arg => !preserveRoot || filterOutRoot(arg))
39
+
40
+ const go = n => {
41
+ if (n >= args.length)
42
+ return
43
+ const options = noglob ? { glob: false } : {}
44
+ rimraf(args[n], options, er => {
45
+ if (er)
46
+ throw er
47
+ go(n+1)
48
+ })
49
+ }
22
50
 
23
51
  if (help || args.length === 0) {
24
52
  // If they didn't ask for help, then this is not a "success"
25
- var log = help ? console.log : console.error
53
+ const log = help ? console.log : console.error
26
54
  log('Usage: rimraf <path> [<path> ...]')
27
55
  log('')
28
56
  log(' Deletes all files and folders at "path" recursively.')
29
57
  log('')
30
58
  log('Options:')
31
59
  log('')
32
- log(' -h, --help Display this usage info')
33
- log(' -G, --no-glob Do not expand glob patterns in arguments')
34
- log(' -g, --glob Expand glob patterns in arguments (default)')
60
+ log(' -h, --help Display this usage info')
61
+ log(' -G, --no-glob Do not expand glob patterns in arguments')
62
+ log(' -g, --glob Expand glob patterns in arguments (default)')
63
+ log(' --preserve-root Do not remove \'/\' (default)')
64
+ log(' --no-preserve-root Do not treat \'/\' specially')
65
+ log(' -- Stop parsing flags')
35
66
  process.exit(help ? 0 : 1)
36
67
  } else
37
68
  go(0)
38
-
39
- function go (n) {
40
- if (n >= args.length)
41
- return
42
- var options = {}
43
- if (noglob)
44
- options = { glob: false }
45
- rimraf(args[n], options, function (er) {
46
- if (er)
47
- throw er
48
- go(n+1)
49
- })
50
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rimraf",
3
- "version": "2.7.1",
3
+ "version": "3.0.0",
4
4
  "main": "rimraf.js",
5
5
  "description": "A deep deletion module for node (like `rm -rf`)",
6
6
  "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)",
@@ -9,7 +9,7 @@
9
9
  "scripts": {
10
10
  "preversion": "npm test",
11
11
  "postversion": "npm publish",
12
- "postpublish": "git push origin --all; git push origin --tags",
12
+ "postpublish": "git push origin --follow-tags",
13
13
  "test": "tap test/*.js"
14
14
  },
15
15
  "bin": "./bin.js",
package/rimraf.js CHANGED
@@ -1,29 +1,25 @@
1
- module.exports = rimraf
2
- rimraf.sync = rimrafSync
3
-
4
- var assert = require("assert")
5
- var path = require("path")
6
- var fs = require("fs")
7
- var glob = undefined
1
+ const assert = require("assert")
2
+ const path = require("path")
3
+ const fs = require("fs")
4
+ let glob = undefined
8
5
  try {
9
6
  glob = require("glob")
10
7
  } catch (_err) {
11
8
  // treat glob as optional.
12
9
  }
13
- var _0666 = parseInt('666', 8)
14
10
 
15
- var defaultGlobOpts = {
11
+ const defaultGlobOpts = {
16
12
  nosort: true,
17
13
  silent: true
18
14
  }
19
15
 
20
16
  // for EMFILE handling
21
- var timeout = 0
17
+ let timeout = 0
22
18
 
23
- var isWindows = (process.platform === "win32")
19
+ const isWindows = (process.platform === "win32")
24
20
 
25
- function defaults (options) {
26
- var methods = [
21
+ const defaults = options => {
22
+ const methods = [
27
23
  'unlink',
28
24
  'chmod',
29
25
  'stat',
@@ -31,7 +27,7 @@ function defaults (options) {
31
27
  'rmdir',
32
28
  'readdir'
33
29
  ]
34
- methods.forEach(function(m) {
30
+ methods.forEach(m => {
35
31
  options[m] = options[m] || fs[m]
36
32
  m = m + 'Sync'
37
33
  options[m] = options[m] || fs[m]
@@ -49,7 +45,7 @@ function defaults (options) {
49
45
  options.glob = options.glob || defaultGlobOpts
50
46
  }
51
47
 
52
- function rimraf (p, options, cb) {
48
+ const rimraf = (p, options, cb) => {
53
49
  if (typeof options === 'function') {
54
50
  cb = options
55
51
  options = {}
@@ -63,27 +59,17 @@ function rimraf (p, options, cb) {
63
59
 
64
60
  defaults(options)
65
61
 
66
- var busyTries = 0
67
- var errState = null
68
- var n = 0
69
-
70
- if (options.disableGlob || !glob.hasMagic(p))
71
- return afterGlob(null, [p])
72
-
73
- options.lstat(p, function (er, stat) {
74
- if (!er)
75
- return afterGlob(null, [p])
62
+ let busyTries = 0
63
+ let errState = null
64
+ let n = 0
76
65
 
77
- glob(p, options.glob, afterGlob)
78
- })
79
-
80
- function next (er) {
66
+ const next = (er) => {
81
67
  errState = errState || er
82
68
  if (--n === 0)
83
69
  cb(errState)
84
70
  }
85
71
 
86
- function afterGlob (er, results) {
72
+ const afterGlob = (er, results) => {
87
73
  if (er)
88
74
  return cb(er)
89
75
 
@@ -91,24 +77,19 @@ function rimraf (p, options, cb) {
91
77
  if (n === 0)
92
78
  return cb()
93
79
 
94
- results.forEach(function (p) {
95
- rimraf_(p, options, function CB (er) {
80
+ results.forEach(p => {
81
+ const CB = (er) => {
96
82
  if (er) {
97
83
  if ((er.code === "EBUSY" || er.code === "ENOTEMPTY" || er.code === "EPERM") &&
98
84
  busyTries < options.maxBusyTries) {
99
85
  busyTries ++
100
- var time = busyTries * 100
101
86
  // try again, with the same exact callback as this one.
102
- return setTimeout(function () {
103
- rimraf_(p, options, CB)
104
- }, time)
87
+ return setTimeout(() => rimraf_(p, options, CB), busyTries * 100)
105
88
  }
106
89
 
107
90
  // this one won't happen if graceful-fs is used.
108
91
  if (er.code === "EMFILE" && timeout < options.emfileWait) {
109
- return setTimeout(function () {
110
- rimraf_(p, options, CB)
111
- }, timeout ++)
92
+ return setTimeout(() => rimraf_(p, options, CB), timeout ++)
112
93
  }
113
94
 
114
95
  // already gone
@@ -117,9 +98,21 @@ function rimraf (p, options, cb) {
117
98
 
118
99
  timeout = 0
119
100
  next(er)
120
- })
101
+ }
102
+ rimraf_(p, options, CB)
121
103
  })
122
104
  }
105
+
106
+ if (options.disableGlob || !glob.hasMagic(p))
107
+ return afterGlob(null, [p])
108
+
109
+ options.lstat(p, (er, stat) => {
110
+ if (!er)
111
+ return afterGlob(null, [p])
112
+
113
+ glob(p, options.glob, afterGlob)
114
+ })
115
+
123
116
  }
124
117
 
125
118
  // Two possible strategies.
@@ -133,14 +126,14 @@ function rimraf (p, options, cb) {
133
126
  //
134
127
  // If anyone ever complains about this, then I guess the strategy could
135
128
  // be made configurable somehow. But until then, YAGNI.
136
- function rimraf_ (p, options, cb) {
129
+ const rimraf_ = (p, options, cb) => {
137
130
  assert(p)
138
131
  assert(options)
139
132
  assert(typeof cb === 'function')
140
133
 
141
134
  // sunos lets the root user unlink directories, which is... weird.
142
135
  // so we have to lstat here and make sure it's not a dir.
143
- options.lstat(p, function (er, st) {
136
+ options.lstat(p, (er, st) => {
144
137
  if (er && er.code === "ENOENT")
145
138
  return cb(null)
146
139
 
@@ -151,7 +144,7 @@ function rimraf_ (p, options, cb) {
151
144
  if (st && st.isDirectory())
152
145
  return rmdir(p, options, er, cb)
153
146
 
154
- options.unlink(p, function (er) {
147
+ options.unlink(p, er => {
155
148
  if (er) {
156
149
  if (er.code === "ENOENT")
157
150
  return cb(null)
@@ -167,18 +160,18 @@ function rimraf_ (p, options, cb) {
167
160
  })
168
161
  }
169
162
 
170
- function fixWinEPERM (p, options, er, cb) {
163
+ const fixWinEPERM = (p, options, er, cb) => {
171
164
  assert(p)
172
165
  assert(options)
173
166
  assert(typeof cb === 'function')
174
167
  if (er)
175
168
  assert(er instanceof Error)
176
169
 
177
- options.chmod(p, _0666, function (er2) {
170
+ options.chmod(p, 0o666, er2 => {
178
171
  if (er2)
179
172
  cb(er2.code === "ENOENT" ? null : er)
180
173
  else
181
- options.stat(p, function(er3, stats) {
174
+ options.stat(p, (er3, stats) => {
182
175
  if (er3)
183
176
  cb(er3.code === "ENOENT" ? null : er)
184
177
  else if (stats.isDirectory())
@@ -189,14 +182,14 @@ function fixWinEPERM (p, options, er, cb) {
189
182
  })
190
183
  }
191
184
 
192
- function fixWinEPERMSync (p, options, er) {
185
+ const fixWinEPERMSync = (p, options, er) => {
193
186
  assert(p)
194
187
  assert(options)
195
188
  if (er)
196
189
  assert(er instanceof Error)
197
190
 
198
191
  try {
199
- options.chmodSync(p, _0666)
192
+ options.chmodSync(p, 0o666)
200
193
  } catch (er2) {
201
194
  if (er2.code === "ENOENT")
202
195
  return
@@ -204,8 +197,9 @@ function fixWinEPERMSync (p, options, er) {
204
197
  throw er
205
198
  }
206
199
 
200
+ let stats
207
201
  try {
208
- var stats = options.statSync(p)
202
+ stats = options.statSync(p)
209
203
  } catch (er3) {
210
204
  if (er3.code === "ENOENT")
211
205
  return
@@ -219,7 +213,7 @@ function fixWinEPERMSync (p, options, er) {
219
213
  options.unlinkSync(p)
220
214
  }
221
215
 
222
- function rmdir (p, options, originalEr, cb) {
216
+ const rmdir = (p, options, originalEr, cb) => {
223
217
  assert(p)
224
218
  assert(options)
225
219
  if (originalEr)
@@ -229,7 +223,7 @@ function rmdir (p, options, originalEr, cb) {
229
223
  // try to rmdir first, and only readdir on ENOTEMPTY or EEXIST (SunOS)
230
224
  // if we guessed wrong, and it's not a directory, then
231
225
  // raise the original error.
232
- options.rmdir(p, function (er) {
226
+ options.rmdir(p, er => {
233
227
  if (er && (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM"))
234
228
  rmkids(p, options, cb)
235
229
  else if (er && er.code === "ENOTDIR")
@@ -239,20 +233,20 @@ function rmdir (p, options, originalEr, cb) {
239
233
  })
240
234
  }
241
235
 
242
- function rmkids(p, options, cb) {
236
+ const rmkids = (p, options, cb) => {
243
237
  assert(p)
244
238
  assert(options)
245
239
  assert(typeof cb === 'function')
246
240
 
247
- options.readdir(p, function (er, files) {
241
+ options.readdir(p, (er, files) => {
248
242
  if (er)
249
243
  return cb(er)
250
- var n = files.length
244
+ let n = files.length
251
245
  if (n === 0)
252
246
  return options.rmdir(p, cb)
253
- var errState
254
- files.forEach(function (f) {
255
- rimraf(path.join(p, f), options, function (er) {
247
+ let errState
248
+ files.forEach(f => {
249
+ rimraf(path.join(p, f), options, er => {
256
250
  if (errState)
257
251
  return
258
252
  if (er)
@@ -267,7 +261,7 @@ function rmkids(p, options, cb) {
267
261
  // this looks simpler, and is strictly *faster*, but will
268
262
  // tie up the JavaScript thread and fail on excessively
269
263
  // deep directory trees.
270
- function rimrafSync (p, options) {
264
+ const rimrafSync = (p, options) => {
271
265
  options = options || {}
272
266
  defaults(options)
273
267
 
@@ -276,7 +270,7 @@ function rimrafSync (p, options) {
276
270
  assert(options, 'rimraf: missing options')
277
271
  assert.equal(typeof options, 'object', 'rimraf: options should be object')
278
272
 
279
- var results
273
+ let results
280
274
 
281
275
  if (options.disableGlob || !glob.hasMagic(p)) {
282
276
  results = [p]
@@ -292,11 +286,12 @@ function rimrafSync (p, options) {
292
286
  if (!results.length)
293
287
  return
294
288
 
295
- for (var i = 0; i < results.length; i++) {
296
- var p = results[i]
289
+ for (let i = 0; i < results.length; i++) {
290
+ const p = results[i]
297
291
 
292
+ let st
298
293
  try {
299
- var st = options.lstatSync(p)
294
+ st = options.lstatSync(p)
300
295
  } catch (er) {
301
296
  if (er.code === "ENOENT")
302
297
  return
@@ -325,7 +320,7 @@ function rimrafSync (p, options) {
325
320
  }
326
321
  }
327
322
 
328
- function rmdirSync (p, options, originalEr) {
323
+ const rmdirSync = (p, options, originalEr) => {
329
324
  assert(p)
330
325
  assert(options)
331
326
  if (originalEr)
@@ -343,12 +338,10 @@ function rmdirSync (p, options, originalEr) {
343
338
  }
344
339
  }
345
340
 
346
- function rmkidsSync (p, options) {
341
+ const rmkidsSync = (p, options) => {
347
342
  assert(p)
348
343
  assert(options)
349
- options.readdirSync(p).forEach(function (f) {
350
- rimrafSync(path.join(p, f), options)
351
- })
344
+ options.readdirSync(p).forEach(f => rimrafSync(path.join(p, f), options))
352
345
 
353
346
  // We only end up here once we got ENOTEMPTY at least once, and
354
347
  // at this point, we are guaranteed to have removed all the kids.
@@ -356,12 +349,12 @@ function rmkidsSync (p, options) {
356
349
  // try really hard to delete stuff on windows, because it has a
357
350
  // PROFOUNDLY annoying habit of not closing handles promptly when
358
351
  // files are deleted, resulting in spurious ENOTEMPTY errors.
359
- var retries = isWindows ? 100 : 1
360
- var i = 0
352
+ const retries = isWindows ? 100 : 1
353
+ let i = 0
361
354
  do {
362
- var threw = true
355
+ let threw = true
363
356
  try {
364
- var ret = options.rmdirSync(p, options)
357
+ const ret = options.rmdirSync(p, options)
365
358
  threw = false
366
359
  return ret
367
360
  } finally {
@@ -370,3 +363,6 @@ function rmkidsSync (p, options) {
370
363
  }
371
364
  } while (true)
372
365
  }
366
+
367
+ module.exports = rimraf
368
+ rimraf.sync = rimrafSync