alinex-fs
Version:
Extension of nodes filesystem tools.
215 lines (192 loc) • 6.67 kB
JavaScript
/*
Make Directories
=================================================
The basic {@link fs.mkdir()} will only create one directory. While this extension
gives additional methods (in plural) which will also create the full path if possible.
With the `maxnum` parameter you can control the maximum number of directories to create.
So if more are neccessary it will given an `Error` and won't create something for
this task.
If an `EEXIST` code will be thrown internally this signals that the directory is already
there so this methods will succeed without doing anything and without `Error`. All
other errors will be given back.
Example Use
---------------------------------------------------
``` coffee
fs = require 'alinex-fs'
fs.mkdirs '/tmp/some/directory', (err, made) ->
return console.error err if err
if made
console.log "Directory starting from #{made} was created."
console.log 'Directory now exists!'
```
*/
(function() {
var chalk, debug, fs, mkdirs, mkdirsSync, path;
debug = require('debug')('fs:mkdirs');
chalk = require('chalk');
fs = require('fs');
path = require('path');
/*
Exported Methods
------------------------------------------------
*/
/*
@param {String} dir directory path to create
@param {String|Integer} [mode] the permission mode for the directories (may be given
as string like '775')
@param {Integer} [maxnum] the maximum number of directories to create
@param {function(<Error>, <Integer>)} [cb] callback method given the path of the
first directory which was created or `null` if nothing had to be done. The errors
may be:
- `ENOENT` Not allowed to create as many directories: ...
- and others
*/
mkdirs = module.exports.mkdirs = function() {
var args, cb, dir, maxnum, mode;
args = Array.prototype.slice.call(arguments);
cb = typeof args[args.length - 1] === 'function' ? args.pop() : function() {};
dir = args[0], mode = args[1], maxnum = args[2];
if (mode == null) {
mode = 0x1ff & (~process.umask());
}
if (typeof mode === 'string') {
mode = parseInt(mode, 8);
}
if (maxnum == null) {
maxnum = 0;
}
dir = path.resolve(dir);
if (debug.enabled) {
debug("directory " + dir + "?");
}
return fs.mkdir(dir, mode, function(err) {
if (!err) {
if (debug.enabled) {
debug("directory " + dir + " created");
}
return cb(null, dir != null ? dir : dir);
}
if (err.code === 'ENOENT') {
if (maxnum === 1) {
err.message = err.message.replace(/^.*?:/, "Not allowed to create as many directories:");
return cb(err);
}
if (debug.enabled) {
debug(chalk.grey("-> parent is missing"));
}
return mkdirs(path.dirname(dir), mode, --maxnum, function(err, made) {
if (err) {
return cb(err, made);
}
return fs.mkdir(dir, mode, function(err) {
if (!err) {
if (debug.enabled) {
debug("directory " + dir + " created");
}
return cb(null, made);
}
if (err.code === 'EEXIST') {
if (debug.enabled) {
debug(chalk.grey("-> directory " + dir + " is there, now"));
}
return cb(null, made);
} else {
return cb(err, made);
}
});
});
} else if (err.code === 'EEXIST') {
debug(chalk.grey("-> directory " + dir + " was already there"));
return cb();
} else {
return cb(err);
}
});
};
/*
@param {String} dir directory path to create
@param {String|Integer} [mode] the permission mode for the directories (may be given
as string like '775')
@param {Integer} [maxnum] the maximum number of directories to create
@return {String} the path of the first directory which was created or `null` if
nothing had to be done
@throws {Error} if anything out of order happened with the messages
- `ENOENT` Not allowed to create as many directories: ...
- and others
*/
mkdirsSync = module.exports.mkdirsSync = function(dir, mode, maxnum) {
var error, made;
if (mode == null) {
mode = 0x1ff & (~process.umask());
}
if (typeof mode === 'string') {
mode = parseInt(mode, 8);
}
if (maxnum == null) {
maxnum = 0;
}
dir = path.resolve(dir);
try {
fs.mkdirSync(dir, mode);
if (debug.enabled) {
debug("directory " + dir + " created");
}
return dir;
} catch (error1) {
error = error1;
if (error.code === 'ENOENT') {
if (maxnum === 1) {
error.message = error.message.replace(/^.*?:/, "Not allowed to create as many directories:");
throw error;
}
if (debug.enabled) {
debug(chalk.grey("-> parent is missing"));
}
made = mkdirsSync(path.dirname(dir), mode, --maxnum);
try {
fs.mkdirSync(dir, mode);
if (debug.enabled) {
debug("directory " + dir + " created");
}
return made;
} catch (error1) {
error = error1;
if (error.code === 'EEXIST') {
if (debug.enabled) {
debug(chalk.grey("-> directory " + dir + " is there, now"));
}
return made;
}
throw error;
}
} else if (error.code === 'EEXIST') {
if (debug.enabled) {
debug(chalk.grey("directory " + dir + " was already there"));
}
return null;
} else {
throw error;
}
}
};
/*
Debugging
------------------------------------------------
Debugging is possible using environment setting:
```
DEBUG=fs:mkdirs
```
fs:mkdirs directory /home/alex/github/node-fs/test/temp/with/multiple/dirs? +0ms
fs:mkdirs -> parent is missing +1ms
fs:mkdirs directory /home/alex/github/node-fs/test/temp/with/multiple? +1ms
fs:mkdirs -> parent is missing +0ms
fs:mkdirs directory /home/alex/github/node-fs/test/temp/with? +0ms
fs:mkdirs -> parent is missing +0ms
fs:mkdirs directory /home/alex/github/node-fs/test/temp? +0ms
fs:mkdirs directory /home/alex/github/node-fs/test/temp created +0ms
fs:mkdirs directory /home/alex/github/node-fs/test/temp/with created +29ms
fs:mkdirs directory /home/alex/github/node-fs/test/temp/with/multiple created +0ms
fs:mkdirs directory /home/alex/github/node-fs/test/temp/with/multiple/dirs created +0ms
*/
}).call(this);
//# sourceMappingURL=mkdirs.map