[6a3a178] | 1 | 'use strict'
|
---|
| 2 |
|
---|
| 3 | const fs = require('graceful-fs')
|
---|
| 4 | const path = require('path')
|
---|
| 5 | const invalidWin32Path = require('./win32').invalidWin32Path
|
---|
| 6 |
|
---|
| 7 | const o777 = parseInt('0777', 8)
|
---|
| 8 |
|
---|
| 9 | function mkdirs (p, opts, callback, made) {
|
---|
| 10 | if (typeof opts === 'function') {
|
---|
| 11 | callback = opts
|
---|
| 12 | opts = {}
|
---|
| 13 | } else if (!opts || typeof opts !== 'object') {
|
---|
| 14 | opts = { mode: opts }
|
---|
| 15 | }
|
---|
| 16 |
|
---|
| 17 | if (process.platform === 'win32' && invalidWin32Path(p)) {
|
---|
| 18 | const errInval = new Error(p + ' contains invalid WIN32 path characters.')
|
---|
| 19 | errInval.code = 'EINVAL'
|
---|
| 20 | return callback(errInval)
|
---|
| 21 | }
|
---|
| 22 |
|
---|
| 23 | let mode = opts.mode
|
---|
| 24 | const xfs = opts.fs || fs
|
---|
| 25 |
|
---|
| 26 | if (mode === undefined) {
|
---|
| 27 | mode = o777 & (~process.umask())
|
---|
| 28 | }
|
---|
| 29 | if (!made) made = null
|
---|
| 30 |
|
---|
| 31 | callback = callback || function () {}
|
---|
| 32 | p = path.resolve(p)
|
---|
| 33 |
|
---|
| 34 | xfs.mkdir(p, mode, er => {
|
---|
| 35 | if (!er) {
|
---|
| 36 | made = made || p
|
---|
| 37 | return callback(null, made)
|
---|
| 38 | }
|
---|
| 39 | switch (er.code) {
|
---|
| 40 | case 'ENOENT':
|
---|
| 41 | if (path.dirname(p) === p) return callback(er)
|
---|
| 42 | mkdirs(path.dirname(p), opts, (er, made) => {
|
---|
| 43 | if (er) callback(er, made)
|
---|
| 44 | else mkdirs(p, opts, callback, made)
|
---|
| 45 | })
|
---|
| 46 | break
|
---|
| 47 |
|
---|
| 48 | // In the case of any other error, just see if there's a dir
|
---|
| 49 | // there already. If so, then hooray! If not, then something
|
---|
| 50 | // is borked.
|
---|
| 51 | default:
|
---|
| 52 | xfs.stat(p, (er2, stat) => {
|
---|
| 53 | // if the stat fails, then that's super weird.
|
---|
| 54 | // let the original error be the failure reason.
|
---|
| 55 | if (er2 || !stat.isDirectory()) callback(er, made)
|
---|
| 56 | else callback(null, made)
|
---|
| 57 | })
|
---|
| 58 | break
|
---|
| 59 | }
|
---|
| 60 | })
|
---|
| 61 | }
|
---|
| 62 |
|
---|
| 63 | module.exports = mkdirs
|
---|