"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/wrench/lib/wrench.js" (8 Mar 2017, 17940 Bytes) of archive /windows/misc/atom-windows.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Javascript source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*  wrench.js
    2  *
    3  *  A collection of various utility functions I've found myself in need of
    4  *  for use with Node.js (http://nodejs.org/). This includes things like:
    5  *
    6  *  - Recursively deleting directories in Node.js (Sync, not Async)
    7  *  - Recursively copying directories in Node.js (Sync, not Async)
    8  *  - Recursively chmoding a directory structure from Node.js (Sync, not Async)
    9  *  - Other things that I'll add here as time goes on. Shhhh...
   10  *
   11  *  ~ Ryan McGrath (ryan [at] venodesigns.net)
   12  */
   13 
   14 var fs = require("fs"),
   15     _path = require("path"),
   16     isWindows = !!process.platform.match(/^win/);
   17 
   18 /*  wrench.readdirSyncRecursive("directory_path");
   19  *
   20  *  Recursively dives through directories and read the contents of all the
   21  *  children directories.
   22  */
   23 exports.readdirSyncRecursive = function(baseDir) {
   24     baseDir = baseDir.replace(/\/$/, '');
   25 
   26     var readdirSyncRecursive = function(baseDir) {
   27         var files = [],
   28             curFiles,
   29             nextDirs,
   30             isDir = function(fname){
   31                 return fs.existsSync(_path.join(baseDir, fname)) ? fs.statSync( _path.join(baseDir, fname) ).isDirectory() : false;
   32             },
   33             prependBaseDir = function(fname){
   34                 return _path.join(baseDir, fname);
   35             };
   36 
   37         curFiles = fs.readdirSync(baseDir);
   38         nextDirs = curFiles.filter(isDir);
   39         curFiles = curFiles.map(prependBaseDir);
   40 
   41         files = files.concat( curFiles );
   42 
   43         while (nextDirs.length) {
   44             files = files.concat( readdirSyncRecursive( _path.join(baseDir, nextDirs.shift()) ) );
   45         }
   46 
   47         return files;
   48     };
   49 
   50     // convert absolute paths to relative
   51     var fileList = readdirSyncRecursive(baseDir).map(function(val){
   52         return _path.relative(baseDir, val);
   53     });
   54 
   55     return fileList;
   56 };
   57 
   58 /*  wrench.readdirRecursive("directory_path", function(error, files) {});
   59  *
   60  *  Recursively dives through directories and read the contents of all the
   61  *  children directories.
   62  *
   63  *  Asynchronous, so returns results/error in callback.
   64  *  Callback receives the of files in currently recursed directory.
   65  *  When no more directories are left, callback is called with null for all arguments.
   66  *
   67  */
   68 exports.readdirRecursive = function(baseDir, fn) {
   69     baseDir = baseDir.replace(/\/$/, '');
   70 
   71     var waitCount = 0;
   72 
   73     function readdirRecursive(curDir) {
   74         var prependcurDir = function(fname){
   75             return _path.join(curDir, fname);
   76         };
   77 
   78         waitCount++;
   79         fs.readdir(curDir, function(e, curFiles) {
   80             if (e) {
   81                 fn(e);
   82                 return;
   83             }
   84             waitCount--;
   85 
   86             curFiles = curFiles.map(prependcurDir);
   87 
   88             curFiles.forEach(function(it) {
   89                 waitCount++;
   90 
   91                 fs.stat(it, function(e, stat) {
   92                     waitCount--;
   93 
   94                     if (e) {
   95                         fn(e);
   96                     } else {
   97                         if (stat.isDirectory()) {
   98                             readdirRecursive(it);
   99                         }
  100                     }
  101 
  102                     if (waitCount == 0) {
  103                         fn(null, null);
  104                     }
  105                 });
  106             });
  107 
  108             fn(null, curFiles.map(function(val) {
  109                 // convert absolute paths to relative
  110                 return _path.relative(baseDir, val);
  111             }));
  112 
  113             if (waitCount == 0) {
  114                 fn(null, null);
  115             }
  116         });
  117     };
  118 
  119     readdirRecursive(baseDir);
  120 };
  121 
  122 
  123 
  124 
  125 
  126 /*  wrench.rmdirSyncRecursive("directory_path", failSilent);
  127  *
  128  *  Recursively dives through directories and obliterates everything about it. This is a
  129  *  Sync-function, which blocks things until it's done. No idea why anybody would want an
  130  *  Asynchronous version. :\
  131  */
  132 exports.rmdirSyncRecursive = function(path, failSilent) {
  133     var files;
  134 
  135     try {
  136         files = fs.readdirSync(path);
  137     } catch (err) {
  138 
  139         if(failSilent) return;
  140         throw new Error(err.message);
  141     }
  142 
  143     /*  Loop through and delete everything in the sub-tree after checking it */
  144     for(var i = 0; i < files.length; i++) {
  145         var file = _path.join(path, files[i]);
  146         var currFile = fs.lstatSync(file);
  147 
  148         if(currFile.isDirectory())  {
  149             // Recursive function back to the beginning
  150             exports.rmdirSyncRecursive(file);
  151         } else if(currFile.isSymbolicLink()) {
  152             // Unlink symlinks
  153             if (isWindows) {
  154                 fs.chmodSync(file, 666) // Windows needs this unless joyent/node#3006 is resolved..
  155             }
  156 
  157             fs.unlinkSync(file);
  158         } else {
  159             // Assume it's a file - perhaps a try/catch belongs here?
  160             if (isWindows) {
  161                 fs.chmodSync(file, 666) // Windows needs this unless joyent/node#3006 is resolved..
  162             }
  163 
  164             fs.unlinkSync(file);
  165         }
  166     }
  167 
  168     /*  Now that we know everything in the sub-tree has been deleted, we can delete the main
  169      directory. Huzzah for the shopkeep. */
  170     return fs.rmdirSync(path);
  171 };
  172 
  173 
  174 
  175 function isFileIncluded(opts, dir, filename) {
  176 
  177     function isMatch(filter) {
  178         if (typeof filter === 'function') {
  179             return filter(filename, dir) === true;
  180         }
  181         else {
  182             // Maintain backwards compatibility and use just the filename
  183             return filename.match(filter);
  184         }
  185     }
  186 
  187     if (opts.include || opts.exclude) {
  188         if (opts.exclude) {
  189             if (isMatch(opts.exclude)) {
  190                 return false;
  191             }
  192         }
  193 
  194         if (opts.include) {
  195             if (isMatch(opts.include)) {
  196                 return true;
  197             }
  198             else  {
  199                 return false;
  200             }
  201         }
  202 
  203         return true;
  204     }
  205     else if (opts.filter) {
  206         var filter = opts.filter;
  207 
  208         if (!opts.whitelist) {
  209             // if !opts.whitelist is false every file or directory 
  210             // which does match opts.filter will be ignored
  211             return isMatch(filter) ? false : true;
  212         } else {
  213             // if opts.whitelist is true every file or directory 
  214             // which doesn't match opts.filter will be ignored
  215             return !isMatch(filter) ? false : true;
  216         }
  217     }
  218 
  219     return true;
  220 }
  221 
  222 /*  wrench.copyDirSyncRecursive("directory_to_copy", "new_directory_location", opts);
  223  *
  224  *  Recursively dives through a directory and moves all its files to a new location. This is a
  225  *  Synchronous function, which blocks things until it's done. If you need/want to do this in
  226  *  an Asynchronous manner, look at wrench.copyDirRecursively() below. Specify forceDelete to force directory overwrite.
  227  *
  228  *  Note: Directories should be passed to this function without a trailing slash.
  229  */
  230 exports.copyDirSyncRecursive = function(sourceDir, newDirLocation, opts) {
  231     opts = opts || {};
  232 
  233     try {
  234         if(fs.statSync(newDirLocation).isDirectory()) { 
  235             if(opts.forceDelete) {
  236             exports.rmdirSyncRecursive(newDirLocation);
  237             } else {
  238                 return new Error('You are trying to delete a directory that already exists. Specify forceDelete in the opts argument to override this. Bailing~');
  239             }
  240         }
  241     } catch(e) { }
  242 
  243     /*  Create the directory where all our junk is moving to; read the mode of the source directory and mirror it */
  244     var checkDir = fs.statSync(sourceDir);
  245     try {
  246         fs.mkdirSync(newDirLocation, checkDir.mode);
  247     } catch (e) {
  248         //if the directory already exists, that's okay
  249         if (e.code !== 'EEXIST') throw e;
  250     }
  251 
  252     var files = fs.readdirSync(sourceDir);
  253     var hasFilter = opts.filter || opts.include || opts.exclude;
  254     var preserveFiles = opts.preserveFiles === true;
  255     var preserveTimestamps = opts.preserveTimestamps === true;
  256 
  257     for(var i = 0; i < files.length; i++) {
  258         // ignores all files or directories which match the RegExp in opts.filter
  259         if(typeof opts !== 'undefined') {
  260             if (hasFilter) {
  261                 if (!isFileIncluded(opts, sourceDir, files[i])) {
  262                     continue;
  263                 }
  264             }
  265             
  266             if (opts.excludeHiddenUnix && /^\./.test(files[i])) continue;
  267         }
  268 
  269         var currFile = fs.lstatSync(_path.join(sourceDir, files[i]));
  270 
  271         var fCopyFile = function(srcFile, destFile) {
  272             if(typeof opts !== 'undefined' && opts.preserveFiles && fs.existsSync(destFile)) return;
  273 
  274             var contents = fs.readFileSync(srcFile);
  275             fs.writeFileSync(destFile, contents);
  276             var stat =  fs.lstatSync(srcFile);
  277             fs.chmodSync(destFile, stat.mode);
  278             if (preserveTimestamps) {
  279                 fs.utimesSync(destFile, stat.atime, stat.mtime)
  280             }
  281         };
  282 
  283         if(currFile.isDirectory()) {
  284             /*  recursion this thing right on back. */
  285             exports.copyDirSyncRecursive(_path.join(sourceDir, files[i]), _path.join(newDirLocation, files[i]), opts);
  286         } else if(currFile.isSymbolicLink()) {
  287             var symlinkFull = fs.readlinkSync(_path.join(sourceDir, files[i]));
  288             symlinkFull = _path.resolve(fs.realpathSync(sourceDir), symlinkFull);
  289 
  290             if (typeof opts !== 'undefined' && !opts.inflateSymlinks) {
  291                 fs.symlinkSync(symlinkFull, _path.join(newDirLocation, files[i]));
  292                 continue;
  293             }
  294 
  295             var tmpCurrFile = fs.lstatSync(symlinkFull);
  296             if (tmpCurrFile.isDirectory()) {
  297                 exports.copyDirSyncRecursive(symlinkFull, _path.join(newDirLocation, files[i]), opts);
  298             } else {
  299                 /*  At this point, we've hit a file actually worth copying... so copy it on over. */
  300                 fCopyFile(symlinkFull, _path.join(newDirLocation, files[i]));
  301             }
  302         } else {
  303             /*  At this point, we've hit a file actually worth copying... so copy it on over. */
  304             fCopyFile(_path.join(sourceDir, files[i]), _path.join(newDirLocation, files[i]));
  305         }
  306     }
  307 };
  308 
  309 /*  wrench.chmodSyncRecursive("directory", filemode);
  310  *
  311  *  Recursively dives through a directory and chmods everything to the desired mode. This is a
  312  *  Synchronous function, which blocks things until it's done.
  313  *
  314  *  Note: Directories should be passed to this function without a trailing slash.
  315  */
  316 exports.chmodSyncRecursive = function(sourceDir, filemode) {
  317     var files = fs.readdirSync(sourceDir);
  318 
  319     for(var i = 0; i < files.length; i++) {
  320         var currFile = fs.lstatSync(_path.join(sourceDir, files[i]));
  321 
  322         if(currFile.isDirectory()) {
  323             /*  ...and recursion this thing right on back. */
  324             exports.chmodSyncRecursive(_path.join(sourceDir, files[i]), filemode);
  325         } else {
  326             /*  At this point, we've hit a file actually worth copying... so copy it on over. */
  327             fs.chmod(_path.join(sourceDir, files[i]), filemode);
  328         }
  329     }
  330 
  331     /*  Finally, chmod the parent directory */
  332     fs.chmod(sourceDir, filemode);
  333 };
  334 
  335 
  336 /*  wrench.chownSyncRecursive("directory", uid, gid);
  337  *
  338  *  Recursively dives through a directory and chowns everything to the desired user and group. This is a
  339  *  Synchronous function, which blocks things until it's done.
  340  *
  341  *  Note: Directories should be passed to this function without a trailing slash.
  342  */
  343 exports.chownSyncRecursive = function(sourceDir, uid, gid) {
  344     var files = fs.readdirSync(sourceDir);
  345 
  346     for(var i = 0; i < files.length; i++) {
  347         var currFile = fs.lstatSync(_path.join(sourceDir, files[i]));
  348 
  349         if(currFile.isDirectory()) {
  350             /*  ...and recursion this thing right on back. */
  351             exports.chownSyncRecursive(_path.join(sourceDir, files[i]), uid, gid);
  352         } else {
  353             /*  At this point, we've hit a file actually worth chowning... so own it. */
  354             fs.chownSync(_path.join(sourceDir, files[i]), uid, gid);
  355         }
  356     }
  357 
  358     /*  Finally, chown the parent directory */
  359     fs.chownSync(sourceDir, uid, gid);
  360 };
  361 
  362 
  363 
  364 /*  wrench.rmdirRecursive("directory_path", callback);
  365  *
  366  *  Recursively dives through directories and obliterates everything about it.
  367  */
  368 exports.rmdirRecursive = function rmdirRecursive(dir, failSilent, clbk){
  369     if(clbk === null || typeof clbk == 'undefined')
  370         clbk = function(err) {};
  371 
  372     fs.readdir(dir, function(err, files) {
  373         if(err && typeof failSilent === 'boolean' && !failSilent) 
  374         return clbk(err);
  375 
  376         if(typeof failSilent === 'function')
  377             clbk = failSilent;
  378         
  379         (function rmFile(err){
  380             if (err) return clbk(err);
  381 
  382             var filename = files.shift();
  383             if (filename === null || typeof filename == 'undefined')
  384                 return fs.rmdir(dir, clbk);
  385 
  386             var file = dir+'/'+filename;
  387             fs.lstat(file, function(err, stat){
  388                 if (err) return clbk(err);
  389                 if (stat.isDirectory())
  390                     rmdirRecursive(file, rmFile);
  391                 else
  392                     fs.unlink(file, rmFile);
  393             });
  394         })();
  395     });
  396 };
  397 
  398 /*  wrench.copyDirRecursive("directory_to_copy", "new_location", {forceDelete: bool}, callback);
  399  *
  400  *  Recursively dives through a directory and moves all its files to a new
  401  *  location. Specify forceDelete to force directory overwrite.
  402  *
  403  *  Note: Directories should be passed to this function without a trailing slash.
  404  */
  405 exports.copyDirRecursive = function copyDirRecursive(srcDir, newDir, opts, clbk) {
  406     var originalArguments = Array.prototype.slice.apply(arguments);
  407     srcDir = _path.normalize(srcDir);
  408     newDir = _path.normalize(newDir);
  409 
  410     fs.stat(newDir, function(err, newDirStat) {
  411         if(!err) {
  412             if(typeof opts !== 'undefined' && typeof opts !== 'function' && opts.forceDelete)
  413                 return exports.rmdirRecursive(newDir, function(err) {
  414                     copyDirRecursive.apply(this, originalArguments);
  415                 });
  416             else
  417                 return clbk(new Error('You are trying to delete a directory that already exists. Specify forceDelete in an options object to override this.'));
  418         }
  419 
  420     if(typeof opts === 'function')
  421         clbk = opts;
  422 
  423         fs.stat(srcDir, function(err, srcDirStat){
  424             if (err) return clbk(err);
  425             fs.mkdir(newDir, srcDirStat.mode, function(err){
  426                 if (err) return clbk(err);
  427                 fs.readdir(srcDir, function(err, files){
  428                     if (err) return clbk(err);
  429                     (function copyFiles(err){
  430                         if (err) return clbk(err);
  431 
  432                         var filename = files.shift();
  433                         if (filename === null || typeof filename == 'undefined')
  434                             return clbk(null);
  435 
  436                         var file = srcDir+'/'+filename,
  437                             newFile = newDir+'/'+filename;
  438 
  439                         fs.stat(file, function(err, fileStat){
  440                             if (err) return clbk(err);
  441                             if (fileStat.isDirectory())
  442                                 copyDirRecursive(file, newFile, copyFiles, clbk);
  443                             else if (fileStat.isSymbolicLink())
  444                                 fs.readlink(file, function(err, link){
  445                                     if (err) return clbk(err);
  446                                     fs.symlink(link, newFile, copyFiles);
  447                                 });
  448                             else
  449                                 fs.readFile(file, function(err, data){
  450                                     if (err) return clbk(err);
  451                                     fs.writeFile(newFile, data, copyFiles);
  452                                 });
  453                         });
  454                     })();
  455                 });
  456             });
  457         });
  458     });
  459 };
  460 
  461 var mkdirSyncRecursive = function(path, mode) {
  462     var self = this;
  463     path = _path.normalize(path)
  464 
  465     try {
  466         fs.mkdirSync(path, mode);
  467     } catch(err) {
  468         if(err.code == "ENOENT") {
  469             var slashIdx = path.lastIndexOf(_path.sep);
  470 
  471             if(slashIdx > 0) {
  472                 var parentPath = path.substring(0, slashIdx);
  473                 mkdirSyncRecursive(parentPath, mode);
  474                 mkdirSyncRecursive(path, mode);
  475             } else {
  476                 throw err;
  477             }
  478         } else if(err.code == "EEXIST") {
  479             return;
  480         } else {
  481             throw err;
  482         }
  483     }
  484 };
  485 exports.mkdirSyncRecursive = mkdirSyncRecursive;
  486 
  487 exports.LineReader = function(filename, bufferSize) {
  488     this.bufferSize = bufferSize || 8192;
  489     this.buffer = "";
  490     this.fd = fs.openSync(filename, "r");
  491     this.currentPosition = 0;
  492 };
  493 
  494 exports.LineReader.prototype = {
  495     close: function() {
  496         return fs.closeSync(this.fd);
  497     },
  498 
  499     getBufferAndSetCurrentPosition: function(position) {
  500         var res = fs.readSync(this.fd, this.bufferSize, position, "ascii");
  501 
  502         this.buffer += res[0];
  503         if(res[1] === 0) {
  504             this.currentPosition = -1;
  505         } else {
  506             this.currentPosition = position + res[1];
  507         }
  508 
  509         return this.currentPosition;
  510     },
  511 
  512     hasNextLine: function() {
  513         while(this.buffer.indexOf('\n') === -1) {
  514             this.getBufferAndSetCurrentPosition(this.currentPosition);
  515             if(this.currentPosition === -1) return false;
  516         }
  517 
  518         if(this.buffer.indexOf("\n") > -1 || this.buffer.length !== 0) return true;
  519         return false;
  520     },
  521 
  522     getNextLine: function() {
  523         var lineEnd = this.buffer.indexOf("\n"),
  524             result = this.buffer.substring(0, lineEnd != -1 ? lineEnd : this.buffer.length);
  525 
  526         this.buffer = this.buffer.substring(result.length + 1, this.buffer.length);
  527         return result;
  528     }
  529 };
  530 
  531 // vim: et ts=4 sw=4