Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/read-package-tree/rpt.js')
-rw-r--r--node_modules/read-package-tree/rpt.js183
1 files changed, 183 insertions, 0 deletions
diff --git a/node_modules/read-package-tree/rpt.js b/node_modules/read-package-tree/rpt.js
new file mode 100644
index 000000000..e6d283883
--- /dev/null
+++ b/node_modules/read-package-tree/rpt.js
@@ -0,0 +1,183 @@
+var fs = require('fs')
+var rpj = require('read-package-json')
+var path = require('path')
+var dz = require('dezalgo')
+var once = require('once')
+var readdir = require('readdir-scoped-modules')
+var debug = require('debuglog')('rpt')
+
+function dpath (p) {
+ if (!p) return ''
+ if (p.indexOf(process.cwd()) === 0) {
+ p = p.substr(process.cwd().length + 1)
+ }
+ return p
+}
+
+module.exports = rpt
+
+rpt.Node = Node
+rpt.Link = Link
+
+var ID = 0
+function Node (pkg, logical, physical, cache) {
+ if (cache[physical]) return cache[physical]
+
+ if (!(this instanceof Node)) {
+ return new Node(pkg, logical, physical, cache)
+ }
+
+ cache[physical] = this
+
+ debug(this.constructor.name, dpath(physical), pkg && pkg._id)
+
+ this.id = ID++
+ this.package = pkg
+ this.path = logical
+ this.realpath = physical
+ this.parent = null
+ this.isLink = false
+ this.children = []
+}
+
+Node.prototype.package = null
+Node.prototype.path = ''
+Node.prototype.realpath = ''
+Node.prototype.children = null
+
+function Link (pkg, logical, physical, realpath, cache) {
+ if (cache[physical]) return cache[physical]
+
+ if (!(this instanceof Link)) {
+ return new Link(pkg, logical, physical, realpath, cache)
+ }
+
+ cache[physical] = this
+
+ debug(this.constructor.name, dpath(physical), pkg && pkg._id)
+
+ this.id = ID++
+ this.path = logical
+ this.realpath = realpath
+ this.package = pkg
+ this.parent = null
+ this.target = new Node(pkg, logical, realpath, cache)
+ this.isLink = true
+ this.children = this.target.children
+}
+
+Link.prototype = Object.create(Node.prototype, {
+ constructor: { value: Link }
+})
+Link.prototype.target = null
+Link.prototype.realpath = ''
+
+function loadNode (logical, physical, cache, cb) {
+ debug('loadNode', dpath(logical))
+ fs.realpath(physical, function (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, cache)
+ } else {
+ node = new Link(pkg, logical, physical, real, cache)
+ }
+
+ cb(er, node)
+ })
+ })
+}
+
+function loadChildren (node, cache, cb) {
+ debug('loadChildren', dpath(node.path))
+ // don't let it be called more than once
+ cb = once(cb)
+ var nm = path.resolve(node.path, 'node_modules')
+ readdir(nm, function (er, kids) {
+ // If there are no children, that's fine, just return
+ if (er) return cb(null, node)
+
+ kids = kids.filter(function (kid) {
+ return kid[0] !== '.'
+ })
+
+ 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)
+
+ node.children.push(kid)
+ kid.parent = node
+ if (--l === 0) {
+ sortChildren(node)
+ return cb(null, node)
+ }
+ }
+ })
+}
+
+function sortChildren (node) {
+ node.children = node.children.sort(function (a, b) {
+ a = a.package.name.toLowerCase()
+ b = b.package.name.toLowerCase()
+ return a > b ? 1 : -1
+ })
+}
+
+function loadTree (node, did, cache, cb) {
+ debug('loadTree', dpath(node.path), !!cache[node.path])
+
+ if (did[node.realpath]) {
+ return dz(cb)(null, node)
+ }
+
+ did[node.realpath] = true
+
+ cb = once(cb)
+ loadChildren(node, cache, function (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, then)
+ })
+
+ function then (er, kid) {
+ if (er) return cb(er)
+
+ if (--l === 0) cb(null, node)
+ }
+ })
+}
+
+function rpt (root, cb) {
+ fs.realpath(root, function (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, function (lter, tree) {
+ cb(er && er.code !== 'ENOENT' ? er : lter, tree)
+ })
+ })
+ })
+}