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-common.js

var Q = require("q");
var Boot = require("./fs-boot");
var RootFs = require("./fs-root");
var MockFs = require("./fs-mock");

// TODO patternToRegExp
// TODO glob
// TODO match

var concat = function (arrays) {
    return Array.prototype.concat.apply([], arrays);
};

exports.update = function (exports, workingDirectory) {

    for (var name in Boot) {
        exports[name] = Boot[name];
    }

    /**
     * Read a complete file.
     * @param {String} path    Path to the file.
     * @param {String} [options.flags]  The mode to open the file with.
     * @param {String} [options.charset]  The charset to open the file with.
     * @param {Object} [options]   An object with options.
     * second argument.
     * @returns {Promise * (String || Buffer)}
     */
    exports.read = function (path, flags, charset, options) {
        if (typeof flags === "object") {
            options = flags;
        } else if (typeof charset === "object") {
            options = charset;
            options.flags = flags;
        } else {
            options = options || {};
            options.flags = flags;
            options.charset = charset;
        }
        options.flags = options.flags || "r";
        return Q.when(this.open(path, options), function (stream) {
            return stream.read();
        }, function (error) {
            error.message = "Can't read " + path + " because " + error.message;
            error.path = path;
            error.flags = flags;
            error.charset = charset;
            throw error;
        });
    };

    /**
     * Write content to a file, overwriting the existing content.
     * @param {String} path    Path to the file.
     * @param {String || Buffer} content
     * @param {String} [options.flags]  The mode to open the file with.
     * @param {String} [options.charset]  The charset to open the file with.
     * @param {Object} [options]   An object with options.
     * @returns {Promise * Undefined} a promise that resolves
     * when the writing is complete.
     */
    exports.write = function (path, content, flags, charset, options) {
        var self = this;
        if (typeof flags === "object") {
            options = flags;
        } else if (typeof charset === "object") {
            options = charset;
            options.flags = flags;
        } else {
            options = options || {};
            options.flags = flags;
            options.charset = charset;
        }
        flags = options.flags || "w";
        if (flags.indexOf("b") !== -1) {
            if (!(content instanceof Buffer)) {
                content = new Buffer(content);
            }
        } else if (content instanceof Buffer) {
            flags += "b";
        }
        options.flags = flags;
        return Q.when(self.open(path, options), function (stream) {
            return Q.when(stream.write(content), function () {
                return stream.close();
            });
        });
    };

    /**
     * Append content to the end of a file.
     * @param {String} path    Path to the file.
     * @param {String || Buffer} content
     * @param {String} [options.flags]  The mode to open the file with.
     * @param {String} [options.charset]  The charset to open the file with.
     * @param {Object} [options]   An object with options.
     * @returns {Promise * Undefined} a promise that resolves
     * when the writing is complete.
     */
    exports.append = function (path, content, flags, charset, options) {
        var self = this;
        if (typeof flags === "object") {
            options = flags;
        } else if (typeof charset === "object") {
            options = charset;
            options.flags = flags;
        } else {
            options = options || {};
            options.flags = flags;
            options.charset = charset;
        }
        flags = options.flags || "a";
        if (content instanceof Buffer) {
            flags += "b";
        }
        options.flags = flags;
        return Q.when(self.open(path, options), function (stream) {
            return Q.when(stream.write(content), function () {
                return stream.close();
            });
        });
    };

    exports.move = function (source, target) {
        var self = this;
        return this.rename(source, target)
        .catch(function (error) {
            if (error.crossDevice) {
                return self.copyTree(source, target)
                .then(function () {
                    return self.removeTree(source);
                });
            } else {
                throw error;
            }
        });
    };

    exports.copy = function (source, target) {
        var self = this;
        return Q.when(self.stat(source), function (stat) {
            var mode = stat.node.mode;
            return Q.all([
                self.open(source, {flags: "rb"}),
                self.open(target, {flags: "wb", mode: mode})
            ]);
        })
        .spread(function (reader, writer) {
            return Q.when(reader.forEach(function (block) {
                return writer.write(block);
            }), function () {
                return Q.all([
                    reader.close(),
                    writer.close()
                ]);
            });
        });
    };

    exports.copyTree = function (source, target) {
        var self = this;
        return Q.when(self.stat(source), function (stat) {
            if (stat.isFile()) {
                return self.copy(source, target);
            } else if (stat.isDirectory()) {
                return self.exists(target).then(function (targetExists) {
                    function copySubTree() {
                        return Q.when(self.list(source), function (list) {
                            return Q.all(list.map(function (child) {
                                return self.copyTree(
                                    self.join(source, child),
                                    self.join(target, child)
                                );
                            }));
                        });
                    }
                    if (targetExists) {
                        return copySubTree();
                    } else {
                        return Q.when(self.makeDirectory(target, stat.node.mode), copySubTree);
                    }
                });
            } else if (stat.isSymbolicLink()) {
                // TODO copy the link and type with readPath (but what about
                // Windows junction type?)
                return self.symbolicCopy(source, target);
            }
        });
    };

    exports.listTree = function (basePath, guard) {
        var self = this;
        basePath = String(basePath || '');
        if (!basePath)
            basePath = ".";
        guard = guard || function () {
            return true;
        };
        var stat = self.stat(basePath);
        return Q.when(stat, function (stat) {
            var paths = [];
            var mode; // true:include, false:exclude, null:no-recur
            try {
                var include = guard(basePath, stat);
            } catch (exception) {
                return Q.reject(exception);
            }
            return Q.when(include, function (include) {
                if (include) {
                    paths.push([basePath]);
                }
                if (include !== null && stat.isDirectory()) {
                    return Q.when(self.list(basePath), function (children) {
                        paths.push.apply(paths, children.map(function (child) {
                            var path = self.join(basePath, child);
                            return self.listTree(path, guard);
                        }));
                        return paths;
                    });
                } else {
                    return paths;
                }
            });
        }, function noSuchFile(reason) {
            return [];
        }).then(Q.all).then(concat);
    };

    exports.listDirectoryTree = function (path) {
        return this.listTree(path, function (path, stat) {
            return stat.isDirectory();
        });
    };

    exports.makeTree = function (path, mode) {
        path = String(path);
        var self = this;
        var parts = self.split(path);
        var at = [];
        if (self.isAbsolute(path)) {
            // On Windows use the root drive (e.g. "C:"), on *nix the first
            // part is the falsey "", and so use the ROOT ("/")
            at.push(parts.shift() || self.ROOT);
        }
        return parts.reduce(function (parent, part) {
            return Q.when(parent, function () {
                at.push(part);
                var parts = self.join(at) || ".";
                var made = self.makeDirectory(parts, mode);
                return Q.when(made, null, function rejected(error) {
                    // throw away errors for already made directories
                    if (error.exists) {
                        return;
                    } else {
                        throw error;
                    }
                });
            });
        }, undefined);
    };

    exports.removeTree = function (path) {
        var self = this;
        return Q.when(self.statLink(path), function (stat) {
            if (stat.isSymbolicLink()) {
                return self.remove(path);
            } else if (stat.isDirectory()) {
                return self.list(path)
                .then(function (list) {
                    // asynchronously remove every subtree
                    return Q.all(list.map(function (name) {
                        return self.removeTree(self.join(path, name));
                    }))
                    .then(function () {
                        return self.removeDirectory(path);
                    });
                });
            } else {
                return self.remove(path);
            }
        });
    };

    exports.symbolicCopy = function (source, target, type) {
        var self = this;
        return Q.when(self.relative(target, source), function (relative) {
            return self.symbolicLink(target, relative, type || "file");
        });
    };

    exports.exists = function (path) {
        return Q.when(this.stat(path), function () {
            return true;
        }, function () {
            return false;
        });
    };

    exports.isFile = function (path) {
        return Q.when(this.stat(path), function (stat) {
            return stat.isFile();
        }, function (reason) {
            return false;
        });
    };

    exports.isDirectory = function (path) {
        return Q.when(this.stat(path), function (stat) {
            return stat.isDirectory();
        }, function (reason) {
            return false;
        });
    };

    exports.isSymbolicLink = function (path) {
        return Q.when(this.statLink(path), function (stat) {
            return stat.isSymbolicLink();
        }, function (reason) {
            return false;
        });
    };

    exports.lastModified = function (path) {
        var self = this;
        return self.stat(path).invoke('lastModified');
    };

    exports.lastAccessed = function (path) {
        var self = this;
        return self.stat(path).invoke('lastAccessed');
    };

    exports.absolute = function (path) {
        if (this.isAbsolute(path))
            return this.normal(path);
        return this.join(workingDirectory(), path);
    };

    exports.relative = function (source, target) {
        var self = this;
        return Q.when(this.isDirectory(source), function (isDirectory) {
            if (isDirectory) {
                return self.relativeFromDirectory(source, target);
            } else {
                return self.relativeFromFile(source, target);
            }
        });
    };

    exports.relativeFromFile = function (source, target) {
        var self = this;
        source = self.absolute(source);
        target = self.absolute(target);
        source = source.split(self.SEPARATORS_RE());
        target = target.split(self.SEPARATORS_RE());
        source.pop();
        while (
            source.length &&
            target.length &&
            target[0] == source[0]
        ) {
            source.shift();
            target.shift();
        }
        while (source.length) {
            source.shift();
            target.unshift("..");
        }
        return target.join(self.SEPARATOR);
    };

    exports.relativeFromDirectory = function (source, target) {
        if (!target) {
            target = source;
            source = workingDirectory();
        }
        source = this.absolute(source);
        target = this.absolute(target);
        source = source.split(this.SEPARATORS_RE());
        target = target.split(this.SEPARATORS_RE());
        if (source.length === 2 && source[1] === "")
            source.pop();
        while (
            source.length &&
            target.length &&
            target[0] == source[0]
        ) {
            source.shift();
            target.shift();
        }
        while (source.length) {
            source.shift();
            target.unshift("..");
        }
        return target.join(this.SEPARATOR);
    };

    exports.contains = function (parent, child) {
        var i, ii;
        parent = this.absolute(parent);
        child = this.absolute(child);
        parent = parent.split(this.SEPARATORS_RE());
        child = child.split(this.SEPARATORS_RE());
        if (parent.length === 2 && parent[1] === "")
            parent.pop();
        if (parent.length > child.length)
            return false;
        for (i = 0, ii = parent.length; i < ii; i++) {
            if (parent[i] !== child[i])
                break;
        }
        return i == ii;
    };

    exports.reroot = reroot;
    function reroot(path) {
        var self = this;
        path = path || this.ROOT;
        return RootFs(self, path);
    }

    exports.toObject = function (path) {
        var self = this;
        var list = self.listTree(path || "", function (path, stat) {
            return stat.isFile();
        });
        return Q.when(list, function (list) {
            var tree = {};
            return Q.all(list.map(function (path) {
                return Q.when(self.read(path, "rb"), function (content) {
                    tree[path] = content;
                });
            })).then(function () {
                return tree;
            });
        });
    };

    exports.merge = function (fss) {
        var tree = {};
        var done;
        fss.forEach(function (fs) {
            done = Q.when(done, function () {
                return fs.listTree("", function (path, stat) {
                    return stat.isFile();
                })
                .then(function (list) {
                    return Q.all(list.map(function (path) {
                        return Q.when(fs.read(path, "rb"), function (content) {
                            tree[path] = content;
                        });
                    }));
                });
            });
        })
        return Q.when(done, function () {
            return MockFs(tree);
        });
    };

    exports.Stats = Stats;
    function Stats(nodeStat) {
        this.node = nodeStat;
        this.size = nodeStat.size;
    }

    var stats = [
        "isDirectory",
        "isFile",
        "isBlockDevice",
        "isCharacterDevice",
        "isSymbolicLink",
        "isFIFO",
        "isSocket"
    ];

    stats.forEach(function (name) {
        Stats.prototype[name] = function () {
            return this.node[name]();
        };
    });

    Stats.prototype.lastModified = function () {
        return new Date(this.node.mtime);
    };

    Stats.prototype.lastAccessed = function () {
        return new Date(this.node.atime);
    };

}