[Pkg-javascript-commits] [node-wrench] 01/01: Imported Upstream version 1.5.8

Julien Puydt julien.puydt at laposte.net
Sat May 30 08:24:11 UTC 2015


This is an automated email from the git hooks/post-receive script.

jpuydt-guest pushed a commit to annotated tag upstream/1.5.8
in repository node-wrench.

commit 37356c36c45f838b4f1efeaa1f44d1e022b780ef
Author: Julien Puydt <julien.puydt at laposte.net>
Date:   Fri May 29 16:34:33 2015 +0200

    Imported Upstream version 1.5.8
---
 .npmignore                     |   3 +
 LICENSE                        |  21 ++
 lib/wrench.js                  | 531 +++++++++++++++++++++++++++++++++++++++++
 package.json                   |  39 +++
 readme.md                      | 103 ++++++++
 tests/copydirsync_unix.js      | 242 +++++++++++++++++++
 tests/mkdir.js                 |  26 ++
 tests/readdir.js               |  61 +++++
 tests/readdir/bar.txt          |   0
 tests/readdir/foo/bar/ipsum.js |   0
 tests/readdir/foo/dolor.md     |   0
 tests/readdir/foo/lorem.txt    |   0
 tests/rmdirSyncRecursive.js    |  74 ++++++
 tests/runner.js                |   9 +
 tests/shown/.hidden.txt        |   1 +
 tests/shown/.hidden/dolor.md   |   0
 tests/shown/bar.txt            |   1 +
 tests/shown/foo/bar/ipsum.js   |   0
 tests/shown/foo/dolor.md       |   0
 tests/shown/foo/lorem.txt      |   0
 tests/withsymlinks/test        |   1 +
 21 files changed, 1112 insertions(+)

