Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/rimraf/rimraf.js')
-rw-r--r--node_modules/rimraf/rimraf.js145
1 files changed, 145 insertions, 0 deletions
diff --git a/node_modules/rimraf/rimraf.js b/node_modules/rimraf/rimraf.js
new file mode 100644
index 000000000..e8104e9e4
--- /dev/null
+++ b/node_modules/rimraf/rimraf.js
@@ -0,0 +1,145 @@
+module.exports = rimraf
+rimraf.sync = rimrafSync
+
+var path = require("path")
+ , fs
+
+try {
+ // optional dependency
+ fs = require("graceful-fs")
+} catch (er) {
+ fs = require("fs")
+}
+
+var lstat = process.platform === "win32" ? "stat" : "lstat"
+ , lstatSync = lstat + "Sync"
+
+// for EMFILE handling
+var timeout = 0
+ , EMFILE_MAX = 1000
+
+function rimraf (p, opts, cb) {
+ if (typeof opts === "function") cb = opts, opts = {}
+
+ if (!cb) throw new Error("No callback passed to rimraf()")
+ if (!opts) opts = {}
+
+ var busyTries = 0
+ opts.maxBusyTries = opts.maxBusyTries || 3
+
+ if (opts.gently) opts.gently = path.resolve(opts.gently)
+
+ rimraf_(p, opts, function CB (er) {
+ if (er) {
+ if (er.code === "EBUSY" && busyTries < opts.maxBusyTries) {
+ var time = (opts.maxBusyTries - busyTries) * 100
+ busyTries ++
+ // try again, with the same exact callback as this one.
+ return setTimeout(function () {
+ rimraf_(p, opts, CB)
+ })
+ }
+
+ // this one won't happen if graceful-fs is used.
+ if (er.code === "EMFILE" && timeout < EMFILE_MAX) {
+ return setTimeout(function () {
+ rimraf_(p, opts, CB)
+ }, timeout ++)
+ }
+
+ // already gone
+ if (er.code === "ENOENT") er = null
+ }
+
+ timeout = 0
+ cb(er)
+ })
+}
+
+function rimraf_ (p, opts, cb) {
+ fs[lstat](p, function (er, s) {
+ // if the stat fails, then assume it's already gone.
+ if (er) {
+ // already gone
+ if (er.code === "ENOENT") return cb()
+ // some other kind of error, permissions, etc.
+ return cb(er)
+ }
+
+ // don't delete that don't point actually live in the "gently" path
+ if (opts.gently) return clobberTest(p, s, opts, cb)
+ return rm_(p, s, opts, cb)
+ })
+}
+
+function rm_ (p, s, opts, cb) {
+ if (!s.isDirectory()) return fs.unlink(p, cb)
+ fs.readdir(p, function (er, files) {
+ if (er) return cb(er)
+ asyncForEach(files.map(function (f) {
+ return path.join(p, f)
+ }), function (file, cb) {
+ rimraf(file, opts, cb)
+ }, function (er) {
+ if (er) return cb(er)
+ fs.rmdir(p, cb)
+ })
+ })
+}
+
+function clobberTest (p, s, opts, cb) {
+ var gently = opts.gently
+ if (!s.isSymbolicLink()) next(null, path.resolve(p))
+ else realish(p, next)
+
+ function next (er, rp) {
+ if (er) return rm_(p, s, cb)
+ if (rp.indexOf(gently) !== 0) return clobberFail(p, gently, cb)
+ else return rm_(p, s, opts, cb)
+ }
+}
+
+function realish (p, cb) {
+ fs.readlink(p, function (er, r) {
+ if (er) return cb(er)
+ return cb(null, path.resolve(path.dirname(p), r))
+ })
+}
+
+function clobberFail (p, g, cb) {
+ var er = new Error("Refusing to delete: "+p+" not in "+g)
+ , constants = require("constants")
+ er.errno = constants.EEXIST
+ er.code = "EEXIST"
+ er.path = p
+ return cb(er)
+}
+
+function asyncForEach (list, fn, cb) {
+ if (!list.length) cb()
+ var c = list.length
+ , errState = null
+ list.forEach(function (item, i, list) {
+ fn(item, function (er) {
+ if (errState) return
+ if (er) return cb(errState = er)
+ if (-- c === 0) return cb()
+ })
+ })
+}
+
+// this looks simpler, but it will fail with big directory trees,
+// or on slow stupid awful cygwin filesystems
+function rimrafSync (p) {
+ try {
+ var s = fs[lstatSync](p)
+ } catch (er) {
+ if (er.code === "ENOENT") return
+ throw er
+ }
+ if (!s.isDirectory()) return fs.unlinkSync(p)
+ fs.readdirSync(p).forEach(function (f) {
+ rimrafSync(path.join(p, f))
+ })
+ fs.rmdirSync(p)
+}