Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Bower components Debian packages RPM packages NuGet packages

azuki-trusty / azk   deb

Repository URL to install this package:

Version: 0.5.1 

/ usr / lib / azk / node_modules / q-io / fs.js

/**
 * An asynchronous local file system API, based on a subset
 * of the `narwhal/fs` API and the `narwhal/promise` API,
 * such that the method names are the same but some return
 * values are promises instead of fully resolved values.
 * @module
 */

/*whatsupdoc*/

var FS = require("fs"); // node
var Q = require("q");
var Reader = require("./reader");
var Writer = require("./writer");
var Common = require("./fs-common");
var Mock = require("./fs-mock");
var Root = require("./fs-root");

Common.update(exports, process.cwd);
exports.Mock = Mock;
exports.Root = Root;

// facilitates AIMD (additive increase, multiplicative decrease) for backing off
var backOffDelay = 0;
var backOffFactor = 1.0001;
function dampen(wrapped, thisp) {
    var retry = function () {
        var args = arguments;
        var ready = backOffDelay ? Q.delay(backOffDelay) : Q.resolve();
        return ready.then(function () {
            return Q.when(wrapped.apply(thisp, args), function (stream) {
                backOffDelay = Math.max(0, backOffDelay - 1);
                return stream;
            }, function (error) {
                if (error.code === "EMFILE") {
                    backOffDelay = (backOffDelay + 1) * backOffFactor;
                    return retry.apply(null, args);
                } else {
                    throw error;
                }
            });
        });
    };
    return retry;
}

/**
 * @param {String} path
 * @param {Object} options (flags, mode, bufferSize, charset, begin, end)
 * @returns {Promise * Stream} a stream from the `q-io` module.
 */
exports.open = dampen(function (path, flags, charset, options) {
    var self = this;
    if (typeof flags == "object") {
        options = flags;
        flags = options.flags;
        charset = options.charset;
    }
    options = options || {};
    flags = flags || "r";
    var nodeFlags = flags.replace(/b/g, "") || "r";
    var nodeOptions = {
        "flags": nodeFlags
    };
    if ("bufferSize" in options) {
        nodeOptions.bufferSize = options.bufferSize;
    }
    if ("mode" in options) {
        nodeOptions.mode = options.mode;
    }
    if ("begin" in options) {
        nodeOptions.start = options.begin;
        nodeOptions.end = options.end - 1;
    }
    if (flags.indexOf("b") >= 0) {
        if (charset) {
            throw new Error("Can't open a binary file with a charset: " + charset);
        }
    } else {
        charset = charset || 'utf-8';
    }
    if (flags.indexOf("w") >= 0 || flags.indexOf("a") >= 0) {
        var stream = FS.createWriteStream(String(path), nodeOptions);
        return Writer(stream, charset);
    } else {
        var stream = FS.createReadStream(String(path), nodeOptions);
        return Reader(stream, charset);
    }
});

exports.remove = function (path) {
    path = String(path);
    var done = Q.defer();
    FS.unlink(path, function (error) {
        if (error) {
            error.message = "Can't remove " + JSON.stringify(path) + ": " + error.message;
            done.reject(error);
        } else {
            done.resolve();
        }
    });
    return done.promise;
};

exports.rename = function (source, target) {
    source = String(source);
    target = String(target);
    return Q.ninvoke(FS, "rename", source, target)
    .fail(function (error) {
        if (error.code === "EXDEV") {
            error.message = "source and target are on different devices: " + error.message;
            error.crossDevice = true;
        }
        error.message = (
            "Can't move " + JSON.stringify(source) + " to " +
            JSON.stringify(target) + " because " + error.message
        );
        throw error;
    });
};

exports.makeDirectory = function (path, mode) {
    path = String(path);
    var done = Q.defer();
    if (typeof mode === "string") {
        mode = parseInt(mode, 8);
    } else if (mode === void 0) {
        mode = parseInt('755', 8);
    }
    FS.mkdir(path, mode, function (error) {
        if (error) {
            if (error.code === "EISDIR") {
                error.exists = true;
                error.isDirectory = true;
                error.message = "directory already exists: " + error.message;
            }
            if (error.code === "EEXIST") {
                error.exists = true;
                error.message = "file exists at that path: " + error.message;
            }
            error.message = "Can't makeDirectory " + JSON.stringify(path) + " with mode " + mode + ": " + error.message;
            done.reject(error);
        } else {
            done.resolve();
        }
    });
    return done.promise;
};

exports.removeDirectory = function (path) {
    path = String(path);
    var done = Q.defer();
    FS.rmdir(path, function (error) {
        if (error) {
            error.message = "Can't removeDirectory " + JSON.stringify(path) + ": " + error.message;
            done.reject(error);
        } else {
            done.resolve();
        }
    });
    return done.promise;
};

