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