Added shell.mkdirp. Fixes issue #126.
This commit is contained in:
parent
9052b285c3
commit
6faabdb937
17
README.md
17
README.md
|
@ -1109,6 +1109,7 @@ var sh = fs.Shell();
|
|||
* [sh.cat(files, callback)](#cat)
|
||||
* [sh.rm(path, [options], callback)](#rm)
|
||||
* [sh.tempDir(callback)](#tempDir)
|
||||
* [sh.mkdirp(path, callback)](#mkdirp)
|
||||
|
||||
#### sh.cd(path, callback)<a name="cd"></a>
|
||||
|
||||
|
@ -1298,3 +1299,19 @@ sh.tempDir(function(err, tmp) {
|
|||
// tmp is now '/temporary', and /temporary exists
|
||||
});
|
||||
```
|
||||
|
||||
#### sh.mkdirp(callback)<a name="mkdirp"></a>
|
||||
|
||||
Recursively creates the directory at the provided path. If the
|
||||
directory already exists, no error is returned. All parents must
|
||||
be valid directories (not files).
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
// Default empty filesystem
|
||||
sh.mkdirp('/test/mkdirp', function(err) {
|
||||
if(err) throw err;
|
||||
// the root '/' now contains a directory 'test' containing the directory 'mkdirp'
|
||||
});
|
||||
```
|
||||
|
|
69
src/shell.js
69
src/shell.js
|
@ -353,6 +353,75 @@ define(function(require) {
|
|||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Recursively creates the directory at `path`. If the parent
|
||||
* of `path` does not exist, it will be created.
|
||||
* Based off EnsureDir by Sam X. Xu
|
||||
* https://www.npmjs.org/package/ensureDir
|
||||
* MIT License
|
||||
*/
|
||||
Shell.prototype.mkdirp = function(path, callback) {
|
||||
var fs = this.fs;
|
||||
callback = callback || function(){};
|
||||
|
||||
if(!path) {
|
||||
callback(new Errors.EInvalid());
|
||||
return;
|
||||
}
|
||||
else if (path === '/'){
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
function _mkdirp(path, callback){
|
||||
fs.stat(path, function (err, stat) {
|
||||
//doesn't exist
|
||||
if (err && err.code === 'ENOENT') {
|
||||
var parent = Path.dirname(path);
|
||||
if(parent === '/'){ //parent is root
|
||||
fs.mkdir(path, function (err) {
|
||||
if (err && err.code != 'EEXIST') {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
callback();
|
||||
return;
|
||||
});
|
||||
}
|
||||
else { //parent is not root, make parent first
|
||||
_mkdirp(parent, function (err) {
|
||||
if (err) return callback(err);
|
||||
fs.mkdir(path, function (err) { //then make dir
|
||||
if (err && err.code != 'EEXIST') {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
callback();
|
||||
return;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
//other error
|
||||
else if (err){
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
//already exists
|
||||
else if (stat.type === 'DIRECTORY') {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
//not a directory
|
||||
else if (stat.type === 'FILE') {
|
||||
callback(new Errors.ENotDirectory());
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_mkdirp(path, callback);
|
||||
};
|
||||
|
||||
return Shell;
|
||||
|
||||
});
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
define(["Filer", "util"], function(Filer, util) {
|
||||
|
||||
describe('FileSystemShell.mkdirp', function() {
|
||||
beforeEach(util.setup);
|
||||
afterEach(util.cleanup);
|
||||
|
||||
it('should be a function', function() {
|
||||
var shell = util.shell();
|
||||
expect(shell.mkdirp).to.be.a('function');
|
||||
});
|
||||
|
||||
it('should fail without a path provided', function(done) {
|
||||
var fs = util.fs();
|
||||
var shell = fs.Shell();
|
||||
|
||||
shell.mkdirp(null, function(err) {
|
||||
expect(err).to.exist;
|
||||
expect(err.code).to.equal('EINVAL');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should succeed if provided path is root', function(done) {
|
||||
var fs = util.fs();
|
||||
var shell = fs.Shell();
|
||||
shell.mkdirp('/', function(err) {
|
||||
expect(err).to.not.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should succeed if the directory exists', function(done) {
|
||||
var fs = util.fs();
|
||||
var shell = fs.Shell();
|
||||
fs.mkdir('/test', function(err){
|
||||
expect(err).to.not.exist;
|
||||
shell.mkdirp('/test',function(err) {
|
||||
expect(err).to.not.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('fail if a file name is provided', function(done) {
|
||||
var fs = util.fs();
|
||||
var shell = fs.Shell();
|
||||
fs.writeFile('/test.txt', 'test', function(err){
|
||||
expect(err).to.not.exist;
|
||||
shell.mkdirp('/test.txt', function(err) {
|
||||
expect(err).to.exist;
|
||||
expect(err.code).to.equal('ENOTDIR');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should succeed on a folder on root (\'/test\')', function(done) {
|
||||
var fs = util.fs();
|
||||
var shell = fs.Shell();
|
||||
shell.mkdirp('/test', function(err) {
|
||||
expect(err).to.not.exist;
|
||||
fs.exists('/test', function(dir){
|
||||
expect(dir).to.be.true;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should succeed on a folder with a nonexistant parent (\'/test/test\')', function(done) {
|
||||
var fs = util.fs();
|
||||
var shell = fs.Shell();
|
||||
shell.mkdirp('/test/test', function(err) {
|
||||
expect(err).to.not.exist;
|
||||
fs.exists('/test', function(dir1){
|
||||
expect(dir1).to.be.true;
|
||||
fs.exists('/test/test', function(dir2){
|
||||
expect(dir2).to.be.true;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail on a folder with a file for its parent (\'/test.txt/test\')', function(done) {
|
||||
var fs = util.fs();
|
||||
var shell = fs.Shell();
|
||||
fs.writeFile('/test.txt', 'test', function(err){
|
||||
expect(err).to.not.exist;
|
||||
shell.mkdirp('/test.txt/test', function(err) {
|
||||
expect(err).to.exist;
|
||||
expect(err.code).to.equal('ENOTDIR');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -55,6 +55,7 @@ define([
|
|||
"spec/shell/ls.spec",
|
||||
"spec/shell/rm.spec",
|
||||
"spec/shell/env.spec",
|
||||
"spec/shell/mkdirp.spec",
|
||||
|
||||
// Ported node.js tests (filenames match names in https://github.com/joyent/node/tree/master/test)
|
||||
"spec/node-js/simple/test-fs-mkdir",
|
||||
|
|
Loading…
Reference in New Issue