/**
 */
exports.list = dampen(function (path) {
    path = String(path);
    var result = Q.defer();
    FS.readdir(path, function (error, list) {
        if (error) {
            error.message = "Can't list " + JSON.stringify(path) + ": " + error.message;
            return result.reject(error);
        } else {
            result.resolve(list);
        }
    });
    return result.promise;
});

/**
 * @param {String} path
 * @returns {Promise * Stat}
 */
exports.stat = function (path) {
    var self = this;
    path = String(path);
    var done = Q.defer();
    try {
        FS.stat(path, function (error, stat) {
            if (error) {
                error.message = "Can't stat " + JSON.stringify(path) + ": " + error;
                done.reject(error);
            } else {
                done.resolve(new self.Stats(stat));
            }
        });
    } catch (error) {
        done.reject(error);
    }
    return done.promise;
};

exports.statLink = function (path) {
    path = String(path);
    var done = Q.defer();
    try {
        FS.lstat(path, function (error, stat) {
            if (error) {
                error.message = "Can't statLink " + JSON.stringify(path) + ": " + error.message;
                done.reject(error);
            } else {
                done.resolve(stat);
            }
        });
    } catch (error) {
        done.reject(error);
    }
    return done.promise;
};

exports.statFd = function (fd) {
    fd = Number(fd);
    var done = Q.defer();
    try {
        FS.fstat(fd, function (error, stat) {
            if (error) {
                error.message = "Can't statFd file descriptor " + JSON.stringify(fd) + ": " + error.message;
                done.reject(error);
            } else {
                done.resolve(stat);
            }
        });
    } catch (error) {
        done.reject(error);
    }
    return done.promise;
};

exports.link = function (source, target) {
    source = String(source);
    target = String(target);
    var done = Q.defer();
    try {
        FS.link(source, target, function (error) {
            if (error) {
                error.message = "Can't link " + JSON.stringify(source) + " to " + JSON.stringify(target) + ": " + error.message;
                done.reject(error);
            } else {
                done.resolve();
            }
        });
    } catch (error) {
        done.reject(error);
    }
    return done.promise;
};

// this lookup table translates the link types that Q-IO accepts (which have
// been normalized to full words to be consistent with the naming convention)
var linkTypes = {
    "file": "file",
    "directory": "dir",
    "junction": "junction"
};

exports.symbolicLink = function (target, relative, type) {
    if (!linkTypes.hasOwnProperty(type)) {
        console.warn(new Error("For Windows compatibility, symbolicLink must be called with a type argument \"file\", \"directory\", or \"junction\""));
    }
    type = linkTypes[type];
    target = String(target);
    relative = String(relative);
    var done = Q.defer();
    try {
        FS.symlink(relative, target, type || 'file', function (error) {
            if (error) {
                error.message = "Can't create symbolicLink " + JSON.stringify(target) + " to relative location " + JSON.stringify(relative) + ": " + error.message;
                done.reject(error);
            } else {
                done.resolve();
            }
        });
    } catch (error) {
        done.reject(error);
    }
    return done.promise;
};

exports.chown = function (path, uid, gid) {
    path = String(path);
    var done = Q.defer();
    try {
        FS.chown(path, uid, gid, function (error) {
            if (error) {
                error.message = "Can't chown (change owner) of " + JSON.stringify(path) + " to user " + JSON.stringify(uid) + " and group " + JSON.stringify(gid) + ": " + error.message;
                done.reject(error);
            } else {
                done.resolve();
            }
        });
    } catch (error) {
        done.reject(error);
    }
    return done.promise;
};

exports.chmod = function (path, mode) {
    path = String(path);
    mode = String(mode);
    var done = Q.defer();
    try {
        FS.chmod(path, mode, function (error) {
            if (error) {
                error.message = "Can't chmod (change permissions mode) of " + JSON.stringify(path) + " to (octal number) " + mode.toString(8) + ": " + error.message;
                done.reject(error);
            } else {
                done.resolve();
            }
        });
    } catch (error) {
        done.reject(error);
    }
    return done.promise;
};

exports.canonical = function (path) {
    var result = Q.defer();
    FS.realpath(path, function (error, canonicalPath) {
        if (error) {
            error.message = "Can't get canonical path of " + JSON.stringify(path) + " by way of C realpath: " + error.message;
            result.reject(error);
        } else {
            result.resolve(canonicalPath);
        }
    });
    return result.promise;
};

exports.readLink = function (path) {
    var result = Q.defer();
    FS.readlink(path, function (error, path) {
        if (error) {
            error.message = "Can't get link from " + JSON.stringify(path) + " by way of C readlink: " + error.message;
            result.reject(error);
        } else {
            result.resolve(path);
        }
    });
    return result.promise;
};

exports.mock = function (path) {
    return Mock.mock(this, path);
};