Skip to content

Commit

Permalink
Fix: Properly handle file in mkdirp path (closes #181)
Browse files Browse the repository at this point in the history
  • Loading branch information
phated committed Nov 30, 2017
1 parent e63dd97 commit 3087b78
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 31 deletions.
67 changes: 40 additions & 27 deletions lib/file-operations.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,47 +195,60 @@ function writeFile(filepath, data, options, callback) {
}
}

function mkdirp(dirpath, mode, callback) {
if (typeof mode === 'function') {
callback = mode;
mode = undefined;
function mkdirp(dirpath, customMode, callback) {
if (typeof customMode === 'function') {
callback = customMode;
customMode = undefined;
}

var m = mode || constants.DEFAULT_DIR_MODE;
var cb = callback || function() {};
var mode = customMode || constants.DEFAULT_DIR_MODE;
dirpath = path.resolve(dirpath);

fs.mkdir(dirpath, m, function(er) {
if (!er) {
return cb();
fs.mkdir(dirpath, mode, onMkdir);

function onMkdir(mkdirErr) {
if (!mkdirErr) {
return callback();
}
switch (er.code) {

switch (mkdirErr.code) {
case 'ENOENT': {
mkdirp(path.dirname(dirpath), m, function(er) {
if (er) {
cb(er);
} else {
mkdirp(dirpath, m, cb);
}
});
break;
return mkdirp(path.dirname(dirpath), mode, onRecurse);
}

case 'EEXIST': {
if (mode) {
fs.chmod(dirpath, mode, cb);
} else {
cb();
}
break;
return fs.stat(dirpath, onStat);
}

default: {
cb(er);
break;
return callback(mkdirErr);
}
}

function onStat(statErr, stats) {
if (statErr) {
return callback(statErr);
}

if (!stats.isDirectory()) {
return callback(mkdirErr);
}

if (!customMode) {
return callback();
}

fs.chmod(dirpath, customMode, callback);
}
}

function onRecurse(recurseErr) {
if (recurseErr) {
return callback(recurseErr);
}
});

mkdirp(dirpath, mode, callback);
}
}

module.exports = {
Expand Down
55 changes: 51 additions & 4 deletions test/file-operations.js
Original file line number Diff line number Diff line change
Expand Up @@ -917,7 +917,7 @@ describe('mkdirp', function() {
var DEFAULT_DIR_MODE = parseInt('0777', 8);
var MODE_MASK = parseInt('0777', 8);

var dir = path.join(__dirname, './fixtures/bif');
var dir = path.join(__dirname, './fixtures/bar');

afterEach(function() {
return del(dir);
Expand Down Expand Up @@ -955,7 +955,7 @@ describe('mkdirp', function() {
});

it('makes multiple directories', function(done) {
var nestedDir = path.join(dir, './bam/bof');
var nestedDir = path.join(dir, './baz/foo');
mkdirp(nestedDir, function(err) {
expect(err).toNotExist();

Expand All @@ -974,7 +974,7 @@ describe('mkdirp', function() {
return;
}

var nestedDir = path.join(dir, './bam/bof');
var nestedDir = path.join(dir, './baz/foo');
mkdirp(nestedDir, function(err) {
expect(err).toNotExist();

Expand Down Expand Up @@ -1012,7 +1012,7 @@ describe('mkdirp', function() {
return;
}

var nestedDir = path.join(dir, './bam/bof');
var nestedDir = path.join(dir, './baz/foo');
var mode = parseInt('0700',8);
mkdirp(nestedDir, mode, function(err) {
expect(err).toNotExist();
Expand Down Expand Up @@ -1053,4 +1053,51 @@ describe('mkdirp', function() {
});
});
});

it('errors with EEXIST if file in path', function(done) {
var file = path.join(dir, './bar.txt');
mkdirp(dir, function(err) {
expect(err).toNotExist();

fs.writeFile(file, 'hello world', function(err2) {
expect(err2).toNotExist();

mkdirp(file, function(err3) {
expect(err3).toExist();
expect(err3.code).toEqual('EEXIST');

done();
});
});
});
});

it('does not change mode of existing file', function(done) {
if (isWindows) {
this.skip();
return;
}

var file = path.join(dir, './bar.txt');
var mode = parseInt('0700', 8);
mkdirp(dir, function(err) {
expect(err).toNotExist();

fs.writeFile(file, 'hello world', function(err2) {
expect(err2).toNotExist();

var stats = fs.statSync(file);
var expectedMode = stats.mode & MODE_MASK;

mkdirp(file, mode, function(err3) {
expect(err3).toExist();

var stats = fs.statSync(file);
expect(stats.mode & MODE_MASK).toEqual(expectedMode);

done();
});
});
});
});
});

0 comments on commit 3087b78

Please sign in to comment.