rimraf 2.7.0 → 3.0.2
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/CHANGELOG.md +65 -0
- package/bin.js +41 -23
- package/package.json +5 -2
- package/rimraf.js +66 -78
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# v3.0
|
|
2
|
+
|
|
3
|
+
- Add `--preserve-root` option to executable (default true)
|
|
4
|
+
- Drop support for Node.js below version 6
|
|
5
|
+
|
|
6
|
+
# v2.7
|
|
7
|
+
|
|
8
|
+
- Make `glob` an optional dependency
|
|
9
|
+
|
|
10
|
+
# 2.6
|
|
11
|
+
|
|
12
|
+
- Retry on EBUSY on non-windows platforms as well
|
|
13
|
+
- Make `rimraf.sync` 10000% more reliable on Windows
|
|
14
|
+
|
|
15
|
+
# 2.5
|
|
16
|
+
|
|
17
|
+
- Handle Windows EPERM when lstat-ing read-only dirs
|
|
18
|
+
- Add glob option to pass options to glob
|
|
19
|
+
|
|
20
|
+
# 2.4
|
|
21
|
+
|
|
22
|
+
- Add EPERM to delay/retry loop
|
|
23
|
+
- Add `disableGlob` option
|
|
24
|
+
|
|
25
|
+
# 2.3
|
|
26
|
+
|
|
27
|
+
- Make maxBusyTries and emfileWait configurable
|
|
28
|
+
- Handle weird SunOS unlink-dir issue
|
|
29
|
+
- Glob the CLI arg for better Windows support
|
|
30
|
+
|
|
31
|
+
# 2.2
|
|
32
|
+
|
|
33
|
+
- Handle ENOENT properly on Windows
|
|
34
|
+
- Allow overriding fs methods
|
|
35
|
+
- Treat EPERM as indicative of non-empty dir
|
|
36
|
+
- Remove optional graceful-fs dep
|
|
37
|
+
- Consistently return null error instead of undefined on success
|
|
38
|
+
- win32: Treat ENOTEMPTY the same as EBUSY
|
|
39
|
+
- Add `rimraf` binary
|
|
40
|
+
|
|
41
|
+
# 2.1
|
|
42
|
+
|
|
43
|
+
- Fix SunOS error code for a non-empty directory
|
|
44
|
+
- Try rmdir before readdir
|
|
45
|
+
- Treat EISDIR like EPERM
|
|
46
|
+
- Remove chmod
|
|
47
|
+
- Remove lstat polyfill, node 0.7 is not supported
|
|
48
|
+
|
|
49
|
+
# 2.0
|
|
50
|
+
|
|
51
|
+
- Fix myGid call to check process.getgid
|
|
52
|
+
- Simplify the EBUSY backoff logic.
|
|
53
|
+
- Use fs.lstat in node >= 0.7.9
|
|
54
|
+
- Remove gently option
|
|
55
|
+
- remove fiber implementation
|
|
56
|
+
- Delete files that are marked read-only
|
|
57
|
+
|
|
58
|
+
# 1.0
|
|
59
|
+
|
|
60
|
+
- Allow ENOENT in sync method
|
|
61
|
+
- Throw when no callback is provided
|
|
62
|
+
- Make opts.gently an absolute path
|
|
63
|
+
- use 'stat' if 'lstat' is not available
|
|
64
|
+
- Consistent error naming, and rethrow non-ENOENT stat errors
|
|
65
|
+
- add fiber implementation
|
package/bin.js
CHANGED
|
@@ -1,11 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const rimraf = require('./')
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
|
|
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
|
|
33
|
-
log(' -G, --no-glob
|
|
34
|
-
log(' -g, --glob
|
|
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": "
|
|
3
|
+
"version": "3.0.2",
|
|
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 --
|
|
12
|
+
"postpublish": "git push origin --follow-tags",
|
|
13
13
|
"test": "tap test/*.js"
|
|
14
14
|
},
|
|
15
15
|
"bin": "./bin.js",
|
|
@@ -25,5 +25,8 @@
|
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"mkdirp": "^0.5.1",
|
|
27
27
|
"tap": "^12.1.1"
|
|
28
|
+
},
|
|
29
|
+
"funding": {
|
|
30
|
+
"url": "https://github.com/sponsors/isaacs"
|
|
28
31
|
}
|
|
29
32
|
}
|
package/rimraf.js
CHANGED
|
@@ -1,29 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
var assert = require("assert")
|
|
5
|
-
var path = require("path")
|
|
6
|
-
var fs = require("fs")
|
|
1
|
+
const assert = require("assert")
|
|
2
|
+
const path = require("path")
|
|
3
|
+
const fs = require("fs")
|
|
7
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
|
-
|
|
11
|
+
const defaultGlobOpts = {
|
|
16
12
|
nosort: true,
|
|
17
13
|
silent: true
|
|
18
14
|
}
|
|
19
15
|
|
|
20
16
|
// for EMFILE handling
|
|
21
|
-
|
|
17
|
+
let timeout = 0
|
|
22
18
|
|
|
23
|
-
|
|
19
|
+
const isWindows = (process.platform === "win32")
|
|
24
20
|
|
|
25
|
-
|
|
26
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
95
|
-
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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,
|
|
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,
|
|
147
|
+
options.unlink(p, er => {
|
|
155
148
|
if (er) {
|
|
156
149
|
if (er.code === "ENOENT")
|
|
157
150
|
return cb(null)
|
|
@@ -167,18 +160,16 @@ function rimraf_ (p, options, cb) {
|
|
|
167
160
|
})
|
|
168
161
|
}
|
|
169
162
|
|
|
170
|
-
|
|
163
|
+
const fixWinEPERM = (p, options, er, cb) => {
|
|
171
164
|
assert(p)
|
|
172
165
|
assert(options)
|
|
173
166
|
assert(typeof cb === 'function')
|
|
174
|
-
if (er)
|
|
175
|
-
assert(er instanceof Error)
|
|
176
167
|
|
|
177
|
-
options.chmod(p,
|
|
168
|
+
options.chmod(p, 0o666, er2 => {
|
|
178
169
|
if (er2)
|
|
179
170
|
cb(er2.code === "ENOENT" ? null : er)
|
|
180
171
|
else
|
|
181
|
-
options.stat(p,
|
|
172
|
+
options.stat(p, (er3, stats) => {
|
|
182
173
|
if (er3)
|
|
183
174
|
cb(er3.code === "ENOENT" ? null : er)
|
|
184
175
|
else if (stats.isDirectory())
|
|
@@ -189,14 +180,12 @@ function fixWinEPERM (p, options, er, cb) {
|
|
|
189
180
|
})
|
|
190
181
|
}
|
|
191
182
|
|
|
192
|
-
|
|
183
|
+
const fixWinEPERMSync = (p, options, er) => {
|
|
193
184
|
assert(p)
|
|
194
185
|
assert(options)
|
|
195
|
-
if (er)
|
|
196
|
-
assert(er instanceof Error)
|
|
197
186
|
|
|
198
187
|
try {
|
|
199
|
-
options.chmodSync(p,
|
|
188
|
+
options.chmodSync(p, 0o666)
|
|
200
189
|
} catch (er2) {
|
|
201
190
|
if (er2.code === "ENOENT")
|
|
202
191
|
return
|
|
@@ -204,8 +193,9 @@ function fixWinEPERMSync (p, options, er) {
|
|
|
204
193
|
throw er
|
|
205
194
|
}
|
|
206
195
|
|
|
196
|
+
let stats
|
|
207
197
|
try {
|
|
208
|
-
|
|
198
|
+
stats = options.statSync(p)
|
|
209
199
|
} catch (er3) {
|
|
210
200
|
if (er3.code === "ENOENT")
|
|
211
201
|
return
|
|
@@ -219,17 +209,15 @@ function fixWinEPERMSync (p, options, er) {
|
|
|
219
209
|
options.unlinkSync(p)
|
|
220
210
|
}
|
|
221
211
|
|
|
222
|
-
|
|
212
|
+
const rmdir = (p, options, originalEr, cb) => {
|
|
223
213
|
assert(p)
|
|
224
214
|
assert(options)
|
|
225
|
-
if (originalEr)
|
|
226
|
-
assert(originalEr instanceof Error)
|
|
227
215
|
assert(typeof cb === 'function')
|
|
228
216
|
|
|
229
217
|
// try to rmdir first, and only readdir on ENOTEMPTY or EEXIST (SunOS)
|
|
230
218
|
// if we guessed wrong, and it's not a directory, then
|
|
231
219
|
// raise the original error.
|
|
232
|
-
options.rmdir(p,
|
|
220
|
+
options.rmdir(p, er => {
|
|
233
221
|
if (er && (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM"))
|
|
234
222
|
rmkids(p, options, cb)
|
|
235
223
|
else if (er && er.code === "ENOTDIR")
|
|
@@ -239,20 +227,20 @@ function rmdir (p, options, originalEr, cb) {
|
|
|
239
227
|
})
|
|
240
228
|
}
|
|
241
229
|
|
|
242
|
-
|
|
230
|
+
const rmkids = (p, options, cb) => {
|
|
243
231
|
assert(p)
|
|
244
232
|
assert(options)
|
|
245
233
|
assert(typeof cb === 'function')
|
|
246
234
|
|
|
247
|
-
options.readdir(p,
|
|
235
|
+
options.readdir(p, (er, files) => {
|
|
248
236
|
if (er)
|
|
249
237
|
return cb(er)
|
|
250
|
-
|
|
238
|
+
let n = files.length
|
|
251
239
|
if (n === 0)
|
|
252
240
|
return options.rmdir(p, cb)
|
|
253
|
-
|
|
254
|
-
files.forEach(
|
|
255
|
-
rimraf(path.join(p, f), options,
|
|
241
|
+
let errState
|
|
242
|
+
files.forEach(f => {
|
|
243
|
+
rimraf(path.join(p, f), options, er => {
|
|
256
244
|
if (errState)
|
|
257
245
|
return
|
|
258
246
|
if (er)
|
|
@@ -267,7 +255,7 @@ function rmkids(p, options, cb) {
|
|
|
267
255
|
// this looks simpler, and is strictly *faster*, but will
|
|
268
256
|
// tie up the JavaScript thread and fail on excessively
|
|
269
257
|
// deep directory trees.
|
|
270
|
-
|
|
258
|
+
const rimrafSync = (p, options) => {
|
|
271
259
|
options = options || {}
|
|
272
260
|
defaults(options)
|
|
273
261
|
|
|
@@ -276,7 +264,7 @@ function rimrafSync (p, options) {
|
|
|
276
264
|
assert(options, 'rimraf: missing options')
|
|
277
265
|
assert.equal(typeof options, 'object', 'rimraf: options should be object')
|
|
278
266
|
|
|
279
|
-
|
|
267
|
+
let results
|
|
280
268
|
|
|
281
269
|
if (options.disableGlob || !glob.hasMagic(p)) {
|
|
282
270
|
results = [p]
|
|
@@ -292,11 +280,12 @@ function rimrafSync (p, options) {
|
|
|
292
280
|
if (!results.length)
|
|
293
281
|
return
|
|
294
282
|
|
|
295
|
-
for (
|
|
296
|
-
|
|
283
|
+
for (let i = 0; i < results.length; i++) {
|
|
284
|
+
const p = results[i]
|
|
297
285
|
|
|
286
|
+
let st
|
|
298
287
|
try {
|
|
299
|
-
|
|
288
|
+
st = options.lstatSync(p)
|
|
300
289
|
} catch (er) {
|
|
301
290
|
if (er.code === "ENOENT")
|
|
302
291
|
return
|
|
@@ -325,11 +314,9 @@ function rimrafSync (p, options) {
|
|
|
325
314
|
}
|
|
326
315
|
}
|
|
327
316
|
|
|
328
|
-
|
|
317
|
+
const rmdirSync = (p, options, originalEr) => {
|
|
329
318
|
assert(p)
|
|
330
319
|
assert(options)
|
|
331
|
-
if (originalEr)
|
|
332
|
-
assert(originalEr instanceof Error)
|
|
333
320
|
|
|
334
321
|
try {
|
|
335
322
|
options.rmdirSync(p)
|
|
@@ -343,12 +330,10 @@ function rmdirSync (p, options, originalEr) {
|
|
|
343
330
|
}
|
|
344
331
|
}
|
|
345
332
|
|
|
346
|
-
|
|
333
|
+
const rmkidsSync = (p, options) => {
|
|
347
334
|
assert(p)
|
|
348
335
|
assert(options)
|
|
349
|
-
options.readdirSync(p).forEach(
|
|
350
|
-
rimrafSync(path.join(p, f), options)
|
|
351
|
-
})
|
|
336
|
+
options.readdirSync(p).forEach(f => rimrafSync(path.join(p, f), options))
|
|
352
337
|
|
|
353
338
|
// We only end up here once we got ENOTEMPTY at least once, and
|
|
354
339
|
// at this point, we are guaranteed to have removed all the kids.
|
|
@@ -356,12 +341,12 @@ function rmkidsSync (p, options) {
|
|
|
356
341
|
// try really hard to delete stuff on windows, because it has a
|
|
357
342
|
// PROFOUNDLY annoying habit of not closing handles promptly when
|
|
358
343
|
// files are deleted, resulting in spurious ENOTEMPTY errors.
|
|
359
|
-
|
|
360
|
-
|
|
344
|
+
const retries = isWindows ? 100 : 1
|
|
345
|
+
let i = 0
|
|
361
346
|
do {
|
|
362
|
-
|
|
347
|
+
let threw = true
|
|
363
348
|
try {
|
|
364
|
-
|
|
349
|
+
const ret = options.rmdirSync(p, options)
|
|
365
350
|
threw = false
|
|
366
351
|
return ret
|
|
367
352
|
} finally {
|
|
@@ -370,3 +355,6 @@ function rmkidsSync (p, options) {
|
|
|
370
355
|
}
|
|
371
356
|
} while (true)
|
|
372
357
|
}
|
|
358
|
+
|
|
359
|
+
module.exports = rimraf
|
|
360
|
+
rimraf.sync = rimrafSync
|