-
-
Notifications
You must be signed in to change notification settings - Fork 252
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
35 changed files
with
8,086 additions
and
3,772 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
name: CI | ||
|
||
on: [push, pull_request] | ||
|
||
jobs: | ||
build: | ||
strategy: | ||
matrix: | ||
node-version: [10.0.x, 10.x, 12.0.x, 12.x, 14.0.x, 14.x, 16.x] | ||
platform: | ||
- os: ubuntu-latest | ||
shell: bash | ||
- os: macos-latest | ||
shell: bash | ||
- os: windows-latest | ||
shell: bash | ||
- os: windows-latest | ||
shell: powershell | ||
fail-fast: false | ||
|
||
runs-on: ${{ matrix.platform.os }} | ||
defaults: | ||
run: | ||
shell: ${{ matrix.platform.shell }} | ||
|
||
steps: | ||
- name: Checkout Repository | ||
uses: actions/checkout@v1.1.0 | ||
|
||
- name: Use Nodejs ${{ matrix.node-version }} | ||
uses: actions/setup-node@v1 | ||
with: | ||
node-version: ${{ matrix.node-version }} | ||
|
||
- name: Install dependencies | ||
run: npm install | ||
|
||
- name: Run Tests | ||
run: npm test -- -t0 -c | ||
env: | ||
# more thorough smoke test in CI | ||
RIMRAF_TEST_START_CHAR: a | ||
RIMRAF_TEST_END_CHAR: j | ||
RIMRAF_TEST_DEPTH: 5 |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,101 +1,84 @@ | ||
[![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, [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. | ||
## Major Changes from v3 to v4 | ||
|
||
The callback will be called with an error if there is one. Certain | ||
errors are handled for you: | ||
* The function returns a `Promise` instead of taking a callback. | ||
* Built-in glob support removed. | ||
* Native implementation used by default when available. | ||
* New implementation on Windows, making the exponential backoff for | ||
`EBUSY` and `ENOTEMPTY` errors no longer necessary. | ||
* Simplified implementation on Posix, since the Windows affordances are not | ||
necessary there. | ||
|
||
* Windows: `EBUSY` and `ENOTEMPTY` - rimraf will back off a maximum of | ||
`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 | ||
## API | ||
|
||
In order to use a custom file system library, you can override | ||
specific fs functions on the options object. | ||
### `rimraf(f, [opts]) -> Promise` | ||
|
||
If any of these functions are present on the options object, then | ||
the supplied function will be used instead of the default fs | ||
method. | ||
This first parameter is a path. The second argument is an options object. | ||
|
||
Sync methods are only relevant for `rimraf.sync()`, of course. | ||
Options: | ||
|
||
For example: | ||
* `tmp`: Temp folder to use to place files and folders for the Windows | ||
implementation. Must be on the same physical device as the path being | ||
deleted. Defaults to `dirname(f)`. | ||
|
||
```javascript | ||
var myCustomFS = require('some-custom-fs') | ||
Any other options are provided to the native Node.js `fs.rm` implementation | ||
when that is used. | ||
|
||
rimraf('some-thing', myCustomFS, callback) | ||
``` | ||
This will attempt to choose the best implementation, based on Node.js | ||
version and `process.platform`. To force a specific implementation, use | ||
one of the other functions provided. | ||
|
||
* maxBusyTries | ||
### `rimraf.sync(f, [opts])` `rimraf.rimrafSync(f, [opts])` | ||
|
||
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. | ||
Synchronous form of `rimraf()` | ||
|
||
Only relevant for async usage. | ||
Note that, unlike many file system operations, the synchronous form will | ||
typically be significantly _slower_ than the async form, because recursive | ||
deletion is extremely parallelizable. | ||
|
||
* emfileWait | ||
### `rimraf.native(f, [opts])` | ||
|
||
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. | ||
Uses the built-in `fs.rm` implementation that Node.js provides. This is | ||
used by default on Node.js versions greater than or equal to `14.14.0`. | ||
|
||
If you repeatedly encounter `EMFILE` errors, then consider using | ||
[graceful-fs](http://npm.im/graceful-fs) in your program. | ||
### `rimraf.nativeSync(f, [opts])` `rimraf.native.sync(f, [opts])` | ||
|
||
Only relevant for async usage. | ||
Synchronous form of `rimraf.native` | ||
|
||
* glob | ||
### `rimraf.manual(f, [opts])` | ||
|
||
Set to `false` to disable [glob](http://npm.im/glob) pattern | ||
matching. | ||
Use the JavaScript implementation appropriate for your operating system. | ||
|
||
Set to an object to pass options to the glob module. The default | ||
glob options are `{ nosort: true, silent: true }`. | ||
### `rimraf.manualSync(f, [opts])` `rimraf.manualSync(f, opts)` | ||
|
||
Glob version 6 is used in this module. | ||
Synchronous form of `rimraf.manual()` | ||
|
||
Relevant for both sync and async usage. | ||
### `rimraf.windows(f, [opts])` | ||
|
||
* disableGlob | ||
JavaScript implementation of file removal appropriate for Windows | ||
platforms, where `unlink` and `rmdir` are not atomic operations. | ||
|
||
Set to any non-falsey value to disable globbing entirely. | ||
(Equivalent to setting `glob: false`.) | ||
Moves all files and folders to the parent directory of `f` with a temporary | ||
filename prior to attempting to remove them. | ||
|
||
## rimraf.sync | ||
Note that, in cases where the operation fails, this _may_ leave files lying | ||
around in the parent directory with names like | ||
`.file-basename.txt.0.123412341`. Until the Windows kernel provides a way | ||
to perform atomic `unlink` and `rmdir` operations, this is unfortunately | ||
unavoidable. | ||
|
||
It can remove stuff synchronously, too. But that's not so good. Use | ||
the async API. It's better. | ||
To move files to a different temporary directory other than the parent, | ||
provide `opts.tmp`. Note that this _must_ be on the same physical device | ||
as the folder being deleted, or else the operation will fail. | ||
|
||
## CLI | ||
### `rimraf.windows.sync(path, [opts])` `rimraf.windowsSync(path, [opts])` | ||
|
||
If installed with `npm install rimraf -g` it can be used as a global | ||
command `rimraf <path> [<path> ...]` which is useful for cross platform support. | ||
Synchronous form of `rimraf.windows()` | ||
|
||
## mkdirp | ||
|
||
If you need to create a directory recursively, check out | ||
If you need to _create_ a directory recursively, check out | ||
[mkdirp](https://github.com/isaacs/node-mkdirp). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
const pathArg = require('./path-arg.js') | ||
const optsArg = require('./opts-arg.js') | ||
|
||
const {rimrafNative, rimrafNativeSync} = require('./rimraf-native.js') | ||
const {rimrafManual, rimrafManualSync} = require('./rimraf-manual.js') | ||
const {rimrafWindows, rimrafWindowsSync} = require('./rimraf-windows.js') | ||
const {rimrafPosix, rimrafPosixSync} = require('./rimraf-posix.js') | ||
const {useNative, useNativeSync} = require('./use-native.js') | ||
|
||
const rimraf = (path, opts) => { | ||
path = pathArg(path) | ||
opts = optsArg(opts) | ||
return useNative(opts) ? rimrafNative(path, opts) | ||
: rimrafManual(path, opts) | ||
} | ||
|
||
const rimrafSync = async (path, opts) => { | ||
path = pathArg(path) | ||
opts = optsArg(opts) | ||
return useNativeSync(opts) ? rimrafNativeSync(path, opts) | ||
: rimrafManualSync(path, opts) | ||
} | ||
|
||
rimraf.rimraf = rimraf | ||
rimraf.sync = rimraf.rimrafSync = rimrafSync | ||
|
||
const native = async (path, opts) => | ||
rimrafNative(pathArg(path), optsArg(opts)) | ||
const nativeSync = (path, opts) => | ||
rimrafNativeSync(pathArg(path), optsArg(opts)) | ||
native.sync = nativeSync | ||
rimraf.native = native | ||
rimraf.nativeSync = nativeSync | ||
|
||
const manual = async (path, opts) => | ||
rimrafManual(pathArg(path), optsArg(opts)) | ||
const manualSync = (path, opts) => | ||
rimrafManualSync(pathArg(path), optsArg(opts)) | ||
manual.sync = manualSync | ||
rimraf.manual = manual | ||
rimraf.manualSync = manualSync | ||
|
||
const windows = async (path, opts) => | ||
rimrafWindows(pathArg(path), optsArg(opts)) | ||
const windowsSync = (path, opts) => | ||
rimrafWindowsSync(pathArg(path), optsArg(opts)) | ||
windows.sync = windowsSync | ||
rimraf.windows = windows | ||
rimraf.windowsSync = windowsSync | ||
|
||
const posix = async (path, opts) => | ||
rimrafPosix(pathArg(path), optsArg(opts)) | ||
const posixSync = (path, opts) => | ||
rimrafPosixSync(pathArg(path), optsArg(opts)) | ||
posix.sync = posixSync | ||
rimraf.posix = posix | ||
rimraf.posixSync = posixSync | ||
|
||
module.exports = rimraf |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
// TODO: validate options | ||
module.exports = (opts = {}) => opts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
const platform = require('./platform.js') | ||
const { resolve, parse } = require('path') | ||
const pathArg = path => { | ||
if (/\0/.test(path)) { | ||
// simulate same failure that node raises | ||
throw Object.assign( | ||
new TypeError('path must be a string without null bytes'), | ||
{ | ||
path, | ||
code: 'ERR_INVALID_ARG_VALUE', | ||
} | ||
) | ||
} | ||
|
||
path = resolve(path) | ||
if (platform === 'win32') { | ||
const badWinChars = /[*|"<>?:]/ | ||
const {root} = parse(path) | ||
if (badWinChars.test(path.substr(root.length))) { | ||
throw Object.assign(new Error('Illegal characters in path.'), { | ||
path, | ||
code: 'EINVAL', | ||
}) | ||
} | ||
} | ||
|
||
return path | ||
} | ||
module.exports = pathArg |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module.exports = process.env.__TESTING_RIMRAF_PLATFORM__ || process.platform |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// returns an array of entries if readdir() works, | ||
// or the error that readdir() raised if not. | ||
const { | ||
readdirSync, | ||
promises: { | ||
readdir, | ||
}, | ||
} = require('fs') | ||
const readdirOrError = path => readdir(path).catch(er => er) | ||
const readdirOrErrorSync = (path) => { | ||
try { | ||
return readdirSync(path) | ||
} catch (er) { | ||
return er | ||
} | ||
} | ||
|
||
module.exports = { | ||
readdirOrError, | ||
readdirOrErrorSync, | ||
} |
Oops, something went wrong.