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