diff options
author | Kazuhito Hokamura <k.hokamura@gmail.com> | 2014-11-25 06:27:55 +0300 |
---|---|---|
committer | Forrest L Norvell <forrest@npmjs.com> | 2014-11-26 00:35:15 +0300 |
commit | 657af7308f7d6cd2f81389fcf0d762252acaf1ce (patch) | |
tree | e609a564c6ea026b49812b73108a4c5e94f61ee0 /lib | |
parent | ac116bbc30e598689fabb2733a6045473b42fdbb (diff) |
resolve symlinks on source & target (fixes #6774)
Diffstat (limited to 'lib')
-rw-r--r-- | lib/utils/gently-rm.js | 65 |
1 files changed, 33 insertions, 32 deletions
diff --git a/lib/utils/gently-rm.js b/lib/utils/gently-rm.js index 6199b8b30..27d3ec500 100644 --- a/lib/utils/gently-rm.js +++ b/lib/utils/gently-rm.js @@ -12,6 +12,7 @@ var npm = require("../npm.js") , isInside = require("path-is-inside") , vacuum = require("fs-vacuum") , some = require("async-some") + , asyncMap = require("slide").asyncMap function gentlyRm (path, gently, base, cb) { if (!cb) { @@ -111,55 +112,55 @@ function gentlyRm (path, gently, base, cb) { var resolvedPaths = {} function isManaged (target) { - return predicate - - function predicate (path, cb) { + return function predicate (path, cb) { if (!path) { log.verbose("isManaged", "no path") return cb(null, false) } - path = resolve(path) - - // if the path has already been memoized, return immediately - var resolved = resolvedPaths[path] - if (resolved) { - var inside = isInside(target, resolved) - log.silly("isManaged", target, inside ? "is" : "is not", "inside", resolved) - - return cb(null, inside && path) - } - - // otherwise, check the path - lstat(path, function (er, stat) { + asyncMap([path, target], resolveSymlink, function (er, results) { if (er) { if (er.code === "ENOENT") return cb(null, false) return cb(er) } - // if it's not a link, cache & test the path itself - if (!stat.isSymbolicLink()) return cacheAndTest(path, path, target, cb) + var path = results[0] + var target = results[1] + var inside = isInside(target, path) + log.silly("isManaged", target, inside ? "is" : "is not", "inside", path) - // otherwise, cache & test the link's source - readlink(path, function (er, source) { - if (er) { - if (er.code === "ENOENT") return cb(null, false) + return cb(null, inside && path) + }) + } - return cb(er) - } + function resolveSymlink (toResolve, cb) { + var resolved = resolve(toResolve) + + // if the path has already been memoized, return immediately + var cached = resolvedPaths[resolved] + if (cached) return cb(null, cached) + + // otherwise, check the path + lstat(resolved, function (er, stat) { + if (er) return cb(er) - cacheAndTest(resolve(path, source), path, target, cb) + // if it's not a link, cache & return the path itself + if (!stat.isSymbolicLink()) { + resolvedPaths[resolved] = resolved + return cb(null, resolved) + } + + // otherwise, cache & return the link's source + readlink(resolved, function (er, source) { + if (er) return cb(er) + + resolved = resolve(resolved, source) + resolvedPaths[resolved] = resolved + cb(null, resolved) }) }) } - - function cacheAndTest (resolved, source, target, cb) { - resolvedPaths[source] = resolved - var inside = isInside(target, resolved) - log.silly("cacheAndTest", target, inside ? "is" : "is not", "inside", resolved) - cb(null, inside && source) - } } function clobberFail (p, g, cb) { |