Comparing version
@@ -5,32 +5,42 @@ module.exports = chmodr | ||
var fs = require("fs") | ||
, path = require("path") | ||
var path = require("path") | ||
function chmodr (p, mode, cb) { | ||
fs.lstat(p, function (er, stats) { | ||
if (er) | ||
return cb(er) | ||
if (stats.isSymbolicLink()) | ||
return cb() | ||
if (stats.isDirectory()) | ||
return chmodrDir(p, mode, cb) | ||
return fs.chmod(p, mode, cb) | ||
}) | ||
} | ||
function chmodrDir (p, mode, cb) { | ||
fs.readdir(p, function (er, children) { | ||
// any error other than ENOTDIR means it's not readable, or | ||
// doesn't exist. give up. | ||
if (er && er.code !== "ENOTDIR") | ||
if (er) | ||
return cb(er) | ||
var isDir = !er | ||
var m = isDir ? dirMode(mode) : mode | ||
if (er || !children.length) | ||
return fs.chmod(p, m, cb) | ||
if (!children.length) | ||
return fs.chmod(p, dirMode(mode), cb) | ||
var len = children.length | ||
var errState = null | ||
children.forEach(function (child) { | ||
var pathChild = path.resolve(p, child); | ||
fs.lstat(pathChild, function(er, stats) { | ||
if (er) | ||
return cb(er) | ||
if (!stats.isSymbolicLink()) | ||
chmodr(pathChild, mode, then) | ||
else | ||
then() | ||
}) | ||
chmodr(path.resolve(p, child), mode, then) | ||
}) | ||
// return first error, but not until all are finished, | ||
// so we don't keep performing FS operations after the cb | ||
function then (er) { | ||
if (errState) return | ||
if (er) return cb(errState = er) | ||
if (-- len === 0) return fs.chmod(p, dirMode(mode), cb) | ||
len = len - 1 | ||
if (er && !errState) | ||
errState = er | ||
if (len === 0) { | ||
if (errState) | ||
return cb(errState) | ||
else | ||
return fs.chmod(p, dirMode(mode), cb) | ||
} | ||
} | ||
@@ -41,16 +51,14 @@ }) | ||
function chmodrSync (p, mode) { | ||
var children | ||
try { | ||
children = fs.readdirSync(p) | ||
} catch (er) { | ||
if (er && er.code === "ENOTDIR") return fs.chmodSync(p, mode) | ||
throw er | ||
} | ||
if (!children.length) return fs.chmodSync(p, dirMode(mode)) | ||
var stats = fs.lstatSync(p) | ||
if (stats.isSymbolicLink()) | ||
return | ||
if (stats.isDirectory()) | ||
return chmodrDirSync(p, mode) | ||
else | ||
return fs.chmodSync(p, mode) | ||
} | ||
children.forEach(function (child) { | ||
var pathChild = path.resolve(p, child) | ||
var stats = fs.lstatSync(pathChild) | ||
if (!stats.isSymbolicLink()) | ||
chmodrSync(pathChild, mode) | ||
function chmodrDirSync (p, mode) { | ||
fs.readdirSync(p).forEach(function (child) { | ||
chmodrSync(path.resolve(p, child), mode) | ||
}) | ||
@@ -63,6 +71,9 @@ return fs.chmodSync(p, dirMode(mode)) | ||
function dirMode(mode) { | ||
if (mode & 0400) mode |= 0100 | ||
if (mode & 040) mode |= 010 | ||
if (mode & 04) mode |= 01 | ||
if (mode & 0400) | ||
mode |= 0100 | ||
if (mode & 040) | ||
mode |= 010 | ||
if (mode & 04) | ||
mode |= 01 | ||
return mode | ||
} |
@@ -5,3 +5,3 @@ { | ||
"description": "like `chmod -R`", | ||
"version": "1.0.1", | ||
"version": "1.0.2", | ||
"repository": { | ||
@@ -8,0 +8,0 @@ "type": "git", |
67
13.56%