• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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