[Pkg-javascript-commits] [node-rimraf] 01/15: New upstream version 2.5.4
Jérémy Lal
kapouer at moszumanska.debian.org
Thu Nov 24 08:43:44 UTC 2016
This is an automated email from the git hooks/post-receive script.
kapouer pushed a commit to branch master
in repository node-rimraf.
commit 075daf32eb3c103c21db32bdc0afab71f05521be
Author: Jérémy Lal <kapouer at melix.org>
Date: Thu Nov 24 09:19:41 2016 +0100
New upstream version 2.5.4
---
.gitignore | 4 ++
.travis.yml | 8 +++
AUTHORS | 6 --
LICENSE | 32 ++++-----
README.md | 79 +++++++++++++++++++--
bin.js | 15 ++--
package.json | 24 +++++--
rimraf.js | 201 +++++++++++++++++++++++++++++++++++++++--------------
test/basic.js | 106 ++++++++++++++++++++++++++++
test/custom-fs.js | 187 +++++++++++++++++++++++++++++++++++++++++++++++++
test/fill.js | 41 +++++++++++
test/run.sh | 16 -----
test/setup.sh | 47 -------------
test/test-async.js | 5 --
test/test-sync.js | 3 -
15 files changed, 609 insertions(+), 165 deletions(-)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ab54836
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+node_modules/
+npm-debug.log
+.nyc_output
+coverage
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..ee45280
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,8 @@
+sudo: false
+language: node_js
+node_js:
+ - '0.10'
+ - '0.12'
+ - '4'
+ - '5'
+ - '6'
diff --git a/AUTHORS b/AUTHORS
deleted file mode 100644
index 247b754..0000000
--- a/AUTHORS
+++ /dev/null
@@ -1,6 +0,0 @@
-# Authors sorted by whether or not they're me.
-Isaac Z. Schlueter <i at izs.me> (http://blog.izs.me)
-Wayne Larsen <wayne at larsen.st> (http://github.com/wvl)
-ritch <skawful at gmail.com>
-Marcel Laverdet
-Yosef Dinerstein <yosefd at microsoft.com>
diff --git a/LICENSE b/LICENSE
index 05a4010..19129e3 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,23 +1,15 @@
-Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
-All rights reserved.
+The ISC License
-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:
+Copyright (c) Isaac Z. Schlueter and Contributors
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
-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.
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/README.md b/README.md
index cd123b6..423b8cf 100644
--- a/README.md
+++ b/README.md
@@ -1,18 +1,89 @@
-`rm -rf` for node.
+[![Build Status](https://travis-ci.org/isaacs/rimraf.svg?branch=master)](https://travis-ci.org/isaacs/rimraf) [![Dependency Status](https://david-dm.org/isaacs/rimraf.svg)](https://david-dm.org/isaacs/rimraf) [![devDependency Status](https://david-dm.org/isaacs/rimraf/dev-status.svg)](https://david-dm.org/isaacs/rimraf#info=devDependencies)
+
+The [UNIX command](http://en.wikipedia.org/wiki/Rm_(Unix)) `rm -rf` for node.
Install with `npm install rimraf`, or just drop rimraf.js somewhere.
## API
-`rimraf(f, callback)`
+`rimraf(f, [opts], callback)`
+
+The first parameter will be interpreted as a globbing pattern for files. If you
+want to disable globbing you can do so with `opts.disableGlob` (defaults to
+`false`). This might be handy, for instance, if you have filenames that contain
+globbing wildcard characters.
The callback will be called with an error if there is one. Certain
errors are handled for you:
* Windows: `EBUSY` and `ENOTEMPTY` - rimraf will back off a maximum of
- `opts.maxBusyTries` times before giving up.
+ `opts.maxBusyTries` times before giving up, adding 100ms of wait
+ between each attempt. The default `maxBusyTries` is 3.
* `ENOENT` - If the file doesn't exist, rimraf will return
successfully, since your desired outcome is already the case.
+* `EMFILE` - Since `readdir` requires opening a file descriptor, it's
+ possible to hit `EMFILE` if too many file descriptors are in use.
+ In the sync case, there's nothing to be done for this. But in the
+ async case, rimraf will gradually back off with timeouts up to
+ `opts.emfileWait` ms, which defaults to 1000.
+
+## options
+
+* unlink, chmod, stat, lstat, rmdir, readdir,
+ unlinkSync, chmodSync, statSync, lstatSync, rmdirSync, readdirSync
+
+ In order to use a custom file system library, you can override
+ specific fs functions on the options object.
+
+ If any of these functions are present on the options object, then
+ the supplied function will be used instead of the default fs
+ method.
+
+ Sync methods are only relevant for `rimraf.sync()`, of course.
+
+ For example:
+
+ ```javascript
+ var myCustomFS = require('some-custom-fs')
+
+ rimraf('some-thing', myCustomFS, callback)
+ ```
+
+* maxBusyTries
+
+ If an `EBUSY`, `ENOTEMPTY`, or `EPERM` error code is encountered
+ on Windows systems, then rimraf will retry with a linear backoff
+ wait of 100ms longer on each try. The default maxBusyTries is 3.
+
+ Only relevant for async usage.
+
+* emfileWait
+
+ If an `EMFILE` error is encountered, then rimraf will retry
+ repeatedly with a linear backoff of 1ms longer on each try, until
+ the timeout counter hits this max. The default limit is 1000.
+
+ If you repeatedly encounter `EMFILE` errors, then consider using
+ [graceful-fs](http://npm.im/graceful-fs) in your program.
+
+ Only relevant for async usage.
+
+* glob
+
+ Set to `false` to disable [glob](http://npm.im/glob) pattern
+ matching.
+
+ Set to an object to pass options to the glob module. The default
+ glob options are `{ nosort: true, silent: true }`.
+
+ Glob version 6 is used in this module.
+
+ Relevant for both sync and async usage.
+
+* disableGlob
+
+ Set to any non-falsey value to disable globbing entirely.
+ (Equivalent to setting `glob: false`.)
## rimraf.sync
@@ -22,7 +93,7 @@ the async API. It's better.
## CLI
If installed with `npm install rimraf -g` it can be used as a global
-command `rimraf <path>` which is useful for cross platform support.
+command `rimraf <path> [<path> ...]` which is useful for cross platform support.
## mkdirp
diff --git a/bin.js b/bin.js
index 29bfa8a..1bd5a0d 100755
--- a/bin.js
+++ b/bin.js
@@ -18,7 +18,7 @@ var args = process.argv.slice(2).filter(function(arg) {
if (help || args.length === 0) {
// If they didn't ask for help, then this is not a "success"
var log = help ? console.log : console.error
- log('Usage: rimraf <path>')
+ log('Usage: rimraf <path> [<path> ...]')
log('')
log(' Deletes all files and folders at "path" recursively.')
log('')
@@ -26,8 +26,15 @@ if (help || args.length === 0) {
log('')
log(' -h, --help Display this usage info')
process.exit(help ? 0 : 1)
-} else {
- args.forEach(function(arg) {
- rimraf.sync(arg)
+} else
+ go(0)
+
+function go (n) {
+ if (n >= args.length)
+ return
+ rimraf(args[n], function (er) {
+ if (er)
+ throw er
+ go(n+1)
})
}
diff --git a/package.json b/package.json
index 0cdd1c9..c2cc045 100644
--- a/package.json
+++ b/package.json
@@ -1,16 +1,26 @@
{
"name": "rimraf",
- "version": "2.2.8",
+ "version": "2.5.4",
"main": "rimraf.js",
"description": "A deep deletion module for node (like `rm -rf`)",
"author": "Isaac Z. Schlueter <i at izs.me> (http://blog.izs.me/)",
- "license": {
- "type": "MIT",
- "url": "https://github.com/isaacs/rimraf/raw/master/LICENSE"
- },
+ "license": "ISC",
"repository": "git://github.com/isaacs/rimraf.git",
"scripts": {
- "test": "cd test && bash run.sh"
+ "test": "tap test/*.js"
+ },
+ "bin": "./bin.js",
+ "dependencies": {
+ "glob": "^7.0.5"
},
- "bin": "./bin.js"
+ "files": [
+ "LICENSE",
+ "README.md",
+ "bin.js",
+ "rimraf.js"
+ ],
+ "devDependencies": {
+ "mkdirp": "^0.5.1",
+ "tap": "^6.1.1"
+ }
}
diff --git a/rimraf.js b/rimraf.js
index eb96c46..5d9a576 100644
--- a/rimraf.js
+++ b/rimraf.js
@@ -4,11 +4,15 @@ rimraf.sync = rimrafSync
var assert = require("assert")
var path = require("path")
var fs = require("fs")
+var glob = require("glob")
+
+var defaultGlobOpts = {
+ nosort: true,
+ silent: true
+}
// for EMFILE handling
var timeout = 0
-exports.EMFILE_MAX = 1000
-exports.BUSYTRIES_MAX = 3
var isWindows = (process.platform === "win32")
@@ -17,6 +21,7 @@ function defaults (options) {
'unlink',
'chmod',
'stat',
+ 'lstat',
'rmdir',
'readdir'
]
@@ -25,6 +30,14 @@ function defaults (options) {
m = m + 'Sync'
options[m] = options[m] || fs[m]
})
+
+ options.maxBusyTries = options.maxBusyTries || 3
+ options.emfileWait = options.emfileWait || 1000
+ if (options.glob === false) {
+ options.disableGlob = true
+ }
+ options.disableGlob = options.disableGlob || false
+ options.glob = options.glob || defaultGlobOpts
}
function rimraf (p, options, cb) {
@@ -32,41 +45,72 @@ function rimraf (p, options, cb) {
cb = options
options = {}
}
- assert(p)
- assert(options)
- assert(typeof cb === 'function')
- defaults(options)
+ assert(p, 'rimraf: missing path')
+ assert.equal(typeof p, 'string', 'rimraf: path should be a string')
+ assert.equal(typeof cb, 'function', 'rimraf: callback function required')
+ assert(options, 'rimraf: invalid options argument provided')
+ assert.equal(typeof options, 'object', 'rimraf: options should be object')
- if (!cb) throw new Error("No callback passed to rimraf()")
+ defaults(options)
var busyTries = 0
- rimraf_(p, options, function CB (er) {
- if (er) {
- if (isWindows && (er.code === "EBUSY" || er.code === "ENOTEMPTY") &&
- busyTries < exports.BUSYTRIES_MAX) {
- busyTries ++
- var time = busyTries * 100
- // try again, with the same exact callback as this one.
- return setTimeout(function () {
- rimraf_(p, options, CB)
- }, time)
- }
+ var errState = null
+ var n = 0
- // this one won't happen if graceful-fs is used.
- if (er.code === "EMFILE" && timeout < exports.EMFILE_MAX) {
- return setTimeout(function () {
- rimraf_(p, options, CB)
- }, timeout ++)
- }
+ if (options.disableGlob || !glob.hasMagic(p))
+ return afterGlob(null, [p])
- // already gone
- if (er.code === "ENOENT") er = null
- }
+ options.lstat(p, function (er, stat) {
+ if (!er)
+ return afterGlob(null, [p])
- timeout = 0
- cb(er)
+ glob(p, options.glob, afterGlob)
})
+
+ function next (er) {
+ errState = errState || er
+ if (--n === 0)
+ cb(errState)
+ }
+
+ function afterGlob (er, results) {
+ if (er)
+ return cb(er)
+
+ n = results.length
+ if (n === 0)
+ return cb()
+
+ results.forEach(function (p) {
+ rimraf_(p, options, function CB (er) {
+ if (er) {
+ if (isWindows && (er.code === "EBUSY" || er.code === "ENOTEMPTY" || er.code === "EPERM") &&
+ busyTries < options.maxBusyTries) {
+ busyTries ++
+ var time = busyTries * 100
+ // try again, with the same exact callback as this one.
+ return setTimeout(function () {
+ rimraf_(p, options, CB)
+ }, time)
+ }
+
+ // this one won't happen if graceful-fs is used.
+ if (er.code === "EMFILE" && timeout < options.emfileWait) {
+ return setTimeout(function () {
+ rimraf_(p, options, CB)
+ }, timeout ++)
+ }
+
+ // already gone
+ if (er.code === "ENOENT") er = null
+ }
+
+ timeout = 0
+ next(er)
+ })
+ })
+ }
}
// Two possible strategies.
@@ -85,18 +129,32 @@ function rimraf_ (p, options, cb) {
assert(options)
assert(typeof cb === 'function')
- options.unlink(p, function (er) {
- if (er) {
- if (er.code === "ENOENT")
- return cb(null)
- if (er.code === "EPERM")
- return (isWindows)
- ? fixWinEPERM(p, options, er, cb)
- : rmdir(p, options, er, cb)
- if (er.code === "EISDIR")
- return rmdir(p, options, er, cb)
- }
- return cb(er)
+ // sunos lets the root user unlink directories, which is... weird.
+ // so we have to lstat here and make sure it's not a dir.
+ options.lstat(p, function (er, st) {
+ if (er && er.code === "ENOENT")
+ return cb(null)
+
+ // Windows can EPERM on stat. Life is suffering.
+ if (er && er.code === "EPERM" && isWindows)
+ fixWinEPERM(p, options, er, cb)
+
+ if (st && st.isDirectory())
+ return rmdir(p, options, er, cb)
+
+ options.unlink(p, function (er) {
+ if (er) {
+ if (er.code === "ENOENT")
+ return cb(null)
+ if (er.code === "EPERM")
+ return (isWindows)
+ ? fixWinEPERM(p, options, er, cb)
+ : rmdir(p, options, er, cb)
+ if (er.code === "EISDIR")
+ return rmdir(p, options, er, cb)
+ }
+ return cb(er)
+ })
})
}
@@ -204,19 +262,56 @@ function rimrafSync (p, options) {
options = options || {}
defaults(options)
- assert(p)
- assert(options)
+ assert(p, 'rimraf: missing path')
+ assert.equal(typeof p, 'string', 'rimraf: path should be a string')
+ assert(options, 'rimraf: missing options')
+ assert.equal(typeof options, 'object', 'rimraf: options should be object')
- try {
- options.unlinkSync(p)
- } catch (er) {
- if (er.code === "ENOENT")
- return
- if (er.code === "EPERM")
- return isWindows ? fixWinEPERMSync(p, options, er) : rmdirSync(p, options, er)
- if (er.code !== "EISDIR")
- throw er
- rmdirSync(p, options, er)
+ var results
+
+ if (options.disableGlob || !glob.hasMagic(p)) {
+ results = [p]
+ } else {
+ try {
+ options.lstatSync(p)
+ results = [p]
+ } catch (er) {
+ results = glob.sync(p, options.glob)
+ }
+ }
+
+ if (!results.length)
+ return
+
+ for (var i = 0; i < results.length; i++) {
+ var p = results[i]
+
+ try {
+ var st = options.lstatSync(p)
+ } catch (er) {
+ if (er.code === "ENOENT")
+ return
+
+ // Windows can EPERM on stat. Life is suffering.
+ if (er.code === "EPERM" && isWindows)
+ fixWinEPERMSync(p, options, er)
+ }
+
+ try {
+ // sunos lets the root user unlink directories, which is... weird.
+ if (st && st.isDirectory())
+ rmdirSync(p, options, null)
+ else
+ options.unlinkSync(p)
+ } catch (er) {
+ if (er.code === "ENOENT")
+ return
+ if (er.code === "EPERM")
+ return isWindows ? fixWinEPERMSync(p, options, er) : rmdirSync(p, options, er)
+ if (er.code !== "EISDIR")
+ throw er
+ rmdirSync(p, options, er)
+ }
}
}
diff --git a/test/basic.js b/test/basic.js
new file mode 100644
index 0000000..d09885b
--- /dev/null
+++ b/test/basic.js
@@ -0,0 +1,106 @@
+var rimraf = require('../')
+var t = require('tap')
+
+var fs = require('fs')
+var fill = require('./fill.js')
+
+t.test('initial clean', function (t) {
+ rimraf.sync(__dirname + '/target')
+ t.throws(function () {
+ fs.statSync(__dirname + '/target')
+ })
+ t.end()
+})
+
+t.test('sync removal', function (t) {
+ fill()
+ t.ok(fs.statSync(__dirname + '/target').isDirectory())
+
+ rimraf.sync(__dirname + '/target')
+ t.throws(function () {
+ fs.statSync(__dirname + '/target')
+ })
+ t.end()
+})
+
+t.test('async removal', function (t) {
+ fill()
+ t.ok(fs.statSync(__dirname + '/target').isDirectory())
+
+ rimraf(__dirname + '/target', function (er) {
+ if (er)
+ throw er
+ t.throws(function () {
+ fs.statSync(__dirname + '/target')
+ })
+ t.end()
+ })
+})
+
+t.test('glob', function (t) {
+ t.plan(2)
+ t.test('async', function (t) {
+ fill()
+ var glob = require('glob')
+ var pattern = __dirname + '/target/f-*'
+ var before = glob.sync(pattern)
+ t.notEqual(before.length, 0)
+ rimraf(pattern, function (er) {
+ if (er)
+ throw er
+ var after = glob.sync(pattern)
+ t.same(after, [])
+ rimraf.sync(__dirname + '/target')
+ t.end()
+ })
+ })
+ t.test('sync', function (t) {
+ fill()
+ var glob = require('glob')
+ var pattern = __dirname + '/target/f-*'
+ var before = glob.sync(pattern)
+ t.notEqual(before.length, 0)
+ rimraf.sync(pattern)
+ var after = glob.sync(pattern)
+ t.same(after, [])
+ rimraf.sync(__dirname + '/target')
+ t.end()
+ })
+})
+
+t.test('no glob', function (t) {
+ t.plan(2)
+ t.test('async', function (t) {
+ fill()
+ var glob = require('glob')
+ var pattern = __dirname + '/target/f-*'
+ var before = glob.sync(pattern)
+ t.notEqual(before.length, 0)
+ rimraf(pattern, { disableGlob: true }, function (er) {
+ if (er)
+ throw er
+ var after = glob.sync(pattern)
+ t.same(after, before)
+ rimraf.sync(__dirname + '/target')
+ t.end()
+ })
+ })
+ t.test('sync', function (t) {
+ fill()
+ var glob = require('glob')
+ var pattern = __dirname + '/target/f-*'
+ var before = glob.sync(pattern)
+ t.notEqual(before.length, 0)
+ rimraf.sync(pattern, { disableGlob: true })
+ var after = glob.sync(pattern)
+ t.same(after, before)
+ rimraf.sync(__dirname + '/target')
+ t.end()
+ })
+})
+
+t.test('verify that cleanup happened', function (t) {
+ t.throws(fs.statSync.bind(fs, __dirname + '/../target'))
+ t.throws(fs.statSync.bind(fs, __dirname + '/target'))
+ t.end()
+})
diff --git a/test/custom-fs.js b/test/custom-fs.js
new file mode 100644
index 0000000..31674df
--- /dev/null
+++ b/test/custom-fs.js
@@ -0,0 +1,187 @@
+var rimraf = require('../')
+var fs = require('fs')
+var path = require('path')
+var t = require('tap')
+
+process.chdir(__dirname)
+
+// track that all the things happened
+var keepDirs = {}
+var intercepted = {}
+function intercept (method, path) {
+ intercepted[method] = intercepted[method] || []
+ intercepted[method].push(path)
+ intercepted[method] = intercepted[method].sort()
+ intercepted._saved = intercepted._saved.sort()
+ intercepted._removed = intercepted._removed.sort()
+}
+
+var expectAsync = {
+ _removed: [
+ 'a',
+ 'a/x',
+ 'a/x/some-file.txt',
+ 'a/y',
+ 'a/y/some-file.txt',
+ 'a/z',
+ 'a/z/some-file.txt'
+ ],
+ _saved: [
+ 'a',
+ 'a/x',
+ 'a/x/keep.txt',
+ 'a/y',
+ 'a/y/keep.txt',
+ 'a/z',
+ 'a/z/keep.txt'
+ ],
+ _keepDirs: { 'a/x': true, 'a/y': true, 'a/z': true, a: true, '.': true },
+ rmdir: [
+ 'a',
+ 'a',
+ 'a/x',
+ 'a/x',
+ 'a/y',
+ 'a/y',
+ 'a/z',
+ 'a/z'
+ ],
+ unlink: [
+ 'a/x/keep.txt',
+ 'a/x/some-file.txt',
+ 'a/y/keep.txt',
+ 'a/y/some-file.txt',
+ 'a/z/keep.txt',
+ 'a/z/some-file.txt'
+ ]
+}
+
+var expectSync = {
+ _removed: [
+ 'a',
+ 'a/x',
+ 'a/x/some-file.txt',
+ 'a/y',
+ 'a/y/some-file.txt',
+ 'a/z',
+ 'a/z/some-file.txt'
+ ],
+ _saved: [
+ 'a',
+ 'a/x',
+ 'a/x/keep.txt',
+ 'a/y',
+ 'a/y/keep.txt',
+ 'a/z',
+ 'a/z/keep.txt'
+ ],
+ _keepDirs: { 'a/x': true, a: true, 'a/y': true, 'a/z': true, '.': true },
+ rmdirSync: [
+ 'a',
+ 'a',
+ 'a/x',
+ 'a/x',
+ 'a/y',
+ 'a/y',
+ 'a/z',
+ 'a/z'
+ ],
+ unlinkSync: [
+ 'a/x/keep.txt',
+ 'a/x/some-file.txt',
+ 'a/y/keep.txt',
+ 'a/y/some-file.txt',
+ 'a/z/keep.txt',
+ 'a/z/some-file.txt'
+ ]
+}
+
+function shouldRemove (file) {
+ if (file.match(/keep.txt$/) || keepDirs[file]) {
+ // add the parent dir to keeps, to avoid ENOTEMPTY
+ intercepted._saved.push(file)
+ intercepted._saved = intercepted._saved.sort()
+ keepDirs[path.dirname(file)] = true
+ return false
+ } else {
+ intercepted._removed.push(file)
+ intercepted._removed = intercepted._removed.sort()
+ return true
+ }
+}
+
+var myFs = {
+ unlink: function (file, cb) {
+ intercept('unlink', file)
+ if (shouldRemove(file)) {
+ return fs.unlink(file, cb)
+ } else {
+ return cb()
+ }
+ },
+ unlinkSync: function (file) {
+ intercept('unlinkSync', file)
+ if (shouldRemove(file)) {
+ return fs.unlinkSync(file)
+ }
+ },
+ rmdir: function (file, cb) {
+ intercept('rmdir', file)
+ if (shouldRemove(file)) {
+ return fs.rmdir(file, cb)
+ } else {
+ return cb()
+ }
+ },
+ rmdirSync: function (file) {
+ intercept('rmdirSync', file)
+ if (shouldRemove(file)) {
+ return fs.rmdirSync(file)
+ }
+ }
+}
+
+var mkdirp = require('mkdirp')
+
+function create () {
+ intercepted = {}
+ intercepted._removed = []
+ intercepted._saved = []
+ intercepted._keepDirs = keepDirs = {}
+ mkdirp.sync('a')
+ ;['x', 'y', 'z'].forEach(function (j) {
+ mkdirp.sync('a/' + j)
+ fs.writeFileSync('a/' + j + '/some-file.txt', 'test\n')
+ fs.writeFileSync('a/' + j + '/keep.txt', 'test\n')
+ })
+}
+
+t.test('setup', function (t) {
+ create()
+ t.end()
+})
+
+t.test('rimraf with interceptor', function (t) {
+ rimraf('a', myFs, function (er) {
+ if (er) {
+ throw er
+ }
+ t.strictSame(intercepted, expectAsync)
+ create()
+ t.end()
+ })
+})
+
+t.test('rimraf sync with interceptor', function (t) {
+ create()
+ rimraf.sync('a', myFs)
+ t.strictSame(intercepted, expectSync)
+ create()
+ t.end()
+})
+
+t.test('cleanup', function (t) {
+ rimraf.sync('a')
+ t.throws(fs.statSync.bind(fs, 'a'))
+ t.end()
+})
diff --git a/test/fill.js b/test/fill.js
new file mode 100644
index 0000000..6c004d4
--- /dev/null
+++ b/test/fill.js
@@ -0,0 +1,41 @@
+var fs = require('fs')
+var mkdirp = require('mkdirp')
+
+module.exports = function () {
+ fill(4, 10, 2, __dirname + '/target')
+}
+
+if (module === require.main) {
+ require('tap').pass('yes')
+ return
+}
+
+function fill (depth, files, folders, target) {
+ mkdirp.sync(target)
+ var o = { flag: 'wx' }
+ if (process.version.match(/^v0\.8/))
+ o = 'utf8'
+
+ for (var f = files; f > 0; f--) {
+ fs.writeFileSync(target + '/f-' + depth + '-' + f, '', o)
+ }
+
+ // valid symlink
+ fs.symlinkSync('f-' + depth + '-1', target + '/link-' + depth + '-good', 'file')
+
+ // invalid symlink
+ fs.symlinkSync('does-not-exist', target + '/link-' + depth + '-bad', 'file')
+
+ // file with a name that looks like a glob
+ fs.writeFileSync(target + '/[a-z0-9].txt', '', o)
+
+ depth--
+ if (depth <= 0)
+ return
+
+ for (f = folders; f > 0; f--) {
+ mkdirp.sync(target + '/folder-' + depth + '-' + f)
+ fill(depth, files, folders, target + '/d-' + depth + '-' + f)
+ }
+}
+
diff --git a/test/run.sh b/test/run.sh
deleted file mode 100644
index 653ff9b..0000000
--- a/test/run.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/bash
-set -e
-code=0
-for i in test-*.js; do
- echo -n $i ...
- bash setup.sh
- node $i
- if [ -d target ]; then
- echo "fail"
- code=1
- else
- echo "pass"
- fi
-done
-rm -rf target
-exit $code
diff --git a/test/setup.sh b/test/setup.sh
deleted file mode 100644
index 2602e63..0000000
--- a/test/setup.sh
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/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 ]
diff --git a/test/test-async.js b/test/test-async.js
deleted file mode 100644
index 9c2e0b7..0000000
--- a/test/test-async.js
+++ /dev/null
@@ -1,5 +0,0 @@
-var rimraf = require("../rimraf")
- , path = require("path")
-rimraf(path.join(__dirname, "target"), function (er) {
- if (er) throw er
-})
diff --git a/test/test-sync.js b/test/test-sync.js
deleted file mode 100644
index eb71f10..0000000
--- a/test/test-sync.js
+++ /dev/null
@@ -1,3 +0,0 @@
-var rimraf = require("../rimraf")
- , path = require("path")
-rimraf.sync(path.join(__dirname, "target"))
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-rimraf.git
More information about the Pkg-javascript-commits
mailing list