diff options
Diffstat (limited to 'node_modules/rimraf')
-rw-r--r-- | node_modules/rimraf/AUTHORS | 5 | ||||
-rw-r--r-- | node_modules/rimraf/LICENSE | 23 | ||||
-rw-r--r-- | node_modules/rimraf/README.md | 32 | ||||
-rw-r--r-- | node_modules/rimraf/fiber.js | 86 | ||||
-rw-r--r-- | node_modules/rimraf/package.json | 9 | ||||
-rw-r--r-- | node_modules/rimraf/rimraf.js | 145 |
6 files changed, 300 insertions, 0 deletions
diff --git a/node_modules/rimraf/AUTHORS b/node_modules/rimraf/AUTHORS new file mode 100644 index 000000000..008cbe7dd --- /dev/null +++ b/node_modules/rimraf/AUTHORS @@ -0,0 +1,5 @@ +# Authors sorted by whether or not they're me. +Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me) +Wayne Larsen <wayne@larsen.st> (http://github.com/wvl) +ritch <skawful@gmail.com> +Marcel Laverdet diff --git a/node_modules/rimraf/LICENSE b/node_modules/rimraf/LICENSE new file mode 100644 index 000000000..05a401094 --- /dev/null +++ b/node_modules/rimraf/LICENSE @@ -0,0 +1,23 @@ +Copyright 2009, 2010, 2011 Isaac Z. Schlueter. +All rights reserved. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/rimraf/README.md b/node_modules/rimraf/README.md new file mode 100644 index 000000000..99983dc43 --- /dev/null +++ b/node_modules/rimraf/README.md @@ -0,0 +1,32 @@ +A `rm -rf` for node. + +Install with `npm install rimraf`, or just drop rimraf.js somewhere. + +## API + +`rimraf(f, [options,] callback)` + +The callback will be called with an error if there is one. Certain +errors are handled for you: + +* `EBUSY` - rimraf will back off a maximum of opts.maxBusyTries times + before giving up. +* `EMFILE` - If too many file descriptors get opened, rimraf will + patiently wait until more become available. + +## Options + +The options object is optional. These fields are respected: + +* `maxBusyTries` - The number of times to retry a file or folder in the + event of an `EBUSY` error. The default is 3. +* `gently` - If provided a `gently` path, then rimraf will only delete + files and folders that are beneath this path, and only delete symbolic + links that point to a place within this path. (This is very important + to npm's use-case, and shows rimraf's pedigree.) + + +## rimraf.sync + +It can remove stuff synchronously, too. But that's not so good. Use +the async API. It's better. diff --git a/node_modules/rimraf/fiber.js b/node_modules/rimraf/fiber.js new file mode 100644 index 000000000..8812a6b44 --- /dev/null +++ b/node_modules/rimraf/fiber.js @@ -0,0 +1,86 @@ +// fiber/future port originally written by Marcel Laverdet +// https://gist.github.com/1131093 +// I updated it to bring to feature parity with cb version. +// The bugs are probably mine, not Marcel's. +// -- isaacs + +var path = require('path') + , fs = require('fs') + , Future = require('fibers/future') + +// Create future-returning fs functions +var fs2 = {} +for (var ii in fs) { + fs2[ii] = Future.wrap(fs[ii]) +} + +// Return a future which just pauses for a certain amount of time + +function timer (ms) { + var future = new Future + setTimeout(function () { + future.return() + }, ms) + return future +} + +function realish (p) { + return path.resolve(path.dirname(fs2.readlink(p))) +} + +// for EMFILE backoff. +var timeout = 0 + , EMFILE_MAX = 1000 + +function rimraf_ (p, opts) { + opts = opts || {} + opts.maxBusyTries = opts.maxBusyTries || 3 + if (opts.gently) opts.gently = path.resolve(opts.gently) + var busyTries = 0 + + // exits by throwing or returning. + // loops on handled errors. + while (true) { + try { + var stat = fs2.lstat(p).wait() + + // check to make sure that symlinks are ours. + if (opts.gently) { + var rp = stat.isSymbolicLink() ? realish(p) : path.resolve(p) + if (rp.indexOf(opts.gently) !== 0) { + var er = new Error("Refusing to delete: "+p+" not in "+opts.gently) + er.errno = require("constants").EEXIST + er.code = "EEXIST" + er.path = p + throw er + } + } + + if (!stat.isDirectory()) return fs2.unlink(p).wait() + + var rimrafs = fs2.readdir(p).wait().map(function (file) { + return rimraf(path.join(p, file), opts) + }) + + Future.wait(rimrafs) + fs2.rmdir(p).wait() + timeout = 0 + return + + } catch (er) { + if (er.message.match(/^EMFILE/) && timeout < EMFILE_MAX) { + timer(timeout++).wait() + } else if (er.message.match(/^EBUSY/) + && busyTries < opt.maxBusyTries) { + timer(++busyTries * 100).wait() + } else if (er.message.match(/^ENOENT/)) { + // already gone + return + } else { + throw er + } + } + } +} + +var rimraf = module.exports = rimraf_.future() diff --git a/node_modules/rimraf/package.json b/node_modules/rimraf/package.json new file mode 100644 index 000000000..2b69536ef --- /dev/null +++ b/node_modules/rimraf/package.json @@ -0,0 +1,9 @@ +{"name":"rimraf" +,"version":"1.0.9" +,"main":"rimraf.js" +,"description":"A deep deletion module for node (like `rm -rf`)" +,"author":"Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)" +,"license": + {"type":"MIT", "url": "https://github.com/isaacs/rimraf/raw/master/LICENSE"} +,"repository":"git://github.com/isaacs/rimraf.git" +,"scripts":{"test":"cd test && bash run.sh"}} 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) +} |