diff --git a/.npmignore b/.npmignore
new file mode 100644
index 0000000..05ade97
--- /dev/null
+++ b/.npmignore
@@ -0,0 +1,3 @@
+node_modules
+npm-debug.log
+.idea
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..a85a94a
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+The MIT License
+
+Copyright (c) 2010 Ryan McGrath
+
+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/lib/wrench.js b/lib/wrench.js
new file mode 100644
index 0000000..01f5e95
--- /dev/null
+++ b/lib/wrench.js
@@ -0,0 +1,531 @@
+/*  wrench.js
+ *
+ *  A collection of various utility functions I've found myself in need of
+ *  for use with Node.js (http://nodejs.org/). This includes things like:
+ *
+ *  - Recursively deleting directories in Node.js (Sync, not Async)
+ *  - Recursively copying directories in Node.js (Sync, not Async)
+ *  - Recursively chmoding a directory structure from Node.js (Sync, not Async)
+ *  - Other things that I'll add here as time goes on. Shhhh...
+ *
+ *  ~ Ryan McGrath (ryan [at] venodesigns.net)
+ */
+
+var fs = require("fs"),
+    _path = require("path"),
+    isWindows = !!process.platform.match(/^win/);
+
+/*  wrench.readdirSyncRecursive("directory_path");
+ *
+ *  Recursively dives through directories and read the contents of all the
+ *  children directories.
+ */
+exports.readdirSyncRecursive = function(baseDir) {
+    baseDir = baseDir.replace(/\/$/, '');
+
+    var readdirSyncRecursive = function(baseDir) {
+        var files = [],
+            curFiles,
+            nextDirs,
+            isDir = function(fname){
+                return fs.existsSync(_path.join(baseDir, fname)) ? fs.statSync( _path.join(baseDir, fname) ).isDirectory() : false;
+            },
+            prependBaseDir = function(fname){
+                return _path.join(baseDir, fname);
+            };
+
+        curFiles = fs.readdirSync(baseDir);
+        nextDirs = curFiles.filter(isDir);
+        curFiles = curFiles.map(prependBaseDir);
+
+        files = files.concat( curFiles );
+
+        while (nextDirs.length) {
+            files = files.concat( readdirSyncRecursive( _path.join(baseDir, nextDirs.shift()) ) );
+        }
+
+        return files;
+    };
+
+    // convert absolute paths to relative
+    var fileList = readdirSyncRecursive(baseDir).map(function(val){
+        return _path.relative(baseDir, val);
+    });
+
+    return fileList;
+};
+
+/*  wrench.readdirRecursive("directory_path", function(error, files) {});
+ *
+ *  Recursively dives through directories and read the contents of all the
+ *  children directories.
+ *
+ *  Asynchronous, so returns results/error in callback.
+ *  Callback receives the of files in currently recursed directory.
+ *  When no more directories are left, callback is called with null for all arguments.
+ *
+ */
+exports.readdirRecursive = function(baseDir, fn) {
+    baseDir = baseDir.replace(/\/$/, '');
+
+    var waitCount = 0;
+
+    function readdirRecursive(curDir) {
+        var prependcurDir = function(fname){
+            return _path.join(curDir, fname);
+        };
+
+        waitCount++;
+        fs.readdir(curDir, function(e, curFiles) {
+            if (e) {
+                fn(e);
+                return;
+            }
+            waitCount--;
+
+            curFiles = curFiles.map(prependcurDir);
+
+            curFiles.forEach(function(it) {
+                waitCount++;
+
+                fs.stat(it, function(e, stat) {
+                    waitCount--;
+
+                    if (e) {
+                        fn(e);
+                    } else {
+                        if (stat.isDirectory()) {
+                            readdirRecursive(it);
+                        }
+                    }
+
+                    if (waitCount == 0) {
+                        fn(null, null);
+                    }
+                });
+            });
+
+            fn(null, curFiles.map(function(val) {
+                // convert absolute paths to relative
+                return _path.relative(baseDir, val);
+            }));
+
+            if (waitCount == 0) {
+                fn(null, null);
+            }
+        });
+    };
+
+    readdirRecursive(baseDir);
+};
+
+
+
+
+
+/*  wrench.rmdirSyncRecursive("directory_path", failSilent);
+ *
+ *  Recursively dives through directories and obliterates everything about it. This is a
+ *  Sync-function, which blocks things until it's done. No idea why anybody would want an
+ *  Asynchronous version. :\
+ */
+exports.rmdirSyncRecursive = function(path, failSilent) {
+    var files;
+
+    try {
+        files = fs.readdirSync(path);
+    } catch (err) {
+
+        if(failSilent) return;
+        throw new Error(err.message);
+    }
+
+    /*  Loop through and delete everything in the sub-tree after checking it */
+    for(var i = 0; i < files.length; i++) {
+        var file = _path.join(path, files[i]);
+        var currFile = fs.lstatSync(file);
+
+        if(currFile.isDirectory())  {
+            // Recursive function back to the beginning
+            exports.rmdirSyncRecursive(file);
+        } else if(currFile.isSymbolicLink()) {
+            // Unlink symlinks
+            if (isWindows) {
+                fs.chmodSync(file, 666) // Windows needs this unless joyent/node#3006 is resolved..
+            }
+
+            fs.unlinkSync(file);
+        } else {
+            // Assume it's a file - perhaps a try/catch belongs here?
+            if (isWindows) {
+                fs.chmodSync(file, 666) // Windows needs this unless joyent/node#3006 is resolved..
+            }
+
+            fs.unlinkSync(file);
+        }
+    }
+
+    /*  Now that we know everything in the sub-tree has been deleted, we can delete the main
+     directory. Huzzah for the shopkeep. */
+    return fs.rmdirSync(path);
+};
+
+
+
+function isFileIncluded(opts, dir, filename) {
+
+    function isMatch(filter) {
+        if (typeof filter === 'function') {
+            return filter(filename, dir) === true;
+        }
+        else {
+            // Maintain backwards compatibility and use just the filename
+            return filename.match(filter);
+        }
+    }
+
+    if (opts.include || opts.exclude) {
+        if (opts.exclude) {
+            if (isMatch(opts.exclude)) {
+                return false;
+            }
+        }
+
+        if (opts.include) {
+            if (isMatch(opts.include)) {
+                return true;
+            }
+            else  {
+                return false;
+            }
+        }
+
+        return true;
+    }
+    else if (opts.filter) {
+        var filter = opts.filter;
+
+        if (!opts.whitelist) {
+            // if !opts.whitelist is false every file or directory 
+            // which does match opts.filter will be ignored
+            return isMatch(filter) ? false : true;
+        } else {
+            // if opts.whitelist is true every file or directory 
+            // which doesn't match opts.filter will be ignored
+            return !isMatch(filter) ? false : true;
+        }
+    }
+
+    return true;
+}
+
+/*  wrench.copyDirSyncRecursive("directory_to_copy", "new_directory_location", opts);
+ *
+ *  Recursively dives through a directory and moves all its files to a new location. This is a
+ *  Synchronous function, which blocks things until it's done. If you need/want to do this in
+ *  an Asynchronous manner, look at wrench.copyDirRecursively() below. Specify forceDelete to force directory overwrite.
+ *
+ *  Note: Directories should be passed to this function without a trailing slash.
+ */
+exports.copyDirSyncRecursive = function(sourceDir, newDirLocation, opts) {
+    opts = opts || {};
+
+    try {
+        if(fs.statSync(newDirLocation).isDirectory()) { 
+            if(opts.forceDelete) {
+            exports.rmdirSyncRecursive(newDirLocation);
+            } else {
+                return new Error('You are trying to delete a directory that already exists. Specify forceDelete in the opts argument to override this. Bailing~');
+            }
+        }
+    } catch(e) { }
+
+    /*  Create the directory where all our junk is moving to; read the mode of the source directory and mirror it */
+    var checkDir = fs.statSync(sourceDir);
+    try {
+        fs.mkdirSync(newDirLocation, checkDir.mode);
+    } catch (e) {
+        //if the directory already exists, that's okay
+        if (e.code !== 'EEXIST') throw e;
+    }
+
+    var files = fs.readdirSync(sourceDir);
+    var hasFilter = opts.filter || opts.include || opts.exclude;
+    var preserveFiles = opts.preserveFiles === true;
+    var preserveTimestamps = opts.preserveTimestamps === true;
+
+    for(var i = 0; i < files.length; i++) {
+        // ignores all files or directories which match the RegExp in opts.filter
+        if(typeof opts !== 'undefined') {
+            if (hasFilter) {
+                if (!isFileIncluded(opts, sourceDir, files[i])) {
+                    continue;
+                }
+            }
+            
+            if (opts.excludeHiddenUnix && /^\./.test(files[i])) continue;
+        }
+
+        var currFile = fs.lstatSync(_path.join(sourceDir, files[i]));
+
+        var fCopyFile = function(srcFile, destFile) {
+            if(typeof opts !== 'undefined' && opts.preserveFiles && fs.existsSync(destFile)) return;
+
+            var contents = fs.readFileSync(srcFile);
+            fs.writeFileSync(destFile, contents);
+            var stat =  fs.lstatSync(srcFile);
+            fs.chmodSync(destFile, stat.mode);
+            if (preserveTimestamps) {
+                fs.utimesSync(destFile, stat.atime, stat.mtime)
+            }
+        };
+
+        if(currFile.isDirectory()) {
+            /*  recursion this thing right on back. */
+            exports.copyDirSyncRecursive(_path.join(sourceDir, files[i]), _path.join(newDirLocation, files[i]), opts);
+        } else if(currFile.isSymbolicLink()) {
+            var symlinkFull = fs.readlinkSync(_path.join(sourceDir, files[i]));
+            symlinkFull = _path.resolve(fs.realpathSync(sourceDir), symlinkFull);
+
+            if (typeof opts !== 'undefined' && !opts.inflateSymlinks) {
+                fs.symlinkSync(symlinkFull, _path.join(newDirLocation, files[i]));
+                continue;
+            }
+
+            var tmpCurrFile = fs.lstatSync(symlinkFull);
+            if (tmpCurrFile.isDirectory()) {
+                exports.copyDirSyncRecursive(symlinkFull, _path.join(newDirLocation, files[i]), opts);
+            } else {
+                /*  At this point, we've hit a file actually worth copying... so copy it on over. */
+                fCopyFile(symlinkFull, _path.join(newDirLocation, files[i]));
+            }
+        } else {
+            /*  At this point, we've hit a file actually worth copying... so copy it on over. */
+            fCopyFile(_path.join(sourceDir, files[i]), _path.join(newDirLocation, files[i]));
+        }
+    }
+};
+
+/*  wrench.chmodSyncRecursive("directory", filemode);
+ *
+ *  Recursively dives through a directory and chmods everything to the desired mode. This is a
+ *  Synchronous function, which blocks things until it's done.
+ *
+ *  Note: Directories should be passed to this function without a trailing slash.
+ */
+exports.chmodSyncRecursive = function(sourceDir, filemode) {
+    var files = fs.readdirSync(sourceDir);
+
+    for(var i = 0; i < files.length; i++) {
+        var currFile = fs.lstatSync(_path.join(sourceDir, files[i]));
+
+        if(currFile.isDirectory()) {
+            /*  ...and recursion this thing right on back. */
+            exports.chmodSyncRecursive(_path.join(sourceDir, files[i]), filemode);
+        } else {
+            /*  At this point, we've hit a file actually worth copying... so copy it on over. */
+            fs.chmod(_path.join(sourceDir, files[i]), filemode);
+        }
+    }
+
+    /*  Finally, chmod the parent directory */
+    fs.chmod(sourceDir, filemode);
+};
+
+
+/*  wrench.chownSyncRecursive("directory", uid, gid);
+ *
+ *  Recursively dives through a directory and chowns everything to the desired user and group. This is a
+ *  Synchronous function, which blocks things until it's done.
+ *
+ *  Note: Directories should be passed to this function without a trailing slash.
+ */
+exports.chownSyncRecursive = function(sourceDir, uid, gid) {
+    var files = fs.readdirSync(sourceDir);
+
+    for(var i = 0; i < files.length; i++) {
+        var currFile = fs.lstatSync(_path.join(sourceDir, files[i]));
+
+        if(currFile.isDirectory()) {
+            /*  ...and recursion this thing right on back. */
+            exports.chownSyncRecursive(_path.join(sourceDir, files[i]), uid, gid);
+        } else {
+            /*  At this point, we've hit a file actually worth chowning... so own it. */
+            fs.chownSync(_path.join(sourceDir, files[i]), uid, gid);
+        }
+    }
+
+    /*  Finally, chown the parent directory */
+    fs.chownSync(sourceDir, uid, gid);
+};
+
+
+
+/*  wrench.rmdirRecursive("directory_path", callback);
+ *
+ *  Recursively dives through directories and obliterates everything about it.
+ */
+exports.rmdirRecursive = function rmdirRecursive(dir, failSilent, clbk){
+    if(clbk === null || typeof clbk == 'undefined')
+        clbk = function(err) {};
+
+    fs.readdir(dir, function(err, files) {
+        if(err && typeof failSilent === 'boolean' && !failSilent) 
+        return clbk(err);
+
+        if(typeof failSilent === 'function')
+            clbk = failSilent;
+        
+        (function rmFile(err){
+            if (err) return clbk(err);
+
+            var filename = files.shift();
+            if (filename === null || typeof filename == 'undefined')
+                return fs.rmdir(dir, clbk);
+
+            var file = dir+'/'+filename;
+            fs.lstat(file, function(err, stat){
+                if (err) return clbk(err);
+                if (stat.isDirectory())
+                    rmdirRecursive(file, rmFile);
+                else
+                    fs.unlink(file, rmFile);
+            });
+        })();
+    });
+};
+
+/*  wrench.copyDirRecursive("directory_to_copy", "new_location", {forceDelete: bool}, callback);
+ *
+ *  Recursively dives through a directory and moves all its files to a new
+ *  location. Specify forceDelete to force directory overwrite.
+ *
+ *  Note: Directories should be passed to this function without a trailing slash.
+ */
+exports.copyDirRecursive = function copyDirRecursive(srcDir, newDir, opts, clbk) {
+    var originalArguments = Array.prototype.slice.apply(arguments);
+    srcDir = _path.normalize(srcDir);
+    newDir = _path.normalize(newDir);
+
+    fs.stat(newDir, function(err, newDirStat) {
+        if(!err) {
+            if(typeof opts !== 'undefined' && typeof opts !== 'function' && opts.forceDelete)
+                return exports.rmdirRecursive(newDir, function(err) {
+                    copyDirRecursive.apply(this, originalArguments);
+                });
+            else
+                return clbk(new Error('You are trying to delete a directory that already exists. Specify forceDelete in an options object to override this.'));
+        }
+
+	if(typeof opts === 'function')
+		clbk = opts;
+
+        fs.stat(srcDir, function(err, srcDirStat){
+            if (err) return clbk(err);
+            fs.mkdir(newDir, srcDirStat.mode, function(err){
+                if (err) return clbk(err);
+                fs.readdir(srcDir, function(err, files){
+                    if (err) return clbk(err);
+                    (function copyFiles(err){
+                        if (err) return clbk(err);
+
+                        var filename = files.shift();
+                        if (filename === null || typeof filename == 'undefined')
+                            return clbk(null);
+
+                        var file = srcDir+'/'+filename,
+                            newFile = newDir+'/'+filename;
+
+                        fs.stat(file, function(err, fileStat){
+                            if (err) return clbk(err);
+                            if (fileStat.isDirectory())
+                                copyDirRecursive(file, newFile, copyFiles, clbk);
+                            else if (fileStat.isSymbolicLink())
+                                fs.readlink(file, function(err, link){
+                                    if (err) return clbk(err);
+                                    fs.symlink(link, newFile, copyFiles);
+                                });
+                            else
+                                fs.readFile(file, function(err, data){
+                                    if (err) return clbk(err);
+                                    fs.writeFile(newFile, data, copyFiles);
+                                });
+                        });
+                    })();
+                });
+            });
+        });
+    });
+};
+
+var mkdirSyncRecursive = function(path, mode) {
+    var self = this;
+    path = _path.normalize(path)
+
+    try {
+        fs.mkdirSync(path, mode);
+    } catch(err) {
+        if(err.code == "ENOENT") {
+            var slashIdx = path.lastIndexOf(_path.sep);
+
+            if(slashIdx > 0) {
+                var parentPath = path.substring(0, slashIdx);
+                mkdirSyncRecursive(parentPath, mode);
+                mkdirSyncRecursive(path, mode);
+            } else {
+                throw err;
+            }
+        } else if(err.code == "EEXIST") {
+            return;
+        } else {
+            throw err;
+        }
+    }
+};
+exports.mkdirSyncRecursive = mkdirSyncRecursive;
+
+exports.LineReader = function(filename, bufferSize) {
+    this.bufferSize = bufferSize || 8192;
+    this.buffer = "";
+    this.fd = fs.openSync(filename, "r");
+    this.currentPosition = 0;
+};
+
+exports.LineReader.prototype = {
+    close: function() {
+        return fs.closeSync(this.fd);
+    },
+
+    getBufferAndSetCurrentPosition: function(position) {
+        var res = fs.readSync(this.fd, this.bufferSize, position, "ascii");
+
+        this.buffer += res[0];
+        if(res[1] === 0) {
+            this.currentPosition = -1;
+        } else {
+            this.currentPosition = position + res[1];
+        }
+
+        return this.currentPosition;
+    },
+
+    hasNextLine: function() {
+        while(this.buffer.indexOf('\n') === -1) {
+            this.getBufferAndSetCurrentPosition(this.currentPosition);
+            if(this.currentPosition === -1) return false;
+        }
+
+        if(this.buffer.indexOf("\n") > -1 || this.buffer.length !== 0) return true;
+        return false;
+    },
+
+    getNextLine: function() {
+        var lineEnd = this.buffer.indexOf("\n"),
+            result = this.buffer.substring(0, lineEnd != -1 ? lineEnd : this.buffer.length);
+
+        this.buffer = this.buffer.substring(result.length + 1, this.buffer.length);
+        return result;
+    }
+};
+
+// vim: et ts=4 sw=4
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..1d9b40c
--- /dev/null
+++ b/package.json
@@ -0,0 +1,39 @@
+{
+  "name": "wrench",
+  "description": "Recursive filesystem (and other) operations that Node *should* have.",
+  "version": "1.5.8",
+  "author": "Ryan McGrath <ryan at venodesigns.net>",
+
+  "repository": {
+    "type" : "git",
+    "url": "https://ryanmcgrath@github.com/ryanmcgrath/wrench-js.git"
+  },
+
+  "bugs": {
+    "url": "http://github.com/ryanmcgrath/wrench-js/issues"
+  },
+
+  "directories": {
+    "lib": "./lib/"
+  },
+
+  "dependencies": {
+  },
+
+  "devDependencies": {
+      "nodeunit": ">= 0.6.4"
+  },
+
+  "main": "./lib/wrench",
+
+  "engines": { 
+    "node": ">=0.1.97"
+  },
+  
+  "scripts": { "test": "nodeunit tests/runner.js" },
+
+  "licenses": [{
+    "type" : "MIT",
+    "url" : "http://github.com/ryanmcgrath/wrench-js/raw/master/LICENSE"
+  }]
+}
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..2d646d0
--- /dev/null
+++ b/readme.md
@@ -0,0 +1,103 @@
+wrench.js - Recursive file operations in Node.js
+----------------------------------------------------------------------------
+While I love Node.js, I've found myself missing some functions. Things like
+recursively deleting/chmodding a directory (or even deep copying a directory),
+or even a basic line reader, shouldn't need to be re-invented time and time again.
+
+That said, here's my attempt at a re-usable solution, at least until something
+more formalized gets integrated into Node.js (*hint hint*). wrench.js is fairly simple
+to use - check out the documentation/examples below:
+
+Possibly Breaking Change in v1.5.0
+-----------------------------------------------------------------------------
+In previous versions of Wrench, we went against the OS-default behavior of not
+deleting a directory unless the operation is forced. In 1.5.0, this has been
+changed to be the behavior people expect there to be - if you try to copy over
+a directory that already exists, you'll get an Error returned or thrown stating
+that you need to force it.
+
+Something like this will do the trick:
+
+``` javascript
+wrench.copyDirSyncRecursive('directory_to_copy', 'location_where_copy_should_end_up', {
+    forceDelete: true
+});
+```
+
+If you desire the older behavior of Wrench... hit up your package.json. If you
+happen to find bugs in the 1.5.0 release please feel free to file them on the 
+GitHub issues tracker for this project, or send me a pull request and I'll get to
+it as fast as I can. Thanks!
+
+**If this breaks enough projects I will consider rolling it back. Please hit me up if this seems to be the case.**
+
+Installation
+-----------------------------------------------------------------------------
+
+    npm install wrench
+
+Usage
+-----------------------------------------------------------------------------
+``` javascript
+var wrench = require('wrench'),
+	util = require('util');
+```
+
+### Synchronous operations
+``` javascript
+// Recursively create directories, sub-trees and all.
+wrench.mkdirSyncRecursive(dir, 0777);
+
+// Recursively delete the entire sub-tree of a directory, then kill the directory
+wrench.rmdirSyncRecursive('my_directory_name', failSilently);
+
+// Recursively read directories contents.
+wrench.readdirSyncRecursive('my_directory_name');
+
+// Recursively chmod the entire sub-tree of a directory
+wrench.chmodSyncRecursive('my_directory_name', 0755);
+
+// Recursively chown the entire sub-tree of a directory
+wrench.chownSyncRecursive("directory", uid, gid);
+
+// Deep-copy an existing directory
+wrench.copyDirSyncRecursive('directory_to_copy', 'location_where_copy_should_end_up', {
+    forceDelete: bool, // Whether to overwrite existing directory or not
+    excludeHiddenUnix: bool, // Whether to copy hidden Unix files or not (preceding .)
+    preserveFiles: bool, // If we're overwriting something and the file already exists, keep the existing
+    preserveTimestamps: bool, // Preserve the mtime and atime when copying files
+    inflateSymlinks: bool, // Whether to follow symlinks or not when copying files
+    filter: regexpOrFunction, // A filter to match files against; if matches, do nothing (exclude).
+    whitelist: bool, // if true every file or directory which doesn't match filter will be ignored
+    include: regexpOrFunction, // An include filter (either a regexp or a function)
+    exclude: regexpOrFunction // An exclude filter (either a regexp or a function)
+});
+
+// Note: If a RegExp is provided then then it will be matched against the filename. If a function is
+//       provided then the signature should be the following:
+//       function(filename, dir) { return result; }
+
+// Read lines in from a file until you hit the end
+var f = new wrench.LineReader('x.txt');
+while(f.hasNextLine()) {
+	util.puts(f.getNextLine());
+}
+
+// Note: You will need to close that above line reader at some point, otherwise
+// you will run into a "too many open files" error. f.close() or fs.closeSync(f.fd) are
+// your friends, as only you know when it is safe to close.
+```
+
+### Asynchronous operations
+``` javascript
+// Recursively read directories contents
+var files = [];
+wrench.readdirRecursive('my_directory_name', function(error, curFiles) {
+    // curFiles is what you want
+});
+
+// If you're feeling somewhat masochistic
+wrench.copyDirRecursive(srcDir, newDir, {forceDelete: bool /* See sync version */}, callbackfn);
+```
+
+Questions, comments? Hit me up. (ryan [at] venodesigns.net | http://twitter.com/ryanmcgrath)
diff --git a/tests/copydirsync_unix.js b/tests/copydirsync_unix.js
new file mode 100644
index 0000000..c48bb62
--- /dev/null
+++ b/tests/copydirsync_unix.js
@@ -0,0 +1,242 @@
+var testCase = require('nodeunit').testCase;
+var fs = require('fs');
+var wrench = require('../lib/wrench');
+var path = require('path');
+
+function checkResultHidden(test, files) {
+    var check = [
+        '.hidden',
+        '.hidden.txt',
+        'bar.txt',
+        'foo',
+        path.join('.hidden', 'dolor.md'),
+        path.join('foo', 'bar'),
+        path.join('foo', 'dolor.md'),
+        path.join('foo', 'lorem.txt'),
+        path.join('foo', 'bar', 'ipsum.js')
+    ];
+
+    test.deepEqual(files, check);
+}
+
+function checkResultShown(test, files) {
+    var check = [
+        'bar.txt',
+        'foo',
+        path.join('foo', 'bar'),
+        path.join('foo', 'dolor.md'),
+        path.join('foo', 'lorem.txt'),
+        path.join('foo', 'bar', 'ipsum.js')
+    ];
+
+    test.deepEqual(files, check);
+}
+
+function checkResultInflate(test, files) {
+    var check = [
+        '.hidden',
+        'bar.txt',
+        'test',
+        path.join('.hidden', 'dolor.md')
+    ];
+
+    test.deepEqual(files, check);
+
+    test.deepEqual(fs.lstatSync(path.join(__dirname, 'testdir/.hidden')).isSymbolicLink(), false);
+    test.deepEqual(fs.lstatSync(path.join(__dirname, 'testdir/bar.txt')).isSymbolicLink(), false);
+}
+
+function checkResultInflateAbsolute(test, files) {
+    var check = [
+        '.hidden',
+        'absolute-bar.txt',
+        'bar.txt',
+        'test',
+        path.join('.hidden', 'dolor.md')
+    ];
+
+    test.deepEqual(files, check);
+
+    test.deepEqual(fs.lstatSync(path.join(__dirname, 'testdir/.hidden')).isSymbolicLink(), false);
+    test.deepEqual(fs.lstatSync(path.join(__dirname, 'testdir/bar.txt')).isSymbolicLink(), false);
+}
+
+function checkResultDontInflate(test, files) {
+    var check = [
+        '.hidden',
+        'bar.txt',
+        'test',
+        path.join('.hidden', 'dolor.md')
+    ];
+
+    test.deepEqual(files, check);
+
+    test.deepEqual(fs.lstatSync(path.join(__dirname, 'testdir/.hidden')).isSymbolicLink(), true);
+    test.deepEqual(fs.lstatSync(path.join(__dirname, 'testdir/bar.txt')).isSymbolicLink(), true);
+}
+
+function checkResultPreserveFiles(test, files) {
+    checkResultHidden(test, files);
+    var contents = fs.readFileSync(path.join(__dirname, path.join('testdir2', '.hidden.txt')), "utf8");
+    test.deepEqual(contents, 'hidden file');
+    contents = fs.readFileSync(path.join(__dirname, path.join('testdir2', 'bar.txt')), "utf8");
+    test.deepEqual(contents, 'shown file');
+}
+
+function checkResultOverwriteFiles(test, files) {
+    checkResultHidden(test, files);
+    var contents = fs.readFileSync(path.join(__dirname, path.join('testdir2', '.hidden.txt')), "utf8");
+    test.deepEqual(contents, 'just some text for .hidden.txt');
+    contents = fs.readFileSync(path.join(__dirname, path.join('testdir2', 'bar.txt')), "utf8");
+    test.deepEqual(contents, 'just some text for bar.txt');
+}
+
+module.exports = testCase({
+    test_copyDirSyncRecursiveWithoutOptions: function(test) {
+        var dir = path.join(__dirname, 'shown');
+        var testdir = path.join(__dirname, 'testdir');
+
+        wrench.copyDirSyncRecursive(dir, testdir);
+
+        wrench.rmdirSyncRecursive(testdir);
+        test.done();
+    },
+    test_copyDirSyncRecursiveHidden: function(test) {
+        var dir = path.join(__dirname, 'shown');
+        var testdir = path.join(__dirname, 'testdir');
+
+        test.ok(fs.existsSync(dir), 'Folders should exist');
+
+        wrench.copyDirSyncRecursive(dir, testdir, { excludeHiddenUnix: false });
+
+        var files = wrench.readdirSyncRecursive(testdir);
+
+        checkResultHidden(test, files);
+
+        wrench.rmdirSyncRecursive(testdir);
+
+        test.done();
+    },
+    test_copyDirSyncRecursiveShown: function(test) {
+        var dir = path.join(__dirname, 'shown');
+        var testdir = path.join(__dirname, 'testdir');
+
+        test.ok(fs.existsSync(dir), 'Folders should exist');
+
+        wrench.copyDirSyncRecursive(dir, testdir, { excludeHiddenUnix: true });
+
+        var files = wrench.readdirSyncRecursive(testdir);
+
+        checkResultShown(test, files);
+
+        wrench.rmdirSyncRecursive(testdir);
+
+        test.done();
+    },
+    test_copyDirSyncRecursiveInflate: function(test) {
+        var dir = path.join(__dirname, 'withsymlinks');
+        var testdir = path.join(__dirname, 'testdir');
+
+        test.ok(fs.existsSync(dir), 'Folders should exist');
+
+        wrench.copyDirSyncRecursive(dir, testdir, { excludeHiddenUnix: false, inflateSymlinks: true });
+
+        var files = wrench.readdirSyncRecursive(testdir);
+
+        checkResultInflate(test, files);
+
+        wrench.rmdirSyncRecursive(testdir);
+
+        test.done();
+    },
+    test_copyDirSyncRecursiveInflateAbsoluteSymlinks: function(test) {
+        var dir = path.join(__dirname, 'withsymlinks');
+        var testdir = path.join(__dirname, 'testdir');
+
+        fs.symlinkSync(
+            path.resolve(__dirname, 'shown/bar.txt'),
+            path.join(dir, 'absolute-bar.txt')
+        );
+
+        wrench.mkdirSyncRecursive(testdir, 0777);
+        wrench.copyDirSyncRecursive(dir, testdir, { forceDelete: true, excludeHiddenUnix: false, inflateSymlinks: true });
+
+        var files = wrench.readdirSyncRecursive(testdir);
+
+        checkResultInflateAbsolute(test, files);
+
+        wrench.rmdirSyncRecursive(testdir);
+        fs.unlinkSync(path.join(dir, 'absolute-bar.txt'));
+
+        test.done();
+    },
+    test_copyDirSyncRecursiveDontInflate: function(test) {
+        var dir = path.join(__dirname, 'withsymlinks');
+        var testdir = path.join(__dirname, 'testdir');
+
+        test.ok(fs.existsSync(dir), 'Folders should exist');
+
+        wrench.copyDirSyncRecursive(dir, testdir, { excludeHiddenUnix: false, inflateSymlinks: false });
+
+        var files = wrench.readdirSyncRecursive(testdir);
+
+        checkResultDontInflate(test, files);
+
+        wrench.rmdirSyncRecursive(testdir);
+
+        test.done();
+    },
+    test_copyDirSyncRecursivePreserveFiles: function(test) {
+        var dir = path.join(__dirname, 'shown'),
+            testdir1 = path.join(__dirname, 'testdir1'),
+            testdir2 = path.join(__dirname, 'testdir2');
+
+        test.ok(fs.existsSync(dir), 'Folders should exist');
+
+        // wrench.mkdirSyncRecursive(testdir1, 0777);
+        wrench.copyDirSyncRecursive(dir, testdir1, { excludeHiddenUnix: false });
+        wrench.copyDirSyncRecursive(dir, testdir2, { excludeHiddenUnix: false });
+
+        fs.writeFileSync(path.join(testdir1, ".hidden.txt"), 'just some text for .hidden.txt');
+        fs.writeFileSync(path.join(testdir1, "bar.txt"), 'just some text for bar.txt');
+
+        wrench.copyDirSyncRecursive(testdir1, testdir2, { excludeHiddenUnix: false, preserveFiles: true });
+
+        var files = wrench.readdirSyncRecursive(testdir2);
+
+        checkResultPreserveFiles(test, files);
+
+        wrench.rmdirSyncRecursive(testdir1);
+        wrench.rmdirSyncRecursive(testdir2);
+
+        test.done();
+    },
+    test_copyDirSyncRecursiveOverwriteFiles: function(test) {
+        var dir = path.join(__dirname, 'shown'),
+            testdir1 = path.join(__dirname, 'testdir1'),
+            testdir2 = path.join(__dirname, 'testdir2');
+
+        test.ok(fs.existsSync(dir), 'Folders should exist');
+
+        // wrench.mkdirSyncRecursive(testdir1, 0777);
+        wrench.copyDirSyncRecursive(dir, testdir1, { excludeHiddenUnix: false });
+        wrench.copyDirSyncRecursive(dir, testdir2, { excludeHiddenUnix: false });
+
+        fs.writeFileSync(path.join(testdir1, ".hidden.txt"), 'just some text for .hidden.txt');
+        fs.writeFileSync(path.join(testdir1, "bar.txt"), 'just some text for bar.txt');
+
+        wrench.copyDirSyncRecursive(testdir1, testdir2, { forceDelete: true, excludeHiddenUnix: false, preserveFiles: false });
+
+        var files = wrench.readdirSyncRecursive(testdir2);
+
+        checkResultOverwriteFiles(test, files);
+
+        wrench.rmdirSyncRecursive(testdir1);
+        wrench.rmdirSyncRecursive(testdir2);
+
+        test.done();
+    }
+
+});
+
+// vim: et ts=4 sw=4
diff --git a/tests/mkdir.js b/tests/mkdir.js
new file mode 100644
index 0000000..933887b
--- /dev/null
+++ b/tests/mkdir.js
@@ -0,0 +1,26 @@
+var testCase = require('nodeunit').testCase;
+var fs = require('fs');
+var wrench = require('../lib/wrench');
+var path = require('path');
+
+module.exports = testCase({
+    test_mkdirSyncRecursive: function(test) {
+        var dir = __dirname + '/_tmp/foo/bar';
+
+        test.equals(fs.existsSync(dir), false, 'Dir shouldn\'t exist - clean it up manually?');
+
+        wrench.mkdirSyncRecursive(dir, 0777);
+
+        test.equals(fs.existsSync(dir), true, 'Dir should exist now');
+
+        // clean up
+        while (dir != __dirname) {
+            fs.rmdirSync(dir);
+            dir = path.dirname(dir);
+        }
+
+        test.done();
+    },
+});
+
+// vim: et ts=4 sw=4
diff --git a/tests/readdir.js b/tests/readdir.js
new file mode 100644
index 0000000..5e8abf0
--- /dev/null
+++ b/tests/readdir.js
@@ -0,0 +1,61 @@
+var testCase = require('nodeunit').testCase;
+var fs = require('fs');
+var wrench = require('../lib/wrench');
+var path = require('path');
+
+
+function checkResult(test, files) {
+    var check = [
+            'bar.txt',
+            'foo',
+            path.join('foo', 'bar'),
+            path.join('foo', 'dolor.md'),
+            path.join('foo', 'lorem.txt'),
+            path.join('foo', 'bar', 'ipsum.js')
+        ];
+
+    test.deepEqual(files, check);
+
+    test.done();
+}
+
+module.exports = testCase({
+    test_readdirSyncRecursive: function(test) {
+        var dir = path.join(__dirname, 'readdir');
+
+        test.ok(fs.existsSync(dir), 'Folders should exist');
+
+        var files = wrench.readdirSyncRecursive(dir);
+
+        checkResult(test, files);
+    },
+
+    test_readdirRecursive: function(test) {
+        var dir = path.join(__dirname, 'readdir');
+
+        test.ok(fs.existsSync(dir), 'Folders should exist');
+
+        var allFiles = [];
+
+        wrench.readdirRecursive(dir, function(e, files) {
+            if (e) throw e;
+
+            if (files) {
+                allFiles = allFiles.concat(files);
+            } else {
+                checkResult(test, allFiles);
+            }
+        });
+    },
+
+    test_readdirRecursiveWithNonExistentDirectory: function(test) {
+        wrench.readdirRecursive('', function (e, files) {
+            test.ok(e);
+            test.equal(e.code, 'ENOENT');
+            test.equal(files, null);
+            test.done();
+        });
+    }
+});
+
+// vim: et ts=4 sw=4
diff --git a/tests/readdir/bar.txt b/tests/readdir/bar.txt
new file mode 100644
index 0000000..e69de29
diff --git a/tests/readdir/foo/bar/ipsum.js b/tests/readdir/foo/bar/ipsum.js
new file mode 100644
index 0000000..e69de29
diff --git a/tests/readdir/foo/dolor.md b/tests/readdir/foo/dolor.md
new file mode 100644
index 0000000..e69de29
diff --git a/tests/readdir/foo/lorem.txt b/tests/readdir/foo/lorem.txt
new file mode 100644
index 0000000..e69de29
diff --git a/tests/rmdirSyncRecursive.js b/tests/rmdirSyncRecursive.js
new file mode 100644
index 0000000..3415e84
--- /dev/null
+++ b/tests/rmdirSyncRecursive.js
@@ -0,0 +1,74 @@
+var testCase = require('nodeunit').testCase;
+var fs = require('fs');
+var wrench = require('../lib/wrench');
+var path = require('path');
+
+module.exports = testCase({
+    test_rmdirSyncRecursive: function(test) {
+        var dir = __dirname + '/_tmp2/foo/bar';
+
+        wrench.mkdirSyncRecursive(dir, '777');
+
+        var f1Path = path.join(dir, 'test1.txt');
+        var f2Path = path.join(path.dirname(dir), 'test2.txt');
+        var f3Path = path.join(path.dirname(path.dirname(dir)), 'test3.txt');
+
+        fs.writeFileSync(f1Path, 'foo bar baz');
+        fs.writeFileSync(f2Path, 'foo bar baz');
+        fs.writeFileSync(f3Path, 'foo bar baz');
+
+        fs.chmodSync(f1Path, '444');
+        fs.chmodSync(f2Path, '444');
+        fs.chmodSync(f3Path, '444');
+
+        test.equals(fs.existsSync(dir), true, 'Dir should exist - mkdirSyncRecursive not working?');
+        test.equals(fs.existsSync(f1Path), true, 'File should exist');
+        test.equals(fs.existsSync(f2Path), true, 'File should exist');
+        test.equals(fs.existsSync(f3Path), true, 'File should exist');
+
+        wrench.rmdirSyncRecursive(dir);
+
+        test.equals(fs.existsSync(dir), false, 'Dir should not exist now...');
+        test.equals(fs.existsSync(f1Path), false, 'File should not exist');
+        test.equals(fs.existsSync(f2Path), true, 'File should exist');
+        test.equals(fs.existsSync(f3Path), true, 'File should exist');
+
+        wrench.rmdirSyncRecursive(path.dirname(path.dirname(dir)));
+
+        test.done();
+    },
+
+    test_rmdirSyncRecursiveFromRoot: function(test) {
+        var dir = __dirname + '/_tmp3/foo/bar';
+
+        wrench.mkdirSyncRecursive(dir, '777');
+
+        var f1Path = path.join(dir, 'test1.txt');
+        var f2Path = path.join(path.dirname(dir), 'test2.txt');
+        var f3Path = path.join(path.dirname(path.dirname(dir)), 'test3.txt');
+
+        fs.writeFileSync(f1Path, 'foo bar baz');
+        fs.writeFileSync(f2Path, 'foo bar baz');
+        fs.writeFileSync(f3Path, 'foo bar baz');
+
+        fs.chmodSync(f1Path, '444');
+        fs.chmodSync(f2Path, '444');
+        fs.chmodSync(f3Path, '444');
+
+        test.equals(fs.existsSync(dir), true, 'Dir should exist - mkdirSyncRecursive not working?');
+        test.equals(fs.existsSync(f1Path), true, 'File should exist');
+        test.equals(fs.existsSync(f2Path), true, 'File should exist');
+        test.equals(fs.existsSync(f3Path), true, 'File should exist');
+
+        wrench.rmdirSyncRecursive(path.dirname(path.dirname(dir)));
+
+        test.equals(fs.existsSync(dir), false, 'Dir should not exist now...');
+        test.equals(fs.existsSync(f1Path), false, 'File should not exist');
+        test.equals(fs.existsSync(f2Path), false, 'File should not exist');
+        test.equals(fs.existsSync(f3Path), false, 'File should not exist');
+
+        test.done();
+    }
+});
+
+// vim: et ts=4 sw=4
diff --git a/tests/runner.js b/tests/runner.js
new file mode 100644
index 0000000..e321a15
--- /dev/null
+++ b/tests/runner.js
@@ -0,0 +1,9 @@
+// `nodeunit tests/runner`
+// will run all the tests
+
+module.exports = {
+    group_mkdir: require('./mkdir'),
+    group_readdir: require('./readdir'),
+    group_copydir: require('./copydirsync_unix'),
+    group_rmdir: require('./rmdirSyncRecursive')
+};
diff --git a/tests/shown/.hidden.txt b/tests/shown/.hidden.txt
new file mode 100644
index 0000000..b96b725
--- /dev/null
+++ b/tests/shown/.hidden.txt
@@ -0,0 +1 @@
+hidden file
\ No newline at end of file
diff --git a/tests/shown/.hidden/dolor.md b/tests/shown/.hidden/dolor.md
new file mode 100644
index 0000000..e69de29
diff --git a/tests/shown/bar.txt b/tests/shown/bar.txt
new file mode 100644
index 0000000..3d36c5c
--- /dev/null
+++ b/tests/shown/bar.txt
@@ -0,0 +1 @@
+shown file
\ No newline at end of file
diff --git a/tests/shown/foo/bar/ipsum.js b/tests/shown/foo/bar/ipsum.js
new file mode 100644
index 0000000..e69de29
diff --git a/tests/shown/foo/dolor.md b/tests/shown/foo/dolor.md
new file mode 100644
index 0000000..e69de29
diff --git a/tests/shown/foo/lorem.txt b/tests/shown/foo/lorem.txt
new file mode 100644
index 0000000..e69de29
diff --git a/tests/withsymlinks/test b/tests/withsymlinks/test
new file mode 100644
index 0000000..dba6882
--- /dev/null
+++ b/tests/withsymlinks/test
@@ -0,0 +1 @@
+aaa bbb ccc ddd
\ No newline at end of file

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-wrench.git



More information about the Pkg-javascript-commits mailing list