chushihua
This commit is contained in:
+3
@@ -0,0 +1,3 @@
|
||||
coverage/
|
||||
test/
|
||||
.travis.yml
|
||||
+191
@@ -0,0 +1,191 @@
|
||||
0.16.5 / 2015-03-08
|
||||
-------------------
|
||||
- fixed `fs.move` when `clobber` is `true` and destination is a directory, it should clobber. https://github.com/jprichardson/node-fs-extra/issues/114
|
||||
|
||||
0.16.4 / 2015-03-01
|
||||
-------------------
|
||||
- `fs.mkdirs` fix infinite loop on Windows. See: See https://github.com/substack/node-mkdirp/pull/74 and https://github.com/substack/node-mkdirp/issues/66
|
||||
|
||||
0.16.3 / 2015-01-28
|
||||
-------------------
|
||||
- reverted https://github.com/jprichardson/node-fs-extra/commit/1ee77c8a805eba5b99382a2591ff99667847c9c9
|
||||
|
||||
|
||||
0.16.2 / 2015-01-28
|
||||
-------------------
|
||||
- fixed `fs.copy` for Node v0.8 (support is temporary and will be removed in the near future)
|
||||
|
||||
0.16.1 / 2015-01-28
|
||||
-------------------
|
||||
- if `setImmediate` is not available, fall back to `process.nextTick`
|
||||
|
||||
0.16.0 / 2015-01-28
|
||||
-------------------
|
||||
- bugfix `fs.move()` into itself. Closes #104
|
||||
- bugfix `fs.move()` moving directory across device. Closes #108
|
||||
- added coveralls support
|
||||
- bugfix: nasty multiple callback `fs.copy()` bug. Closes #98
|
||||
- misc fs.copy code cleanups
|
||||
|
||||
0.15.0 / 2015-01-21
|
||||
-------------------
|
||||
- dropped `ncp`, imported code in
|
||||
- because of previous, now supports `io.js`
|
||||
- `graceful-fs` is now a dependency
|
||||
|
||||
0.14.0 / 2015-01-05
|
||||
-------------------
|
||||
- changed `copy`/`copySync` from `fs.copy(src, dest, [filters], callback)` to `fs.copy(src, dest, [options], callback)` https://github.com/jprichardson/node-fs-extra/pull/100
|
||||
- removed mockfs tests for mkdirp (this may be temporary, but was getting in the way of other tests)
|
||||
|
||||
0.13.0 / 2014-12-10
|
||||
-------------------
|
||||
- removed `touch` and `touchSync` methods (they didn't handle permissions like UNIX touch)
|
||||
- updated `"ncp": "^0.6.0"` to `"ncp": "^1.0.1"`
|
||||
- imported `mkdirp` => `minimist` and `mkdirp` are no longer dependences, should now appease people who wanted `mkdirp` to be `--use_strict` safe. See [#59](https://github.com/jprichardson/node-fs-extra/issues/59)
|
||||
|
||||
0.12.0 / 2014-09-22
|
||||
-------------------
|
||||
- copy symlinks in `copySync()` [#85](https://github.com/jprichardson/node-fs-extra/pull/85)
|
||||
|
||||
0.11.1 / 2014-09-02
|
||||
-------------------
|
||||
- bugfix `copySync()` preserve file permissions [#80](https://github.com/jprichardson/node-fs-extra/pull/80)
|
||||
|
||||
0.11.0 / 2014-08-11
|
||||
-------------------
|
||||
- upgraded `"ncp": "^0.5.1"` to `"ncp": "^0.6.0"`
|
||||
- upgrade `jsonfile": "^1.2.0"` to `jsonfile": "^2.0.0"` => on write, json files now have `\n` at end. Also adds `options.throws` to `readJsonSync()`
|
||||
see https://github.com/jprichardson/node-jsonfile#readfilesyncfilename-options for more details.
|
||||
|
||||
0.10.0 / 2014-06-29
|
||||
------------------
|
||||
* bugfix: upgaded `"jsonfile": "~1.1.0"` to `"jsonfile": "^1.2.0"`, bumped minor because of `jsonfile` dep change
|
||||
from `~` to `^`. #67
|
||||
|
||||
0.9.1 / 2014-05-22
|
||||
------------------
|
||||
* removed Node.js `0.8.x` support, `0.9.0` was published moments ago and should have been done there
|
||||
|
||||
0.9.0 / 2014-05-22
|
||||
------------------
|
||||
* upgraded `ncp` from `~0.4.2` to `^0.5.1`, #58
|
||||
* upgraded `rimraf` from `~2.2.6` to `^2.2.8`
|
||||
* upgraded `mkdirp` from `0.3.x` to `^0.5.0`
|
||||
* added methods `ensureFile()`, `ensureFileSync()`
|
||||
* added methods `ensureDir()`, `ensureDirSync()` #31
|
||||
* added `move()` method. From: https://github.com/andrewrk/node-mv
|
||||
|
||||
|
||||
0.8.1 / 2013-10-24
|
||||
------------------
|
||||
* copy failed to return an error to the callback if a file doesn't exist (ulikoehler #38, #39)
|
||||
|
||||
0.8.0 / 2013-10-14
|
||||
------------------
|
||||
* `filter` implemented on `copy()` and `copySync()`. (Srirangan / #36)
|
||||
|
||||
0.7.1 / 2013-10-12
|
||||
------------------
|
||||
* `copySync()` implemented (Srirangan / #33)
|
||||
* updated to the latest `jsonfile` version `1.1.0` which gives `options` params for the JSON methods. Closes #32
|
||||
|
||||
0.7.0 / 2013-10-07
|
||||
------------------
|
||||
* update readme conventions
|
||||
* `copy()` now works if destination directory does not exist. Closes #29
|
||||
|
||||
0.6.4 / 2013-09-05
|
||||
------------------
|
||||
* changed `homepage` field in package.json to remove NPM warning
|
||||
|
||||
0.6.3 / 2013-06-28
|
||||
------------------
|
||||
* changed JSON spacing default from `4` to `2` to follow Node conventions
|
||||
* updated `jsonfile` dep
|
||||
* updated `rimraf` dep
|
||||
|
||||
0.6.2 / 2013-06-28
|
||||
------------------
|
||||
* added .npmignore, #25
|
||||
|
||||
0.6.1 / 2013-05-14
|
||||
------------------
|
||||
* modified for `strict` mode, closes #24
|
||||
* added `outputJson()/outputJsonSync()`, closes #23
|
||||
|
||||
0.6.0 / 2013-03-18
|
||||
------------------
|
||||
* removed node 0.6 support
|
||||
* added node 0.10 support
|
||||
* upgraded to latest `ncp` and `rimraf`.
|
||||
* optional `graceful-fs` support. Closes #17
|
||||
|
||||
|
||||
0.5.0 / 2013-02-03
|
||||
------------------
|
||||
* Removed `readTextFile`.
|
||||
* Renamed `readJSONFile` to `readJSON` and `readJson`, same with write.
|
||||
* Restructured documentation a bit. Added roadmap.
|
||||
|
||||
0.4.0 / 2013-01-28
|
||||
------------------
|
||||
* Set default spaces in `jsonfile` from 4 to 2.
|
||||
* Updated `testutil` deps for tests.
|
||||
* Renamed `touch()` to `createFile()`
|
||||
* Added `outputFile()` and `outputFileSync()`
|
||||
* Changed creation of testing diretories so the /tmp dir is not littered.
|
||||
* Added `readTextFile()` and `readTextFileSync()`.
|
||||
|
||||
0.3.2 / 2012-11-01
|
||||
------------------
|
||||
* Added `touch()` and `touchSync()` methods.
|
||||
|
||||
0.3.1 / 2012-10-11
|
||||
------------------
|
||||
* Fixed some stray globals.
|
||||
|
||||
0.3.0 / 2012-10-09
|
||||
------------------
|
||||
* Removed all CoffeeScript from tests.
|
||||
* Renamed `mkdir` to `mkdirs`/`mkdirp`.
|
||||
|
||||
0.2.1 / 2012-09-11
|
||||
------------------
|
||||
* Updated `rimraf` dep.
|
||||
|
||||
0.2.0 / 2012-09-10
|
||||
------------------
|
||||
* Rewrote module into JavaScript. (Must still rewrite tests into JavaScript)
|
||||
* Added all methods of [jsonfile][https://github.com/jprichardson/node-jsonfile]
|
||||
* Added Travis-CI.
|
||||
|
||||
0.1.3 / 2012-08-13
|
||||
------------------
|
||||
* Added method `readJSONFile`.
|
||||
|
||||
0.1.2 / 2012-06-15
|
||||
------------------
|
||||
* Bug fix: `deleteSync()` didn't exist.
|
||||
* Verified Node v0.8 compatibility.
|
||||
|
||||
0.1.1 / 2012-06-15
|
||||
------------------
|
||||
* Fixed bug in `remove()`/`delete()` that wouldn't execute the function if a callback wasn't passed.
|
||||
|
||||
0.1.0 / 2012-05-31
|
||||
------------------
|
||||
* Renamed `copyFile()` to `copy()`. `copy()` can now copy directories (recursively) too.
|
||||
* Renamed `rmrf()` to `remove()`.
|
||||
* `remove()` aliased with `delete()`.
|
||||
* Added `mkdirp` capabilities. Named: `mkdir()`. Hides Node.js native `mkdir()`.
|
||||
* Instead of exporting the native `fs` module with new functions, I now copy over the native methods to a new object and export that instead.
|
||||
|
||||
0.0.4 / 2012-03-14
|
||||
------------------
|
||||
* Removed CoffeeScript dependency
|
||||
|
||||
0.0.3 / 2012-01-11
|
||||
------------------
|
||||
* Added methods rmrf and rmrfSync
|
||||
* Moved tests from Jasmine to Mocha
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2011-2014 JP Richardson
|
||||
|
||||
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.
|
||||
+411
@@ -0,0 +1,411 @@
|
||||
Node.js: fs-extra
|
||||
=================
|
||||
|
||||
[](http://travis-ci.org/jprichardson/node-fs-extra)
|
||||
[](https://www.npmjs.org/package/fs-extra)
|
||||
[](https://coveralls.io/r/jprichardson/node-fs-extra)
|
||||
|
||||
This module adds a few extra file system methods that aren't included in the native `fs` module. It is a drop in replacement for `fs`.
|
||||
|
||||
|
||||
|
||||
Why?
|
||||
----
|
||||
|
||||
I got tired of including `mkdirp`, `rimraf`, and `cp -r` in most of my projects.
|
||||
|
||||
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
npm install --save fs-extra
|
||||
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
`fs-extra` is a drop in replacement for native `fs`. All methods in `fs` are unmodified and attached to `fs-extra`.
|
||||
|
||||
You don't ever need to include the original `fs` module again:
|
||||
|
||||
```javascript
|
||||
var fs = require('fs') //this is no longer necessary
|
||||
```
|
||||
|
||||
you can now do this:
|
||||
|
||||
```javascript
|
||||
var fs = require('fs-extra') //var fs = require('fs')
|
||||
```
|
||||
|
||||
or if you prefer to make it clear that you're using `fs-extra` and not `fs`, you may want
|
||||
to do this:
|
||||
|
||||
```javascript
|
||||
//var fs = require('fs')
|
||||
var fse = require('fs-extra')
|
||||
```
|
||||
|
||||
you can also keep both, but it's redundant:
|
||||
|
||||
```javascript
|
||||
var fs = require('fs')
|
||||
var fse = require('fs-extra')
|
||||
```
|
||||
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
**NOTE:** You can still use the native Node.js methods. They are copied over to `fs-extra`.
|
||||
|
||||
|
||||
### copy(src, dest, [options], callback)
|
||||
|
||||
Copy a file or directory. The directory can have contents. Like `cp -r`.
|
||||
|
||||
Sync: `copySync()`
|
||||
|
||||
|
||||
Examples:
|
||||
|
||||
```javascript
|
||||
var fs = require('fs-extra')
|
||||
|
||||
fs.copy('/tmp/myfile', '/tmp/mynewfile', function(err) {
|
||||
if (err) return console.error(err)
|
||||
console.log("success!")
|
||||
}) //copies file
|
||||
|
||||
fs.copy('/tmp/mydir', '/tmp/mynewdir', function(err) {
|
||||
if (err) return console.error(err)
|
||||
console.log("success!")
|
||||
}) //copies directory, even if it has subdirectories or files
|
||||
```
|
||||
|
||||
|
||||
### ensureFile(file, callback)
|
||||
|
||||
Ensures that the file exists. If the file that is requested to be created is in directories that do not exist, these directories are created. If the file already exists, it is **NOT MODIFIED**.
|
||||
|
||||
Alias: `createFile()`
|
||||
|
||||
Sync: `createFileSync()`,`ensureFileSync()`
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
var fs = require('fs-extra')
|
||||
|
||||
var file = '/tmp/this/path/does/not/exist/file.txt'
|
||||
fs.ensureFile(file, function(err) {
|
||||
console.log(err) // => null
|
||||
//file has now been created, including the directory it is to be placed in
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
### ensureDir(dir, callback)
|
||||
|
||||
Ensures that the directory exists. If the directory structure does not exist, it is created.
|
||||
|
||||
Sync: `ensureDirSync()`
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
var fs = require('fs-extra')
|
||||
|
||||
var dir = '/tmp/this/path/does/not/exist'
|
||||
fs.ensureDir(dir, function(err) {
|
||||
console.log(err) // => null
|
||||
//dir has now been created, including the directory it is to be placed in
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
|
||||
### mkdirs(dir, callback)
|
||||
|
||||
Creates a directory. If the parent hierarchy doesn't exist, it's created. Like `mkdir -p`.
|
||||
|
||||
Alias: `mkdirp()`
|
||||
|
||||
Sync: `mkdirsSync()` / `mkdirpSync()`
|
||||
|
||||
|
||||
Examples:
|
||||
|
||||
```javascript
|
||||
var fs = require('fs-extra')
|
||||
|
||||
fs.mkdirs('/tmp/some/long/path/that/prob/doesnt/exist', function(err) {
|
||||
if (err) return console.error(err)
|
||||
console.log("success!")
|
||||
})
|
||||
|
||||
fs.mkdirsSync('/tmp/another/path')
|
||||
```
|
||||
|
||||
|
||||
### move(src, dest, [options], callback)
|
||||
|
||||
Moves a file or directory, even across devices.
|
||||
|
||||
Options:
|
||||
clobber (boolean): overwrite existing file or directory
|
||||
limit (number): number of concurrent moves, see ncp for more information
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
var fs = require('fs-extra')
|
||||
|
||||
fs.move('/tmp/somefile', '/tmp/does/not/exist/yet/somefile', function(err) {
|
||||
if (err) return console.error(err)
|
||||
console.log("success!")
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
### outputFile(file, data, callback)
|
||||
|
||||
Almost the same as `writeFile` (i.e. it [overwrites](http://pages.citebite.com/v2o5n8l2f5reb)), except that if the parent directory does not exist, it's created.
|
||||
|
||||
Sync: `outputFileSync()`
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
var fs = require('fs-extra')
|
||||
var file = '/tmp/this/path/does/not/exist/file.txt'
|
||||
|
||||
fs.outputFile(file, 'hello!', function(err) {
|
||||
console.log(err) // => null
|
||||
|
||||
fs.readFile(file, 'utf8', function(err, data) {
|
||||
console.log(data) // => hello!
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
|
||||
### outputJson(file, data, callback)
|
||||
|
||||
Almost the same as `writeJson`, except that if the directory does not exist, it's created.
|
||||
|
||||
Alias: `outputJSON()`
|
||||
|
||||
Sync: `outputJsonSync()`, `outputJSONSync()`
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
var fs = require('fs-extra')
|
||||
var file = '/tmp/this/path/does/not/exist/file.txt'
|
||||
|
||||
fs.outputJson(file, {name: 'JP'}, function(err) {
|
||||
console.log(err) // => null
|
||||
|
||||
fs.readJson(file, function(err, data) {
|
||||
console.log(data.name) // => JP
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
|
||||
### readJson(file, [options], callback)
|
||||
|
||||
Reads a JSON file and then parses it into an object. `options` are the same that you'd pass to `fs.readFile`.
|
||||
|
||||
Alias: `readJSON()`
|
||||
|
||||
Sync: `readJsonSync()`, `readJSONSync()`
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
var fs = require('fs-extra')
|
||||
|
||||
fs.readJson('./package.json', function(err, packageObj) {
|
||||
console.log(packageObj.version) // => 0.1.3
|
||||
})
|
||||
```
|
||||
|
||||
`readJsonSync()` can take a `throws` option set to `false` and it won't throw if the JSON is invalid. Example:
|
||||
|
||||
```js
|
||||
var fs = require('fs-extra')
|
||||
var file = path.join('/tmp/some-invalid.json')
|
||||
var data = "{not valid JSON"
|
||||
fs.writeFileSync(file, data)
|
||||
|
||||
var obj = fs.readJsonSync(file, {throws: false})
|
||||
console.log(obj) // => null
|
||||
```
|
||||
|
||||
|
||||
### remove(dir, callback)
|
||||
|
||||
Removes a file or directory. The directory can have contents. Like `rm -rf`.
|
||||
|
||||
Alias: `delete()`
|
||||
|
||||
Sync: `removeSync()` / `deleteSync()`
|
||||
|
||||
|
||||
Examples:
|
||||
|
||||
```javascript
|
||||
var fs = require('fs-extra')
|
||||
|
||||
fs.remove('/tmp/myfile', function(err) {
|
||||
if (err) return console.error(err)
|
||||
|
||||
console.log("success!")
|
||||
})
|
||||
|
||||
fs.removeSync('/home/jprichardson') //I just deleted my entire HOME directory.
|
||||
```
|
||||
|
||||
|
||||
|
||||
### writeJson(file, object, [options], callback)
|
||||
|
||||
Writes an object to a JSON file. `options` are the same that you'd pass to `fs.readFile`.
|
||||
|
||||
Alias: `writeJSON()`
|
||||
|
||||
Sync: `writeJsonSync()`, `writeJSONSync()`
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
var fs = require('fs-extra')
|
||||
fs.writeJson('./package.json', {name: 'fs-extra'}, function(err) {
|
||||
console.log(err)
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
Third Party
|
||||
-----------
|
||||
|
||||
### Promises
|
||||
|
||||
Use [Bluebird](https://github.com/petkaantonov/bluebird). See https://github.com/petkaantonov/bluebird/blob/master/API.md#promisification. `fs-extra` is
|
||||
explicitly listed as supported.
|
||||
|
||||
```js
|
||||
var Promise = require("bluebird")
|
||||
var fs = Promise.promisifyAll(require("fs-extra"))
|
||||
```
|
||||
|
||||
Or you can use the package [`fs-extra-promise`](https://github.com/overlookmotel/fs-extra-promise) that marries the two together.
|
||||
|
||||
|
||||
### TypeScript
|
||||
|
||||
If you like TypeScript, you can use `fs-extra` with it: https://github.com/borisyankov/DefinitelyTyped/tree/master/fs-extra
|
||||
|
||||
|
||||
### File / Directory Watching
|
||||
|
||||
If you want to watch for changes to files or directories, then you should use [chokidar](https://github.com/paulmillr/chokidar).
|
||||
|
||||
|
||||
### Misc.
|
||||
|
||||
- [mfs](https://github.com/cadorn/mfs) - Monitor your fs-extra calls.
|
||||
|
||||
|
||||
|
||||
|
||||
Naming
|
||||
------
|
||||
|
||||
I put a lot of thought into the naming of these functions. Inspired by @coolaj86's request. So he deserves much of the credit for raising the issue. See discussion(s) here:
|
||||
|
||||
* https://github.com/jprichardson/node-fs-extra/issues/2
|
||||
* https://github.com/flatiron/utile/issues/11
|
||||
* https://github.com/ryanmcgrath/wrench-js/issues/29
|
||||
* https://github.com/substack/node-mkdirp/issues/17
|
||||
|
||||
First, I believe that in as many cases as possible, the [Node.js naming schemes](http://nodejs.org/api/fs.html) should be chosen. However, there are problems with the Node.js own naming schemes.
|
||||
|
||||
For example, `fs.readFile()` and `fs.readdir()`: the **F** is capitalized in *File* and the **d** is not capitalized in *dir*. Perhaps a bit pedantic, but they should still be consistent. Also, Node.js has chosen a lot of POSIX naming schemes, which I believe is great. See: `fs.mkdir()`, `fs.rmdir()`, `fs.chown()`, etc.
|
||||
|
||||
We have a dilemma though. How do you consistently name methods that perform the following POSIX commands: `cp`, `cp -r`, `mkdir -p`, and `rm -rf`?
|
||||
|
||||
My perspective: when in doubt, err on the side of simplicity. A directory is just a hierarchical grouping of directories and files. Consider that for a moment. So when you want to copy it or remove it, in most cases you'll want to copy or remove all of its contents. When you want to create a directory, if the directory that it's suppose to be contained in does not exist, then in most cases you'll want to create that too.
|
||||
|
||||
So, if you want to remove a file or a directory regardless of whether it has contents, just call `fs.remove(path)` or its alias `fs.delete(path)`. If you want to copy a file or a directory whether it has contents, just call `fs.copy(source, destination)`. If you want to create a directory regardless of whether its parent directories exist, just call `fs.mkdirs(path)` or `fs.mkdirp(path)`.
|
||||
|
||||
|
||||
Credit
|
||||
------
|
||||
|
||||
`fs-extra` wouldn't be possible without using the modules from the following authors:
|
||||
|
||||
- [Isaac Shlueter](https://github.com/isaacs)
|
||||
- [Charlie McConnel](https://github.com/avianflu)
|
||||
- [James Halliday](https://github.com/substack)
|
||||
- [Andrew Kelley](https://github.com/andrewrk)
|
||||
|
||||
|
||||
Contributions
|
||||
-------------
|
||||
|
||||
If you want to contribute, please add a test. Also, don't change the version in `package.json`.
|
||||
|
||||
|
||||
### Contributors
|
||||
|
||||
- [*] [JP Richardson](https://github.com/jprichardson)
|
||||
- [*] [Mike McNeil](https://github.com/mikermcneil)
|
||||
- [*] [Ian Crowther](https://github.com/iancrowther)
|
||||
- [*] [Stephen Mathieson](https://github.com/stephenmathieson)
|
||||
- [*] [Srirangan](https://github.com/Srirangan)
|
||||
- [*] [Uli Köhler](https://github.com/ulikoehler)
|
||||
- [2] [Sylvain Cleymans](https://github.com/Ackar)
|
||||
- [1] [Jim Higson](https://github.com/jimhigson)
|
||||
- [1] [PatrickJS](https://github.com/gdi2290)
|
||||
- [1] [Michael Tiller](https://github.com/xogeny)
|
||||
- [1] [yibuyisheng](https://github.com/yibuyisheng)
|
||||
- [1] [overlookmotel](https://github.com/overlookmotel)
|
||||
- `<your name here>`
|
||||
|
||||
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
|
||||
Licensed under MIT
|
||||
|
||||
Copyright (c) 2011-2014 JP Richardson
|
||||
|
||||
[1]: http://nodejs.org/docs/latest/api/fs.html
|
||||
|
||||
|
||||
[jsonfile]: https://github.com/jprichardson/node-jsonfile
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+250
@@ -0,0 +1,250 @@
|
||||
// imported from ncp (this is temporary, will rewrite)
|
||||
|
||||
var fs = require('graceful-fs')
|
||||
var path = require('path')
|
||||
|
||||
function ncp (source, dest, options, callback) {
|
||||
var cback = callback
|
||||
|
||||
if (!callback) {
|
||||
cback = options
|
||||
options = {}
|
||||
}
|
||||
|
||||
var basePath = process.cwd()
|
||||
var currentPath = path.resolve(basePath, source)
|
||||
var targetPath = path.resolve(basePath, dest)
|
||||
|
||||
var filter = options.filter
|
||||
var transform = options.transform
|
||||
var clobber = options.clobber !== false
|
||||
var dereference = options.dereference
|
||||
|
||||
var errs = null
|
||||
|
||||
var started = 0
|
||||
var finished = 0
|
||||
var running = 0
|
||||
// this is pretty useless now that we're using graceful-fs
|
||||
// consider removing
|
||||
var limit = options.limit || 512
|
||||
|
||||
startCopy(currentPath)
|
||||
|
||||
function startCopy(source) {
|
||||
started++
|
||||
if (filter) {
|
||||
if (filter instanceof RegExp) {
|
||||
if (!filter.test(source)) {
|
||||
return cb(true)
|
||||
}
|
||||
}
|
||||
else if (typeof filter === 'function') {
|
||||
if (!filter(source)) {
|
||||
return cb(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
return getStats(source)
|
||||
}
|
||||
|
||||
function getStats(source) {
|
||||
var defer = global.setImmediate || process.nextTick
|
||||
var stat = dereference ? fs.stat : fs.lstat
|
||||
if (running >= limit) {
|
||||
return defer(function () {
|
||||
getStats(source)
|
||||
})
|
||||
}
|
||||
running++
|
||||
stat(source, function (err, stats) {
|
||||
var item = {}
|
||||
if (err) {
|
||||
return onError(err)
|
||||
}
|
||||
|
||||
// We need to get the mode from the stats object and preserve it.
|
||||
item.name = source
|
||||
item.mode = stats.mode
|
||||
item.mtime = stats.mtime //modified time
|
||||
item.atime = stats.atime //access time
|
||||
|
||||
if (stats.isDirectory()) {
|
||||
return onDir(item)
|
||||
}
|
||||
else if (stats.isFile()) {
|
||||
return onFile(item)
|
||||
}
|
||||
else if (stats.isSymbolicLink()) {
|
||||
// Symlinks don't really need to know about the mode.
|
||||
return onLink(source)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function onFile(file) {
|
||||
var target = file.name.replace(currentPath, targetPath)
|
||||
isWritable(target, function (writable) {
|
||||
if (writable) {
|
||||
copyFile(file, target)
|
||||
} else {
|
||||
if(clobber) {
|
||||
rmFile(target, function () {
|
||||
copyFile(file, target)
|
||||
})
|
||||
} else {
|
||||
cb()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function copyFile(file, target) {
|
||||
var readStream = fs.createReadStream(file.name),
|
||||
writeStream = fs.createWriteStream(target, { mode: file.mode })
|
||||
|
||||
readStream.on('error', onError)
|
||||
writeStream.on('error', onError)
|
||||
|
||||
if(transform) {
|
||||
transform(readStream, writeStream, file)
|
||||
} else {
|
||||
writeStream.on('open', function() {
|
||||
readStream.pipe(writeStream)
|
||||
})
|
||||
}
|
||||
|
||||
//presumably old node then
|
||||
var eventName = global.setImmediate ? 'finish' : 'close'
|
||||
writeStream.once(eventName, function() {
|
||||
cb()
|
||||
})
|
||||
}
|
||||
|
||||
function rmFile(file, done) {
|
||||
fs.unlink(file, function (err) {
|
||||
if (err) {
|
||||
return onError(err)
|
||||
}
|
||||
return done()
|
||||
})
|
||||
}
|
||||
|
||||
function onDir(dir) {
|
||||
var target = dir.name.replace(currentPath, targetPath)
|
||||
isWritable(target, function (writable) {
|
||||
if (writable) {
|
||||
return mkDir(dir, target)
|
||||
}
|
||||
copyDir(dir.name)
|
||||
})
|
||||
}
|
||||
|
||||
function mkDir(dir, target) {
|
||||
fs.mkdir(target, dir.mode, function (err) {
|
||||
if (err) {
|
||||
return onError(err)
|
||||
}
|
||||
copyDir(dir.name)
|
||||
})
|
||||
}
|
||||
|
||||
function copyDir(dir) {
|
||||
fs.readdir(dir, function (err, items) {
|
||||
if (err) {
|
||||
return onError(err)
|
||||
}
|
||||
items.forEach(function (item) {
|
||||
startCopy(path.join(dir, item))
|
||||
})
|
||||
return cb()
|
||||
})
|
||||
}
|
||||
|
||||
function onLink(link) {
|
||||
var target = link.replace(currentPath, targetPath)
|
||||
fs.readlink(link, function (err, resolvedPath) {
|
||||
if (err) {
|
||||
return onError(err)
|
||||
}
|
||||
checkLink(resolvedPath, target)
|
||||
})
|
||||
}
|
||||
|
||||
function checkLink(resolvedPath, target) {
|
||||
if (dereference) {
|
||||
resolvedPath = path.resolve(basePath, resolvedPath)
|
||||
}
|
||||
isWritable(target, function (writable) {
|
||||
if (writable) {
|
||||
return makeLink(resolvedPath, target)
|
||||
}
|
||||
fs.readlink(target, function (err, targetDest) {
|
||||
if (err) {
|
||||
return onError(err)
|
||||
}
|
||||
if (dereference) {
|
||||
targetDest = path.resolve(basePath, targetDest)
|
||||
}
|
||||
if (targetDest === resolvedPath) {
|
||||
return cb()
|
||||
}
|
||||
return rmFile(target, function () {
|
||||
makeLink(resolvedPath, target)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function makeLink(linkPath, target) {
|
||||
fs.symlink(linkPath, target, function (err) {
|
||||
if (err) {
|
||||
return onError(err)
|
||||
}
|
||||
return cb()
|
||||
})
|
||||
}
|
||||
|
||||
function isWritable(path, done) {
|
||||
fs.lstat(path, function (err) {
|
||||
if (err) {
|
||||
if (err.code === 'ENOENT') return done(true)
|
||||
return done(false)
|
||||
}
|
||||
return done(false)
|
||||
})
|
||||
}
|
||||
|
||||
function onError(err) {
|
||||
if (options.stopOnError) {
|
||||
return cback(err)
|
||||
}
|
||||
else if (!errs && options.errs) {
|
||||
errs = fs.createWriteStream(options.errs)
|
||||
}
|
||||
else if (!errs) {
|
||||
errs = []
|
||||
}
|
||||
if (typeof errs.write === 'undefined') {
|
||||
errs.push(err)
|
||||
}
|
||||
else {
|
||||
errs.write(err.stack + '\n\n')
|
||||
}
|
||||
return cb()
|
||||
}
|
||||
|
||||
function cb(skipped) {
|
||||
if (!skipped) running--
|
||||
finished++
|
||||
if ((started === finished) && (running === 0)) {
|
||||
if (cback !== undefined ) {
|
||||
return errs ? cback(errs) : cback(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// todo, make this just export ncp
|
||||
module.exports.ncp = ncp
|
||||
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
var fs = require('graceful-fs')
|
||||
var path = require('path')
|
||||
var ncp = require('./_copy').ncp
|
||||
var mkdir = require('./mkdir')
|
||||
var create = require('./create')
|
||||
|
||||
var BUF_LENGTH = 64 * 1024
|
||||
var _buff = new Buffer(BUF_LENGTH)
|
||||
|
||||
var copyFileSync = function(srcFile, destFile) {
|
||||
var fdr = fs.openSync(srcFile, 'r')
|
||||
var stat = fs.fstatSync(fdr)
|
||||
var fdw = fs.openSync(destFile, 'w', stat.mode)
|
||||
var bytesRead = 1
|
||||
var pos = 0
|
||||
|
||||
while (bytesRead > 0) {
|
||||
bytesRead = fs.readSync(fdr, _buff, 0, BUF_LENGTH, pos)
|
||||
fs.writeSync(fdw, _buff, 0, bytesRead)
|
||||
pos += bytesRead
|
||||
}
|
||||
|
||||
fs.closeSync(fdr)
|
||||
fs.closeSync(fdw)
|
||||
}
|
||||
|
||||
function copy(src, dest, options, callback) {
|
||||
if( typeof options == "function" && !callback) {
|
||||
callback = options
|
||||
options = {}
|
||||
} else if (typeof options == "function" || options instanceof RegExp) {
|
||||
options = {filter: options}
|
||||
}
|
||||
callback = callback || function(){}
|
||||
|
||||
fs.lstat(src, function(err, stats) {
|
||||
if (err) return callback(err)
|
||||
|
||||
var dir = null
|
||||
if (stats.isDirectory()) {
|
||||
var parts = dest.split(path.sep)
|
||||
parts.pop()
|
||||
dir = parts.join(path.sep)
|
||||
} else {
|
||||
dir = path.dirname(dest)
|
||||
}
|
||||
|
||||
fs.exists(dir, function(dirExists) {
|
||||
if (dirExists) return ncp(src, dest, options, callback)
|
||||
mkdir.mkdirs(dir, function(err) {
|
||||
if (err) return callback(err)
|
||||
ncp(src, dest, options, callback)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function copySync(src, dest, options) {
|
||||
if (typeof options == "function" || options instanceof RegExp) {
|
||||
options = {filter: options}
|
||||
}
|
||||
|
||||
options = options || {}
|
||||
options.recursive = !!options.recursive
|
||||
|
||||
options.filter = options.filter || function() { return true }
|
||||
|
||||
var stats = options.recursive ? fs.lstatSync(src) : fs.statSync(src)
|
||||
var destFolder = path.dirname(dest)
|
||||
var destFolderExists = fs.existsSync(destFolder)
|
||||
var performCopy = false
|
||||
|
||||
if (stats.isFile()) {
|
||||
if (options.filter instanceof RegExp) performCopy = options.filter.test(src)
|
||||
else if (typeof options.filter == "function") performCopy = options.filter(src)
|
||||
|
||||
if (performCopy) {
|
||||
if (!destFolderExists) mkdir.mkdirsSync(destFolder)
|
||||
copyFileSync(src, dest)
|
||||
}
|
||||
}
|
||||
else if (stats.isDirectory()) {
|
||||
if (!fs.existsSync(dest)) mkdir.mkdirsSync(dest)
|
||||
var contents = fs.readdirSync(src)
|
||||
contents.forEach(function(content) {
|
||||
copySync(path.join(src, content), path.join(dest, content), {filter: options.filter, recursive: true})
|
||||
})
|
||||
}
|
||||
else if (options.recursive && stats.isSymbolicLink()) {
|
||||
var srcPath = fs.readlinkSync(src)
|
||||
fs.symlinkSync(srcPath, dest)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
copy: copy,
|
||||
copySync: copySync
|
||||
}
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
var path = require('path')
|
||||
var fs = require('graceful-fs')
|
||||
var mkdir = require('./mkdir')
|
||||
|
||||
function createFile (file, callback) {
|
||||
function makeFile() {
|
||||
fs.writeFile(file, '', function(err) {
|
||||
if (err) return callback(err)
|
||||
callback()
|
||||
})
|
||||
}
|
||||
|
||||
fs.exists(file, function(fileExists) {
|
||||
if (fileExists) return callback()
|
||||
var dir = path.dirname(file)
|
||||
fs.exists(dir, function(dirExists) {
|
||||
if (dirExists) return makeFile()
|
||||
mkdir.mkdirs(dir, function(err) {
|
||||
if (err) return callback(err)
|
||||
makeFile()
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function createFileSync (file) {
|
||||
if (fs.existsSync(file)) return
|
||||
|
||||
var dir = path.dirname(file)
|
||||
if (!fs.existsSync(dir))
|
||||
mkdir.mkdirsSync(dir)
|
||||
|
||||
fs.writeFileSync(file, '')
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createFile: createFile,
|
||||
createFileSync: createFileSync
|
||||
}
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
var jsonFile = require('jsonfile')
|
||||
var json = require('./json')
|
||||
|
||||
var fse = {}
|
||||
var fs = require("graceful-fs")
|
||||
|
||||
//attach fs methods to fse
|
||||
Object.keys(fs).forEach(function(key) {
|
||||
var func = fs[key]
|
||||
if (typeof func == 'function')
|
||||
fse[key] = func
|
||||
})
|
||||
fs = fse
|
||||
|
||||
var copy = require('./copy')
|
||||
fs.copy = copy.copy
|
||||
fs.copySync = copy.copySync
|
||||
|
||||
var remove = require('./remove')
|
||||
fs.remove = remove.remove
|
||||
fs.removeSync = remove.removeSync
|
||||
fs['delete'] = fs.remove
|
||||
fs.deleteSync = fs.removeSync
|
||||
|
||||
var mkdir = require('./mkdir')
|
||||
fs.mkdirs = mkdir.mkdirs
|
||||
fs.mkdirsSync = mkdir.mkdirsSync
|
||||
fs.mkdirp = fs.mkdirs
|
||||
fs.mkdirpSync = fs.mkdirsSync
|
||||
|
||||
var create = require('./create')
|
||||
fs.createFile = create.createFile
|
||||
fs.createFileSync = create.createFileSync
|
||||
|
||||
fs.ensureFile = create.createFile
|
||||
fs.ensureFileSync = create.createFileSync
|
||||
fs.ensureDir = mkdir.mkdirs
|
||||
fs.ensureDirSync = mkdir.mkdirsSync
|
||||
|
||||
|
||||
var move = require('./move')
|
||||
fs.move = function(src, dest, opts, callback) {
|
||||
if (typeof opts == 'function') {
|
||||
callback = opts
|
||||
opts = {}
|
||||
}
|
||||
|
||||
if (opts.mkdirp == null) opts.mkdirp = true
|
||||
if (opts.clobber == null) opts.clobber = false
|
||||
|
||||
move(src, dest, opts, callback)
|
||||
}
|
||||
|
||||
|
||||
var output = require('./output')
|
||||
fs.outputFile = output.outputFile
|
||||
fs.outputFileSync = output.outputFileSync
|
||||
|
||||
|
||||
fs.readJsonFile = jsonFile.readFile
|
||||
fs.readJSONFile = jsonFile.readFile
|
||||
fs.readJsonFileSync = jsonFile.readFileSync
|
||||
fs.readJSONFileSync = jsonFile.readFileSync
|
||||
|
||||
fs.readJson = jsonFile.readFile
|
||||
fs.readJSON = jsonFile.readFile
|
||||
fs.readJsonSync = jsonFile.readFileSync
|
||||
fs.readJSONSync = jsonFile.readFileSync
|
||||
|
||||
fs.outputJsonSync = json.outputJsonSync
|
||||
fs.outputJSONSync = json.outputJsonSync
|
||||
fs.outputJson = json.outputJson
|
||||
fs.outputJSON = json.outputJson
|
||||
|
||||
fs.writeJsonFile = jsonFile.writeFile
|
||||
fs.writeJSONFile = jsonFile.writeFile
|
||||
fs.writeJsonFileSync = jsonFile.writeFileSync
|
||||
fs.writeJSONFileSync = jsonFile.writeFileSync
|
||||
|
||||
fs.writeJson = jsonFile.writeFile
|
||||
fs.writeJSON = jsonFile.writeFile
|
||||
fs.writeJsonSync = jsonFile.writeFileSync
|
||||
fs.writeJSONSync = jsonFile.writeFileSync
|
||||
|
||||
|
||||
module.exports = fs
|
||||
|
||||
jsonFile.spaces = 2 //set to 2
|
||||
module.exports.jsonfile = jsonFile //so users of fs-extra can modify jsonFile.spaces
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
var fs = require('graceful-fs')
|
||||
var path = require('path')
|
||||
var jsonFile = require('jsonfile')
|
||||
var mkdir = require('./mkdir')
|
||||
|
||||
function outputJsonSync(file, data) {
|
||||
var dir = path.dirname(file)
|
||||
|
||||
if (!fs.existsSync(dir))
|
||||
mkdir.mkdirsSync(dir)
|
||||
|
||||
jsonFile.writeFileSync(file, data)
|
||||
}
|
||||
|
||||
function outputJson(file, data, callback) {
|
||||
var dir = path.dirname(file)
|
||||
|
||||
fs.exists(dir, function(itDoes) {
|
||||
if (itDoes) return jsonFile.writeFile(file, data, callback)
|
||||
|
||||
mkdir.mkdirs(dir, function(err) {
|
||||
if (err) return callback(err)
|
||||
jsonFile.writeFile(file, data, callback)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
outputJsonSync: outputJsonSync,
|
||||
outputJson: outputJson
|
||||
}
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
var fs = require('graceful-fs')
|
||||
var path = require('path')
|
||||
|
||||
var octal_0777 = parseInt('0777', 8)
|
||||
|
||||
function mkdirs(p, opts, f, made) {
|
||||
if (typeof opts === 'function') {
|
||||
f = opts
|
||||
opts = {}
|
||||
}
|
||||
else if (!opts || typeof opts !== 'object') {
|
||||
opts = { mode: opts }
|
||||
}
|
||||
|
||||
var mode = opts.mode
|
||||
var xfs = opts.fs || fs
|
||||
|
||||
if (mode === undefined) {
|
||||
mode = octal_0777 & (~process.umask())
|
||||
}
|
||||
if (!made) made = null
|
||||
|
||||
var cb = f || function () {}
|
||||
p = path.resolve(p)
|
||||
|
||||
xfs.mkdir(p, mode, function (er) {
|
||||
if (!er) {
|
||||
made = made || p
|
||||
return cb(null, made)
|
||||
}
|
||||
switch (er.code) {
|
||||
case 'ENOENT':
|
||||
if (path.dirname(p) == p) return cb(er)
|
||||
mkdirs(path.dirname(p), opts, function (er, made) {
|
||||
if (er) cb(er, made)
|
||||
else mkdirs(p, opts, cb, made)
|
||||
})
|
||||
break
|
||||
|
||||
// In the case of any other error, just see if there's a dir
|
||||
// there already. If so, then hooray! If not, then something
|
||||
// is borked.
|
||||
default:
|
||||
xfs.stat(p, function (er2, stat) {
|
||||
// if the stat fails, then that's super weird.
|
||||
// let the original error be the failure reason.
|
||||
if (er2 || !stat.isDirectory()) cb(er, made)
|
||||
else cb(null, made)
|
||||
})
|
||||
break
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function mkdirsSync (p, opts, made) {
|
||||
if (!opts || typeof opts !== 'object') {
|
||||
opts = { mode: opts }
|
||||
}
|
||||
|
||||
var mode = opts.mode
|
||||
var xfs = opts.fs || fs
|
||||
|
||||
if (mode === undefined) {
|
||||
mode = octal_0777 & (~process.umask())
|
||||
}
|
||||
if (!made) made = null
|
||||
|
||||
p = path.resolve(p)
|
||||
|
||||
try {
|
||||
xfs.mkdirSync(p, mode)
|
||||
made = made || p
|
||||
}
|
||||
catch (err0) {
|
||||
switch (err0.code) {
|
||||
case 'ENOENT' :
|
||||
made = mkdirsSync(path.dirname(p), opts, made)
|
||||
mkdirsSync(p, opts, made)
|
||||
break
|
||||
|
||||
// In the case of any other error, just see if there's a dir
|
||||
// there already. If so, then hooray! If not, then something
|
||||
// is borked.
|
||||
default:
|
||||
var stat
|
||||
try {
|
||||
stat = xfs.statSync(p)
|
||||
}
|
||||
catch (err1) {
|
||||
throw err0
|
||||
}
|
||||
if (!stat.isDirectory()) throw err0
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return made
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
mkdirs: mkdirs,
|
||||
mkdirsSync: mkdirsSync
|
||||
}
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
// most of this code was written by Andrew Kelley
|
||||
// licensed under the BSD license: see
|
||||
// https://github.com/andrewrk/node-mv/blob/master/package.json
|
||||
|
||||
// this needs a cleanup
|
||||
|
||||
var fs = require('graceful-fs')
|
||||
var ncp = require('./_copy').ncp
|
||||
var path = require('path')
|
||||
var rimraf = require('rimraf')
|
||||
var mkdirp = require('./mkdir').mkdirs
|
||||
|
||||
function mv(source, dest, options, callback){
|
||||
if (typeof options === 'function') {
|
||||
callback = options
|
||||
options = {}
|
||||
}
|
||||
|
||||
var shouldMkdirp = !!options.mkdirp
|
||||
var clobber = options.clobber !== false
|
||||
var limit = options.limit || 16
|
||||
|
||||
if (shouldMkdirp) {
|
||||
mkdirs()
|
||||
} else {
|
||||
doRename()
|
||||
}
|
||||
|
||||
function mkdirs() {
|
||||
mkdirp(path.dirname(dest), function(err) {
|
||||
if (err) return callback(err)
|
||||
doRename()
|
||||
})
|
||||
}
|
||||
|
||||
function doRename() {
|
||||
if (clobber) {
|
||||
fs.rename(source, dest, function(err) {
|
||||
if (!err) return callback()
|
||||
|
||||
if (err.code === 'ENOTEMPTY') {
|
||||
rimraf(dest, function(err) {
|
||||
if (err) return callback(err)
|
||||
options.clobber = false // just clobbered it, no need to do it again
|
||||
mv(source, dest, options, callback)
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (err.code !== 'EXDEV') return callback(err)
|
||||
moveFileAcrossDevice(source, dest, clobber, limit, callback)
|
||||
})
|
||||
} else {
|
||||
fs.link(source, dest, function(err) {
|
||||
if (err) {
|
||||
if (err.code === 'EXDEV') {
|
||||
moveFileAcrossDevice(source, dest, clobber, limit, callback)
|
||||
return
|
||||
}
|
||||
if (err.code === 'EISDIR' || err.code === 'EPERM') {
|
||||
moveDirAcrossDevice(source, dest, clobber, limit, callback)
|
||||
return
|
||||
}
|
||||
callback(err)
|
||||
return
|
||||
}
|
||||
fs.unlink(source, callback)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function moveFileAcrossDevice(source, dest, clobber, limit, callback) {
|
||||
var outFlags = clobber ? 'w' : 'wx'
|
||||
var ins = fs.createReadStream(source)
|
||||
var outs = fs.createWriteStream(dest, {flags: outFlags})
|
||||
|
||||
ins.on('error', function(err) {
|
||||
ins.destroy()
|
||||
outs.destroy()
|
||||
outs.removeListener('close', onClose)
|
||||
|
||||
// may want to create a directory but `out` line above
|
||||
// creates an empty file for us: See #108
|
||||
// don't care about error here
|
||||
fs.unlink(dest, function() {
|
||||
// note: `err` here is from the input stream errror
|
||||
if (err.code === 'EISDIR' || err.code === 'EPERM') {
|
||||
moveDirAcrossDevice(source, dest, clobber, limit, callback)
|
||||
} else {
|
||||
callback(err)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
outs.on('error', function(err) {
|
||||
ins.destroy()
|
||||
outs.destroy()
|
||||
outs.removeListener('close', onClose)
|
||||
callback(err)
|
||||
})
|
||||
|
||||
outs.once('close', onClose)
|
||||
ins.pipe(outs)
|
||||
|
||||
function onClose() {
|
||||
fs.unlink(source, callback)
|
||||
}
|
||||
}
|
||||
|
||||
function moveDirAcrossDevice(source, dest, clobber, limit, callback) {
|
||||
var options = {
|
||||
stopOnErr: true,
|
||||
clobber: false,
|
||||
limit: limit,
|
||||
}
|
||||
|
||||
function startNcp() {
|
||||
ncp(source, dest, options, function(errList) {
|
||||
if (errList) return callback(errList[0])
|
||||
rimraf(source, callback)
|
||||
})
|
||||
}
|
||||
|
||||
if (clobber) {
|
||||
rimraf(dest, function(err) {
|
||||
if (err) return callback(err)
|
||||
startNcp()
|
||||
})
|
||||
} else {
|
||||
startNcp()
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = mv
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
var path = require('path')
|
||||
var fs = require('graceful-fs')
|
||||
var mkdir = require('./mkdir')
|
||||
|
||||
function outputFile (file, data, encoding, callback) {
|
||||
if (typeof encoding === 'function') {
|
||||
callback = encoding
|
||||
encoding = 'utf8'
|
||||
}
|
||||
|
||||
var dir = path.dirname(file)
|
||||
fs.exists(dir, function(itDoes) {
|
||||
if (itDoes) return fs.writeFile(file, data, encoding, callback)
|
||||
|
||||
mkdir.mkdirs(dir, function(err) {
|
||||
if (err) return callback(err)
|
||||
|
||||
fs.writeFile(file, data, encoding, callback)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function outputFileSync (file, data, encoding) {
|
||||
var dir = path.dirname(file)
|
||||
if (fs.existsSync(dir))
|
||||
return fs.writeFileSync.apply(fs, arguments)
|
||||
mkdir.mkdirsSync(dir)
|
||||
fs.writeFileSync.apply(fs, arguments)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
outputFile: outputFile,
|
||||
outputFileSync: outputFileSync
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
var rimraf = require('rimraf')
|
||||
|
||||
function removeSync(dir) {
|
||||
return rimraf.sync(dir)
|
||||
}
|
||||
|
||||
function remove(dir, callback) {
|
||||
return callback ? rimraf(dir, callback) : rimraf(dir, function(){})
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
remove: remove,
|
||||
removeSync: removeSync
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"name": "fs-extra",
|
||||
"version": "0.16.5",
|
||||
"description": "fs-extra contains methods that aren't included in the vanilla Node.js fs package. Such as mkdir -p, cp -r, and rm -rf.",
|
||||
"homepage": "https://github.com/jprichardson/node-fs-extra",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jprichardson/node-fs-extra"
|
||||
},
|
||||
"keywords": [
|
||||
"fs",
|
||||
"file",
|
||||
"file system",
|
||||
"copy",
|
||||
"directory",
|
||||
"extra",
|
||||
"mkdirp",
|
||||
"mkdir",
|
||||
"mkdirs",
|
||||
"recursive",
|
||||
"json",
|
||||
"read",
|
||||
"write",
|
||||
"extra",
|
||||
"delete",
|
||||
"remove",
|
||||
"touch",
|
||||
"create",
|
||||
"text",
|
||||
"output",
|
||||
"move"
|
||||
],
|
||||
"author": "JP Richardson <jprichardson@gmail.com>",
|
||||
"licenses": [
|
||||
{
|
||||
"type": "MIT",
|
||||
"url": "http://github.com/jprichardson/node-fs-extra/raw/master/LICENSE"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"graceful-fs": "^3.0.5",
|
||||
"jsonfile": "^2.0.0",
|
||||
"rimraf": "^2.2.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"coveralls": "^2.11.2",
|
||||
"istanbul": "^0.3.5",
|
||||
"mocha": "^2.1.0",
|
||||
"read-dir-files": "^0.1.1",
|
||||
"secure-random": "^1.1.1",
|
||||
"testutil": "^0.7.0"
|
||||
},
|
||||
"main": "./lib/index",
|
||||
"scripts": {
|
||||
"coverage": "istanbul cover ./node_modules/.bin/_mocha -- --reporter list test/*.js",
|
||||
"coveralls": "npm run coverage && coveralls < coverage/lcov.info",
|
||||
"test": "mocha test"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user