mkdirp.js 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. 'use strict';
  2. var path = require('path');
  3. var fs = require('graceful-fs');
  4. var MASK_MODE = parseInt('7777', 8);
  5. var DEFAULT_DIR_MODE = parseInt('0777', 8);
  6. function mkdirp(dirpath, customMode, callback) {
  7. if (typeof customMode === 'function') {
  8. callback = customMode;
  9. customMode = undefined;
  10. }
  11. var mode = customMode || (DEFAULT_DIR_MODE & ~process.umask());
  12. dirpath = path.resolve(dirpath);
  13. fs.mkdir(dirpath, mode, onMkdir);
  14. function onMkdir(mkdirErr) {
  15. if (!mkdirErr) {
  16. return fs.stat(dirpath, onStat);
  17. }
  18. switch (mkdirErr.code) {
  19. case 'ENOENT': {
  20. return mkdirp(path.dirname(dirpath), onRecurse);
  21. }
  22. case 'EEXIST': {
  23. return fs.stat(dirpath, onStat);
  24. }
  25. default: {
  26. return callback(mkdirErr);
  27. }
  28. }
  29. function onStat(statErr, stats) {
  30. if (statErr) {
  31. return callback(statErr);
  32. }
  33. if (!stats.isDirectory()) {
  34. return callback(mkdirErr);
  35. }
  36. // TODO: Is it proper to mask like this?
  37. if ((stats.mode & MASK_MODE) === mode) {
  38. return callback();
  39. }
  40. if (!customMode) {
  41. return callback();
  42. }
  43. fs.chmod(dirpath, mode, callback);
  44. }
  45. }
  46. function onRecurse(recurseErr) {
  47. if (recurseErr) {
  48. return callback(recurseErr);
  49. }
  50. mkdirp(dirpath, mode, callback);
  51. }
  52. }
  53. module.exports = mkdirp;