123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- var path = require('path');
- var fs = require('fs');
- var assert = require("assert");
- // file.mkdirs
- //
- // Given a path to a directory, create it, and all the intermediate directories
- // as well
- //
- // @path: the path to create
- // @mode: the file mode to create the directory with:
- // ex: file.mkdirs("/tmp/dir", 755, function () {})
- // @callback: called when finished.
- exports.mkdirs = function (_path, mode, callback) {
- _path = exports.path.abspath(_path);
- var dirs = _path.split(path.sep);
- var walker = [dirs.shift()];
- // walk
- // @ds: A list of directory names
- // @acc: An accumulator of walked dirs
- // @m: The mode
- // @cb: The callback
- var walk = function (ds, acc, m, cb) {
- if (ds.length > 0) {
- var d = ds.shift();
- acc.push(d);
- var dir = acc.join(path.sep);
- // look for dir on the fs, if it doesn't exist then create it, and
- // continue our walk, otherwise if it's a file, we have a name
- // collision, so exit.
- fs.stat(dir, function (err, stat) {
- // if the directory doesn't exist then create it
- if (err) {
- // 2 means it's wasn't there
- if (err.errno == 2 || err.errno == 34) {
- fs.mkdir(dir, m, function (erro) {
- if (erro && erro.errno != 17 && erro.errno != 34) {
- return cb(erro);
- } else {
- return walk(ds, acc, m, cb);
- }
- });
- } else {
- return cb(err);
- }
- } else {
- if (stat.isDirectory()) {
- return walk(ds, acc, m, cb);
- } else {
- return cb(new Error("Failed to mkdir " + dir + ": File exists\n"));
- }
- }
- });
- } else {
- return cb();
- }
- };
- return walk(dirs, walker, mode, callback);
- };
- // file.mkdirsSync
- //
- // Synchronus version of file.mkdirs
- //
- // Given a path to a directory, create it, and all the intermediate directories
- // as well
- //
- // @path: the path to create
- // @mode: the file mode to create the directory with:
- // ex: file.mkdirs("/tmp/dir", 755, function () {})
- exports.mkdirsSync = function (_path, mode) {
- if (_path[0] !== path.sep) {
- _path = path.join(process.cwd(), _path)
- }
- var dirs = _path.split(path.sep);
- var walker = [dirs.shift()];
- dirs.reduce(function (acc, d) {
- acc.push(d);
- var dir = acc.join(path.sep);
-
- try {
- var stat = fs.statSync(dir);
- if (!stat.isDirectory()) {
- throw "Failed to mkdir " + dir + ": File exists";
- }
- } catch (err) {
- fs.mkdirSync(dir, mode);
- }
- return acc;
- }, walker);
- };
- // file.walk
- //
- // Given a path to a directory, walk the fs below that directory
- //
- // @start: the path to startat
- // @callback: called for each new directory we enter
- // ex: file.walk("/tmp", function(error, path, dirs, name) {})
- //
- // path is the current directory we're in
- // dirs is the list of directories below it
- // names is the list of files in it
- //
- exports.walk = function (start, callback) {
- fs.lstat(start, function (err, stat) {
- if (err) { return callback(err) }
- if (stat.isDirectory()) {
- fs.readdir(start, function (err, files) {
- var coll = files.reduce(function (acc, i) {
- var abspath = path.join(start, i);
- if (fs.statSync(abspath).isDirectory()) {
- exports.walk(abspath, callback);
- acc.dirs.push(abspath);
- } else {
- acc.names.push(abspath);
- }
- return acc;
- }, {"names": [], "dirs": []});
- return callback(null, start, coll.dirs, coll.names);
- });
- } else {
- return callback(new Error("path: " + start + " is not a directory"));
- }
- });
- };
- // file.walkSync
- //
- // Synchronus version of file.walk
- //
- // Given a path to a directory, walk the fs below that directory
- //
- // @start: the path to startat
- // @callback: called for each new directory we enter
- // ex: file.walk("/tmp", function(error, path, dirs, name) {})
- //
- // path is the current directory we're in
- // dirs is the list of directories below it
- // names is the list of files in it
- //
- exports.walkSync = function (start, callback) {
- var stat = fs.statSync(start);
- if (stat.isDirectory()) {
- var filenames = fs.readdirSync(start);
- var coll = filenames.reduce(function (acc, name) {
- var abspath = path.join(start, name);
- if (fs.statSync(abspath).isDirectory()) {
- acc.dirs.push(name);
- } else {
- acc.names.push(name);
- }
- return acc;
- }, {"names": [], "dirs": []});
- callback(start, coll.dirs, coll.names);
- coll.dirs.forEach(function (d) {
- var abspath = path.join(start, d);
- exports.walkSync(abspath, callback);
- });
- } else {
- throw new Error("path: " + start + " is not a directory");
- }
- };
- exports.path = {};
- exports.path.abspath = function (to) {
- var from;
- switch (to.charAt(0)) {
- case "~": from = process.env.HOME; to = to.substr(1); break
- case path.sep: from = ""; break
- default : from = process.cwd(); break
- }
- return path.join(from, to);
- }
- exports.path.relativePath = function (base, compare) {
- base = base.split(path.sep);
- compare = compare.split(path.sep);
- if (base[0] == "") {
- base.shift();
- }
- if (compare[0] == "") {
- compare.shift();
- }
- var l = compare.length;
- for (var i = 0; i < l; i++) {
- if (!base[i] || (base[i] != compare[i])) {
- return compare.slice(i).join(path.sep);
- }
- }
- return ""
- };
- exports.path.join = function (head, tail) {
- if (head == "") {
- return tail;
- } else {
- return path.join(head, tail);
- }
- };
|