Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

rimraf@2.1.1

  • Loading branch information...
commit 45ac9b2e8486be4c5945396d519491234e8e89ae 1 parent 8179369
@isaacs isaacs authored
View
21 node_modules/rimraf/package.json
@@ -1,6 +1,6 @@
{
"name": "rimraf",
- "version": "2.0.2",
+ "version": "2.1.1",
"main": "rimraf.js",
"description": "A deep deletion module for node (like `rm -rf`)",
"author": {
@@ -22,11 +22,6 @@
"scripts": {
"test": "cd test && bash run.sh"
},
- "_npmUser": {
- "name": "isaacs",
- "email": "i@izs.me"
- },
- "_id": "rimraf@2.0.2",
"contributors": [
{
"name": "Isaac Z. Schlueter",
@@ -50,16 +45,14 @@
"email": "yosefd@microsoft.com"
}
],
+ "readme": "A `rm -rf` for node.\n\nInstall with `npm install rimraf`, or just drop rimraf.js somewhere.\n\n## API\n\n`rimraf(f, callback)`\n\nThe callback will be called with an error if there is one. Certain\nerrors are handled for you:\n\n* `EBUSY` - rimraf will back off a maximum of opts.maxBusyTries times\n before giving up.\n* `EMFILE` - If too many file descriptors get opened, rimraf will\n patiently wait until more become available.\n\n\n## rimraf.sync\n\nIt can remove stuff synchronously, too. But that's not so good. Use\nthe async API. It's better.\n",
+ "readmeFilename": "README.md",
+ "_id": "rimraf@2.1.1",
"dependencies": {
"graceful-fs": "~1.1"
},
- "devDependencies": {},
- "engines": {
- "node": "*"
+ "dist": {
+ "shasum": "ee9cec7e2d796ef59ceaa5f3a3024c225e630c61"
},
- "_engineSupported": true,
- "_npmVersion": "1.1.24",
- "_nodeVersion": "v0.7.10-pre",
- "_defaultsLoaded": true,
- "_from": "rimraf@2"
+ "_from": "rimraf@2.1.1"
}
View
143 node_modules/rimraf/rimraf.js
@@ -11,28 +11,15 @@ try {
fs = require("fs")
}
-var lstat = "lstat"
-if (process.platform === "win32") {
- // not reliable on windows prior to 0.7.9
- var v = process.version.replace(/^v/, '').split(/\.|-/).map(Number)
- if (v[0] === 0 && (v[1] < 7 || v[1] == 7 && v[2] < 9)) {
- lstat = "stat"
- }
-}
-if (!fs[lstat]) lstat = "stat"
-var lstatSync = lstat + "Sync"
-
// for EMFILE handling
var timeout = 0
exports.EMFILE_MAX = 1000
exports.BUSYTRIES_MAX = 3
function rimraf (p, cb) {
-
if (!cb) throw new Error("No callback passed to rimraf()")
var busyTries = 0
-
rimraf_(p, function CB (er) {
if (er) {
if (er.code === "EBUSY" && busyTries < exports.BUSYTRIES_MAX) {
@@ -60,102 +47,62 @@ function rimraf (p, cb) {
})
}
+// Two possible strategies.
+// 1. Assume it's a file. unlink it, then do the dir stuff on EPERM or EISDIR
+// 2. Assume it's a directory. readdir, then do the file stuff on ENOTDIR
+//
+// Both result in an extra syscall when you guess wrong. However, there
+// are likely far more normal files in the world than directories. This
+// is based on the assumption that a the average number of files per
+// directory is >= 1.
+//
+// If anyone ever complains about this, then I guess the strategy could
+// be made configurable somehow. But until then, YAGNI.
function rimraf_ (p, cb) {
- fs[lstat](p, function (er, s) {
- if (er) {
- // already gone
- if (er.code === "ENOENT") return cb()
- // some other kind of error, permissions, etc.
- return cb(er)
- }
-
- return rm_(p, s, false, cb)
+ fs.unlink(p, function (er) {
+ if (er && er.code === "ENOENT")
+ return cb()
+ if (er && (er.code === "EPERM" || er.code === "EISDIR"))
+ return rmdir(p, cb)
+ return cb(er)
})
}
-
-var myGid = function myGid () {
- var g = process.getuid && process.getgid()
- myGid = function myGid () { return g }
- return g
-}
-
-var myUid = function myUid () {
- var u = process.getuid && process.getuid()
- myUid = function myUid () { return u }
- return u
-}
-
-
-function writable (s) {
- var mode = s.mode || 0777
- , uid = myUid()
- , gid = myGid()
- return (mode & 0002)
- || (gid === s.gid && (mode & 0020))
- || (uid === s.uid && (mode & 0200))
-}
-
-function rm_ (p, s, didWritableCheck, cb) {
- if (!didWritableCheck && !writable(s)) {
- // make file writable
- // user/group/world, doesn't matter at this point
- // since it's about to get nuked.
- return fs.chmod(p, s.mode | 0222, function (er) {
- if (er) return cb(er)
- rm_(p, s, true, cb)
- })
- }
-
- if (!s.isDirectory()) {
- return fs.unlink(p, cb)
- }
-
- // directory
+function rmdir (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, cb)
- }, function (er) {
- if (er) return cb(er)
- fs.rmdir(p, cb)
- })
- })
-}
-
-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()
+ if (er)
+ return cb(er)
+ var n = files.length
+ if (n === 0)
+ return fs.rmdir(p, cb)
+ var errState
+ files.forEach(function (f) {
+ rimraf(path.join(p, f), function (er) {
+ if (errState)
+ return
+ if (er)
+ return cb(errState = er)
+ if (--n === 0)
+ fs.rmdir(p, cb)
+ })
})
})
}
-// this looks simpler, but it will fail with big directory trees,
-// or on slow stupid awful cygwin filesystems
+// this looks simpler, and is strictly *faster*, but will
+// tie up the JavaScript thread and fail on excessively
+// deep directory trees.
function rimrafSync (p) {
try {
- var s = fs[lstatSync](p)
+ fs.unlinkSync(p)
} catch (er) {
- if (er.code === "ENOENT") return
- throw er
- }
-
- if (!writable(s)) {
- fs.chmodSync(p, s.mode | 0222)
+ if (er.code === "ENOENT")
+ return
+ if (er.code !== "EPERM" && er.code !== "EISDIR")
+ throw er
+ fs.readdirSync(p).forEach(function (f) {
+ rimrafSync(path.join(p, f))
+ })
+ fs.rmdirSync(p)
}
-
- if (!s.isDirectory()) return fs.unlinkSync(p)
-
- fs.readdirSync(p).forEach(function (f) {
- rimrafSync(path.join(p, f))
- })
- fs.rmdirSync(p)
}
View
10 node_modules/rimraf/test/run.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+set -e
+for i in test-*.js; do
+ echo -n $i ...
+ bash setup.sh
+ node $i
+ ! [ -d target ]
+ echo "pass"
+done
+rm -rf target
View
47 node_modules/rimraf/test/setup.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+
+set -e
+
+files=10
+folders=2
+depth=4
+target="$PWD/target"
+
+rm -rf target
+
+fill () {
+ local depth=$1
+ local files=$2
+ local folders=$3
+ local target=$4
+
+ if ! [ -d $target ]; then
+ mkdir -p $target
+ fi
+
+ local f
+
+ f=$files
+ while [ $f -gt 0 ]; do
+ touch "$target/f-$depth-$f"
+ let f--
+ done
+
+ let depth--
+
+ if [ $depth -le 0 ]; then
+ return 0
+ fi
+
+ f=$folders
+ while [ $f -gt 0 ]; do
+ mkdir "$target/folder-$depth-$f"
+ fill $depth $files $folders "$target/d-$depth-$f"
+ let f--
+ done
+}
+
+fill $depth $files $folders $target
+
+# sanity assert
+[ -d $target ]
View
5 node_modules/rimraf/test/test-async.js
@@ -0,0 +1,5 @@
+var rimraf = require("../rimraf")
+ , path = require("path")
+rimraf(path.join(__dirname, "target"), function (er) {
+ if (er) throw er
+})
View
0  node_modules/rimraf/test/test-fiber.js
No changes.
View
3  node_modules/rimraf/test/test-sync.js
@@ -0,0 +1,3 @@
+var rimraf = require("../rimraf")
+ , path = require("path")
+rimraf.sync(path.join(__dirname, "target"))
Please sign in to comment.
Something went wrong with that request. Please try again.