index.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. var path = require('path');
  2. var fs = require('fs');
  3. var _0777 = parseInt('0777', 8);
  4. module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP;
  5. function mkdirP (p, opts, f, made) {
  6. if (typeof opts === 'function') {
  7. f = opts;
  8. opts = {};
  9. }
  10. else if (!opts || typeof opts !== 'object') {
  11. opts = { mode: opts };
  12. }
  13. var mode = opts.mode;
  14. var xfs = opts.fs || fs;
  15. if (mode === undefined) {
  16. mode = _0777
  17. }
  18. if (!made) made = null;
  19. var cb = f || /* istanbul ignore next */ function () {};
  20. p = path.resolve(p);
  21. xfs.mkdir(p, mode, function (er) {
  22. if (!er) {
  23. made = made || p;
  24. return cb(null, made);
  25. }
  26. switch (er.code) {
  27. case 'ENOENT':
  28. /* istanbul ignore if */
  29. if (path.dirname(p) === p) return cb(er);
  30. mkdirP(path.dirname(p), opts, function (er, made) {
  31. /* istanbul ignore if */
  32. if (er) cb(er, made);
  33. else mkdirP(p, opts, cb, made);
  34. });
  35. break;
  36. // In the case of any other error, just see if there's a dir
  37. // there already. If so, then hooray! If not, then something
  38. // is borked.
  39. default:
  40. xfs.stat(p, function (er2, stat) {
  41. // if the stat fails, then that's super weird.
  42. // let the original error be the failure reason.
  43. if (er2 || !stat.isDirectory()) cb(er, made)
  44. else cb(null, made);
  45. });
  46. break;
  47. }
  48. });
  49. }
  50. mkdirP.sync = function sync (p, opts, made) {
  51. if (!opts || typeof opts !== 'object') {
  52. opts = { mode: opts };
  53. }
  54. var mode = opts.mode;
  55. var xfs = opts.fs || fs;
  56. if (mode === undefined) {
  57. mode = _0777
  58. }
  59. if (!made) made = null;
  60. p = path.resolve(p);
  61. try {
  62. xfs.mkdirSync(p, mode);
  63. made = made || p;
  64. }
  65. catch (err0) {
  66. switch (err0.code) {
  67. case 'ENOENT' :
  68. made = sync(path.dirname(p), opts, made);
  69. sync(p, opts, made);
  70. break;
  71. // In the case of any other error, just see if there's a dir
  72. // there already. If so, then hooray! If not, then something
  73. // is borked.
  74. default:
  75. var stat;
  76. try {
  77. stat = xfs.statSync(p);
  78. }
  79. catch (err1) /* istanbul ignore next */ {
  80. throw err0;
  81. }
  82. /* istanbul ignore if */
  83. if (!stat.isDirectory()) throw err0;
  84. break;
  85. }
  86. }
  87. return made;
  88. };