FS

Copyright(c) 2013 Stefano Balietti MIT Licensed

Collection of static functions related to file system operations.

(function(JSUS) {

    if (!JSUS.isNodeJS()){
        JSUS.log('Cannot load JSUS.FS outside of Node.JS.')
        return false;
    }

    var resolve = require('resolve'),
    path = require('path'),
    fs = require('fs'),
    wrench = require('wrench');


    function FS(){};

FS.resolveModuleDir

Backward-compatible version of fs.existsSync

    FS.existsSync = ('undefined' === typeof fs.existsSync) ?
        path.existsSync : fs.existsSync;

FS.resolveModuleDir

Resolves the root directory of a module

Npm does not install a dependency if the same module is available in a parent folder. This method returns the full path of the root directory of the specified module as installed by npm.

Trailing slash is added.

Params
module string The name of the module
basedir string Optional The basedir from which starting searching
Returns
string The path of the root directory of the module
See
    FS.resolveModuleDir = function(module, basedir) {
        var str, stop;
        if (!module) return false;

        str = resolve.sync(module, {basedir: basedir || __dirname});
        stop = str.indexOf(module) + module.length;
        return str.substr(0, stop) + '/';
    };

FS.deleteIfExists

Deletes a file or directory

Returns false if the file does not exist.

Params
file string The path to the file or directory
Returns
boolean TRUE, if operation is succesfull
See
FS.cleanDir
    FS.deleteIfExists = function(file) {
        if (!FS.existsSync(file)) {
            return false;
        }
        var stats = fs.lstatSync(file);
        if (stats.isDirectory()) {
            fs.rmdir(file, function(err) {
                if (err) throw err;
            });
        }
        else {
            fs.unlink(file, function(err) {
                if (err) throw err;
            });
        }
        return true;

    };

FS.cleanDir

Removes all files from a target directory

It is possible to specify an extension as second parameter. In such case, only file with that extension will be removed. The '.' (dot) must be included as part of the extension.

Params
dir string The directory to clean
ext string Optional. If set, only files with this extension will be removed
cb function Optional. A callback function to call if no error is raised
Returns
boolean TRUE, if the operation is successful
See
FS.deleteIfExists
    FS.cleanDir = function(dir, ext, cb) {
        var fileterFunc;
        if (!dir) {
            JSUS.log('You must specify a directory to clean.');
            return false;
        }
        if (ext) {
            filterFunc = function(file) {
                return path.extname(file) ===  ext;
            };
        }
        else {
            filterFunc = function(file) {
                return true;
            };
        }

        if (dir[dir.length] !== '/') dir = dir + '/';

        fs.readdir(dir, function(err, files) {
            if (err) {
                JSUS.log(err);
                return false;
            }

            files.filter(filterFunc)
                .forEach(function(file) {
                    JSUS.deleteIfExists(dir + file);
                });

            if (cb) return cb(null);

        });


        return true;
    };

FS.copyFromDir

Copies all files from a source directory to a destination directory.

It is possible to specify an extension as second parameter (e.g. '.js'). In such case, only file with that extension will be copied.

Warning! If an extension filter is not specified, and if subdirectories are found, an error will occur.

Params
dirIn string The source directory
dirOut string The destination directory
ext string Optional. If set, only files with this extension will be copied
cb function Optional. A callback function to call if no error is raised
Returns
boolean TRUE, if the operation is successful
See
FS.copyFile
    FS.copyFromDir = function(dirIn, dirOut, ext, cb) {
        if (!dirIn) {
            JSUS.log('You must specify a source directory');
            return false;
        }
        if (!dirOut) {
            JSUS.log('You must specify a destination directory');
            return false;
        }

        dirOut = path.resolve(dirOut) + '/';
        var i, dir, dirs = [dirIn, dirOut];
        for (i=0; i < 2; i++) {
            dir = dirs[i];
            if (!FS.existsSync(dir)) {
                console.log(dir + ' does not exist');
                return false;
            }

            var stats = fs.lstatSync(dir);
            if (!stats.isDirectory()) {
                console.log(dir + ' is not a directory');
                return false;
            }
        }

        fs.readdir(dirIn, function(err, files){
            if (err) {
                JSUS.log(err);
                throw new Error;
            }
            for (var i in files) {
                if (ext && path.extname(files[i]) !== ext) {
                    continue;
                }
                copyFile(dirIn + files[i], dirOut + files[i]);
            }

            if (cb) return cb(null);
        });

        return true;
    };

FS.copyFile

Copies a file into another path

Params
srcFile string The source file
destFile string The destination file
cb function Optional. If set, the callback will be executed upon success
cb function Optional. A callback function to call if no error is raised
Returns
boolean TRUE, if the operation is successful
See
    var copyFile = function(srcFile, destFile, cb) {
        var fdr, fdw;
        fdr = fs.createReadStream(srcFile);
        fdw = fs.createWriteStream(destFile);
        fdr.on('end', function() {
            if (cb) return cb(null);
        });
        return fdr.pipe(fdw);
    };

wrench

FS exposes the properties of the great package wrench for performing recursive operations on directories

@see https://github.com/ryanmcgrath/wrench-js

    (function() {
        for (var w in wrench) {
            if (wrench.hasOwnProperty(w)) {
                FS[w] = wrench[w];
            }
        }

    })();
    JSUS.extend(FS);

})('undefined' !== typeof JSUS ? JSUS : module.parent.exports.JSUS);