summaryrefslogtreecommitdiff
path: root/deps/npm/node_modules/read-package-tree/rpt.js
diff options
context:
space:
mode:
Diffstat (limited to 'deps/npm/node_modules/read-package-tree/rpt.js')
-rw-r--r--deps/npm/node_modules/read-package-tree/rpt.js158
1 files changed, 100 insertions, 58 deletions
diff --git a/deps/npm/node_modules/read-package-tree/rpt.js b/deps/npm/node_modules/read-package-tree/rpt.js
index acd91bd8c0..5229897632 100644
--- a/deps/npm/node_modules/read-package-tree/rpt.js
+++ b/deps/npm/node_modules/read-package-tree/rpt.js
@@ -6,6 +6,23 @@ var once = require('once')
var readdir = require('readdir-scoped-modules')
var debug = require('debuglog')('rpt')
+function asyncForEach (items, todo, done) {
+ var remaining = items.length
+ if (remaining === 0) return done()
+ var seenErr
+ items.forEach(function (item) {
+ todo(item, handleComplete)
+ })
+ function handleComplete (err) {
+ if (seenErr) return
+ if (err) {
+ seenErr = true
+ return done(err)
+ }
+ if (--remaining === 0) done()
+ }
+}
+
function dpath (p) {
if (!p) return ''
if (p.indexOf(process.cwd()) === 0) {
@@ -77,30 +94,47 @@ Link.prototype.realpath = ''
function loadNode (logical, physical, cache, cb) {
debug('loadNode', dpath(logical))
- fs.realpath(physical, function (er, real) {
+ return fs.realpath(physical, thenReadPackageJson)
+
+ var realpath
+ function thenReadPackageJson (er, real) {
if (er) return cb(er)
debug('realpath l=%j p=%j real=%j', dpath(logical), dpath(physical), dpath(real))
- var pj = path.resolve(real, 'package.json')
- rpj(pj, function (er, pkg) {
- pkg = pkg || null
- var node
- if (physical === real) {
- node = new Node(pkg, logical, physical, er, cache)
- } else {
- node = new Link(pkg, logical, physical, real, er, cache)
- }
-
- cb(null, node)
- })
- })
+ var pj = path.join(real, 'package.json')
+ realpath = real
+ return rpj(pj, thenCreateNode)
+ }
+ function thenCreateNode (er, pkg) {
+ pkg = pkg || null
+ var node
+ if (physical === realpath) {
+ node = new Node(pkg, logical, physical, er, cache)
+ } else {
+ node = new Link(pkg, logical, physical, realpath, er, cache)
+ }
+
+ cb(null, node)
+ }
}
function loadChildren (node, cache, filterWith, cb) {
debug('loadChildren', dpath(node.path))
- // don't let it be called more than once
+ // needed 'cause we process all kids async-like and errors
+ // short circuit, so we have to be sure that after an error
+ // the cbs from other kids don't result in calling cb a second
+ // (or more) time.
cb = once(cb)
- var nm = path.resolve(node.path, 'node_modules')
- readdir(nm, function (er, kids) {
+ var nm = path.join(node.path, 'node_modules')
+ var rm
+ return fs.realpath(path.join(node.path, 'node_modules'), thenReaddir)
+
+ function thenReaddir (er, real_nm) {
+ if (er) return cb(null, node)
+ rm = real_nm
+ readdir(nm, thenLoadKids)
+ }
+
+ function thenLoadKids (er, kids) {
// If there are no children, that's fine, just return
if (er) return cb(null, node)
@@ -108,26 +142,25 @@ function loadChildren (node, cache, filterWith, cb) {
return kid[0] !== '.' && (!filterWith || filterWith(node, kid))
})
- var l = kids . length
- if (l === 0) return cb(null, node)
-
- kids.forEach(function (kid) {
- var kidPath = path.resolve(nm, kid)
- var kidRealPath = path.resolve(node.realpath,'node_modules',kid)
- loadNode(kidPath, kidRealPath, cache, then)
- })
-
- function then (er, kid) {
- if (er) return cb(er)
-
+ asyncForEach(kids, thenLoadNode, thenSortChildren)
+ }
+ function thenLoadNode (kid, done) {
+ var kidPath = path.join(nm, kid)
+ var kidRealPath = path.join(rm, kid)
+ loadNode(kidPath, kidRealPath, cache, andAddNode(done))
+ }
+ function andAddNode (done) {
+ return function (er, kid) {
+ if (er) return done(er)
node.children.push(kid)
kid.parent = node
- if (--l === 0) {
- sortChildren(node)
- return cb(null, node)
- }
+ done()
}
- })
+ }
+ function thenSortChildren (er) {
+ sortChildren(node)
+ cb(er, node)
+ }
}
function sortChildren (node) {
@@ -147,27 +180,25 @@ function loadTree (node, did, cache, filterWith, cb) {
did[node.realpath] = true
+ // needed 'cause we process all kids async-like and errors
+ // short circuit, so we have to be sure that after an error
+ // the cbs from other kids don't result in calling cb a second
+ // (or more) time.
cb = once(cb)
- loadChildren(node, cache, filterWith, function (er, node) {
+ return loadChildren(node, cache, filterWith, thenProcessChildren)
+
+ function thenProcessChildren (er, node) {
if (er) return cb(er)
var kids = node.children.filter(function (kid) {
return !did[kid.realpath]
})
- var l = kids.length
- if (l === 0) return cb(null, node)
-
- kids.forEach(function (kid, index) {
- loadTree(kid, did, cache, filterWith, then)
- })
-
- function then (er, kid) {
- if (er) return cb(er)
-
- if (--l === 0) cb(null, node)
- }
- })
+ return asyncForEach(kids, loadTreeForKid, cb)
+ }
+ function loadTreeForKid (kid, done) {
+ loadTree(kid, did, cache, filterWith, done)
+ }
}
function rpt (root, filterWith, cb) {
@@ -175,16 +206,27 @@ function rpt (root, filterWith, cb) {
cb = filterWith
filterWith = null
}
- fs.realpath(root, function (er, realRoot) {
+ var cache = Object.create(null)
+ var topErr
+ var tree
+ return fs.realpath(root, thenLoadNode)
+
+ function thenLoadNode (er, realRoot) {
if (er) return cb(er)
debug('rpt', dpath(realRoot))
- var cache = Object.create(null)
- loadNode(root, realRoot, cache, function (er, node) {
- // if there's an error, it's fine, as long as we got a node
- if (!node) return cb(er)
- loadTree(node, {}, cache, filterWith, function (lter, tree) {
- cb(er && er.code !== 'ENOENT' ? er : lter, tree)
- })
- })
- })
+ loadNode(root, realRoot, cache, thenLoadTree)
+ }
+ function thenLoadTree(er, node) {
+ // even if there's an error, it's fine, as long as we got a node
+ if (node) {
+ topErr = er
+ tree = node
+ loadTree(node, {}, cache, filterWith, thenHandleErrors)
+ } else {
+ cb(er)
+ }
+ }
+ function thenHandleErrors (er) {
+ cb(topErr && topErr.code !== 'ENOENT' ? topErr : er, tree)
+ }
}