Skip to content

Commit

Permalink
Update: Implement custom mkdirp (closes #165) (#169)
Browse files Browse the repository at this point in the history
  • Loading branch information
virtuakazib authored and phated committed Jun 28, 2016
1 parent 1fb9da2 commit 5eeaa57
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 17 deletions.
7 changes: 1 addition & 6 deletions lib/dest/writeContents/writeDir.js
@@ -1,16 +1,11 @@
'use strict';

var fs = require('graceful-fs');
var mkdirp = require('mkdirp');

var fo = require('../../fileOperations');

function writeDir(writePath, file, written) {
var mkdirpOpts = {
mode: file.stat.mode,
fs: fs,
};
mkdirp(writePath, mkdirpOpts, onMkdirp);
fo.mkdirp(writePath, file.stat.mode, onMkdirp);

function onMkdirp(mkdirpErr) {
if (mkdirpErr) {
Expand Down
50 changes: 48 additions & 2 deletions lib/fileOperations.js
@@ -1,6 +1,7 @@
'use strict';

var fs = require('graceful-fs');
var path = require('path');
var assign = require('object-assign');
var isEqual = require('lodash.isequal');
var isValidDate = require('vali-date');
Expand All @@ -9,6 +10,7 @@ var isValidDate = require('vali-date');
// TODO include sticky/setuid/setgid, i.e. 7777?
var MASK_MODE = parseInt('0777', 8);
var DEFAULT_FILE_MODE = parseInt('0666', 8);
var DEFAULT_DIR_MODE = parseInt('0777', 8);
var APPEND_MODE_REGEXP = /a/;

function closeFd(propagatedErr, fd, callback) {
Expand Down Expand Up @@ -161,7 +163,7 @@ function updateMetadata(fd, file, callback) {
file descriptor after the write is complete.
Most of the implementation taken from node core.
*/
function writeFile(path, data, options, callback) {
function writeFile(filepath, data, options, callback) {
if (typeof options === 'function') {
callback = options;
options = {};
Expand All @@ -181,7 +183,7 @@ function writeFile(path, data, options, callback) {
var flag = options.flag || 'w';
var position = APPEND_MODE_REGEXP.test(flag) ? null : 0;

fs.open(path, flag, mode, onOpen);
fs.open(filepath, flag, mode, onOpen);

function onOpen(err, fd) {
if (err) {
Expand All @@ -196,11 +198,55 @@ function writeFile(path, data, options, callback) {
}
}

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

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

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

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

default: {
cb(er);
break;
}
}
});
}

module.exports = {
closeFd: closeFd,
getModeDiff: getModeDiff,
getTimesDiff: getTimesDiff,
isOwner: isOwner,
updateMetadata: updateMetadata,
writeFile: writeFile,
mkdirp: mkdirp,
};
9 changes: 2 additions & 7 deletions lib/prepareWrite.js
Expand Up @@ -2,8 +2,8 @@

var assign = require('object-assign');
var path = require('path');
var mkdirp = require('mkdirp');
var fs = require('graceful-fs');
var fo = require('./fileOperations');

function booleanOrFunc(v, file) {
if (typeof v !== 'boolean' && typeof v !== 'function') {
Expand Down Expand Up @@ -53,12 +53,7 @@ function prepareWrite(outFolder, file, opt, cb) {
file.base = basePath;
file.path = writePath;

// Mkdirp the folder the file is going in
var mkdirpOpts = {
mode: options.dirMode,
fs: fs,
};
mkdirp(writeFolder, mkdirpOpts, function(err) {
fo.mkdirp(writeFolder, options.dirMode, function(err) {
if (err) {
return cb(err);
}
Expand Down
1 change: 0 additions & 1 deletion package.json
Expand Up @@ -19,7 +19,6 @@
"lazystream": "^1.0.0",
"lodash.isequal": "^4.0.0",
"merge-stream": "^1.0.0",
"mkdirp": "^0.5.0",
"object-assign": "^4.0.0",
"readable-stream": "^2.0.4",
"strip-bom": "^2.0.0",
Expand Down
2 changes: 1 addition & 1 deletion test/dest.js
Expand Up @@ -1100,12 +1100,12 @@ describe('dest stream', function() {
});

var stream = vfs.dest(outputDir);
stream.write(expectedFile);
stream.on('error', function(err) {
expect(err).toExist();
expect(mkdirSpy.calls.length).toEqual(1);
done();
});
stream.write(expectedFile);
});

it('errors if vinyl object is a directory and we cannot mkdirp', function(done) {
Expand Down
119 changes: 119 additions & 0 deletions test/fileOperations.js
Expand Up @@ -12,6 +12,7 @@ var defaultResolution = require('default-resolution');

var fo = require('../lib/fileOperations');

var mkdirp = fo.mkdirp;
var closeFd = fo.closeFd;
var isOwner = fo.isOwner;
var writeFile = fo.writeFile;
Expand Down Expand Up @@ -892,3 +893,121 @@ describe('updateMetadata', function() {
});
});
});

describe('mkdirp', function() {
var DEFAULT_DIR_MODE = parseInt('0777', 8);
var MODE_MASK = parseInt('0777', 8);

it('makes single directory', function(done) {
if (isWindows) {
this.skip();
return;
}

var dir = path.join(__dirname, './fixtures/bif');
mkdirp(dir, function(err) {
expect(err).toNotExist();

fs.stat(dir, function(err2, stats) {
expect(err2).toNotExist();
expect(stats.mode & MODE_MASK).toEqual(DEFAULT_DIR_MODE & ~process.umask());
del(dir);

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

it('makes multiple directories', function(done) {
if (isWindows) {
this.skip();
return;
}

var dir = path.join(__dirname, './fixtures/bif/bam/bof');
mkdirp(dir, function(err) {
expect(err).toNotExist();

fs.stat(dir, function(err2, stats) {
expect(err2).toNotExist();
expect(stats.mode & MODE_MASK).toEqual(DEFAULT_DIR_MODE & ~process.umask());
del(path.join(__dirname, './fixtures/bif'));

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

it('makes directory with mode', function(done) {
if (isWindows) {
this.skip();
return;
}

var dir = path.join(__dirname, './fixtures/bif');
var mode = parseInt('0700',8);
mkdirp(dir, mode, function(err) {
expect(err).toNotExist();

fs.stat(dir, function(err2, stats) {
expect(err2).toNotExist();
expect(stats.mode & MODE_MASK).toEqual(mode & ~process.umask());
del(dir).then(function() {
done();
});
});
});
});

it('makes multiple directories with mode', function(done) {
if (isWindows) {
this.skip();
return;
}

var dir = path.join(__dirname, './fixtures/bif/bam/bof');
var mode = parseInt('0700',8);
mkdirp(dir, mode, function(err) {
expect(err).toNotExist();

fs.stat(dir, function(err2, stats) {
expect(err2).toNotExist();
expect(stats.mode & MODE_MASK).toEqual(mode & ~process.umask());
del(path.join(__dirname, './fixtures/bif'))
.then(function() {
done();
});
});
});
});

it('changes mode of existing directory', function(done) {
if (isWindows) {
this.skip();
return;
}

var dir = path.join(__dirname, './fixtures/bif');
var mode = parseInt('0700',8);
mkdirp(dir, function(err) {
expect(err).toNotExist();

fs.stat(dir, function(err2, stats) {
expect(err2).toNotExist();
expect(stats.mode & MODE_MASK).toEqual(DEFAULT_DIR_MODE & ~process.umask());

mkdirp(dir, mode, function(err3) {
expect(err3).toNotExist();

fs.stat(dir, function(err4, stats) {
expect(err2).toNotExist();
expect(stats.mode & MODE_MASK).toEqual(mode & ~process.umask());
del(path.join(__dirname, './fixtures/bif'));

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

0 comments on commit 5eeaa57

Please sign in to comment.