diff options
Diffstat (limited to 'node_modules/read-package-tree')
16 files changed, 506 insertions, 0 deletions
diff --git a/node_modules/read-package-tree/LICENSE b/node_modules/read-package-tree/LICENSE new file mode 100644 index 000000000..19129e315 --- /dev/null +++ b/node_modules/read-package-tree/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/read-package-tree/README.md b/node_modules/read-package-tree/README.md new file mode 100644 index 000000000..5d76d0241 --- /dev/null +++ b/node_modules/read-package-tree/README.md @@ -0,0 +1,56 @@ +# read-package-tree + +Read the contents of node_modules. + +## USAGE + +```javascript +var rpt = require ('read-package-tree') +rpt('/path/to/pkg/root', function (er, data) { + // er means that something didn't work. + // data is a structure like: + // { + // package: <package.json data, or null> + // children: [ <more things like this> ] + // parent: <thing that has this in its children property, or null> + // path: <path loaded> + // realpath: <the real path on disk> + // target: <if a Link, then this is the actual Node> + // } +}) +``` + +That's it. It doesn't figure out if dependencies are met, it doesn't +mutate package.json data objects (beyond what +[read-package-json](http://npm.im/read-package-json) already does), it +doesn't limit its search to include/exclude `devDependencies`, or +anything else. + +Just follows the links in the `node_modules` heirarchy and reads the +package.json files it finds therein. + +## Symbolic Links + +When there are symlinks to packages in the `node_modules` hierarchy, a +`Link` object will be created, with a `target` that is a `Node` +object. + +For the most part, you can treat `Link` objects just the same as +`Node` objects. But if your tree-walking program needs to treat +symlinks differently from normal folders, then make sure to check the +object. + +In a given `read-package-tree` run, a specific `path` will always +correspond to a single object, and a specific `realpath` will always +correspond to a single `Node` object. This means that you may not be +able to pass the resulting data object to `JSON.stringify`, because it +may contain cycles. + +## Errors + +Errors parsing or finding a package.json in node_modules will call back with +an error object and no tree. + +A missing or invalid top level package.json will call back with an error +object AND a tree, so that you may, at your discretion, choose to ignore +the error. diff --git a/node_modules/read-package-tree/package.json b/node_modules/read-package-tree/package.json new file mode 100644 index 000000000..be117af03 --- /dev/null +++ b/node_modules/read-package-tree/package.json @@ -0,0 +1,62 @@ +{ + "name": "read-package-tree", + "version": "4.1.0", + "description": "Read the contents of node_modules.", + "main": "rpt.js", + "directories": { + "test": "test" + }, + "dependencies": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "once": "^1.3.0", + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0" + }, + "devDependencies": { + "tap": "^0.4.12", + "archy": "0" + }, + "scripts": { + "test": "tap test/*.js" + }, + "repository": { + "type": "git", + "url": "https://github.com/npm/read-package-tree" + }, + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "license": "ISC", + "bugs": { + "url": "https://github.com/npm/read-package-tree/issues" + }, + "homepage": "https://github.com/npm/read-package-tree", + "gitHead": "14162fb39841acac16ecaad5e9b79e65b430a1fb", + "_id": "read-package-tree@4.1.0", + "_shasum": "d42e418ed22d23d88f308e660ddbf0753be467c1", + "_from": "read-package-tree@4.1.0", + "_npmVersion": "2.7.5", + "_nodeVersion": "0.10.38", + "_npmUser": { + "name": "iarna", + "email": "me@re-becca.org" + }, + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + }, + { + "name": "iarna", + "email": "me@re-becca.org" + } + ], + "dist": { + "shasum": "d42e418ed22d23d88f308e660ddbf0753be467c1", + "tarball": "http://registry.npmjs.org/read-package-tree/-/read-package-tree-4.1.0.tgz" + }, + "_resolved": "https://registry.npmjs.org/read-package-tree/-/read-package-tree-4.1.0.tgz" +} 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) + }) + }) + }) +} diff --git a/node_modules/read-package-tree/test/basic.js b/node_modules/read-package-tree/test/basic.js new file mode 100644 index 000000000..ada43a51c --- /dev/null +++ b/node_modules/read-package-tree/test/basic.js @@ -0,0 +1,135 @@ +var test = require('tap').test +var rpt = require('../rpt.js') +var path = require('path') +var fs = require('fs') +var archy = require('archy') +var fixtures = path.resolve(__dirname, 'fixtures') +var roots = [ 'root', 'other', 'selflink' ] +var cwd = path.resolve(__dirname, '..') + +var symlinks = { + 'selflink/node_modules/@scope/z/node_modules/glob': + '../../../foo/node_modules/glob', + 'other/node_modules/glob': + '../../root/node_modules/@scope/x/node_modules/glob', + 'linkedroot': + 'root', + 'deep/root': + '../root', + 'deeproot': + 'deep' +} + +function cleanup () { + Object.keys(symlinks).forEach(function (s) { + var p = path.resolve(cwd, 'test/fixtures', s) + try { + fs.unlinkSync(p) + } catch (er) {} + }) +} + +test('setup symlinks', function (t) { + cleanup() + + Object.keys(symlinks).forEach(function (s) { + var p = path.resolve(cwd, 'test/fixtures', s) + fs.symlinkSync(symlinks [ s ], p, 'dir') + }) + + t.end() +}) + +roots.forEach(function (root) { + var dir = path.resolve(fixtures, root) + var out = path.resolve(dir, 'archy.txt') + + test(root, function (t) { + rpt(dir, function (er, d) { + if (er && er.code !== 'ENOENT') throw er + + var actual = archy(archyize(d)).trim() + // console . log ('----', dir) + console.log(actual) + // console . log (require ('util') . inspect (d, { + // depth: Infinity + // })) + var expect = fs.readFileSync(out, 'utf8').trim() + t.equal(actual, expect, root + ' tree') + t.end() + }) + }) +}) + +test('linkedroot', function (t) { + var dir = path.resolve(fixtures, 'linkedroot') + var out = dir + '-archy.txt' + rpt(dir, function (er, d) { + if (er && er.code !== 'ENOENT') throw er + + var actual = archy(archyize(d)).trim() + console.log(actual) + var expect = fs.readFileSync(out, 'utf8').trim() + t.equal(actual, expect, 'linkedroot tree') + t.end() + }) +}) + +test('deeproot', function (t) { + var dir = path.resolve(fixtures, 'deeproot/root') + var out = path.resolve(fixtures, 'deep') + '-archy.txt' + rpt(dir, function (er, d) { + if (er && er.code !== 'ENOENT') throw er + + var actual = archy(archyize(d)).trim() + console.log(actual) + var expect = fs.readFileSync(out, 'utf8').trim() + t.equal(actual, expect, 'deeproot tree') + t.end() + }) +}) + +test('broken json', function (t) { + rpt(path.resolve(fixtures, 'bad'), function (er, d) { + t.ok(er, 'Got an error object') + t.equal(er && er.code, 'EJSONPARSE') + t.ok(d, 'Got a tree') + t.end() + }) +}) + +test('missing json does not obscure deeper errors', function (t) { + rpt(path.resolve(fixtures, 'empty'), function (er, d) { + t.ok(er, 'Got an error object') + t.equal(er && er.code, 'EJSONPARSE') + t.ok(!d, 'No tree on internal error') + t.end() + }) +}) + +function archyize (d, seen) { + seen = seen || {} + var path = d.path + if (d.target) { + path = d.target.path + } + + var label = d.package ? d.package._id + ' ' : '' + label += path.substr(cwd.length + 1) + + if (d . target) { + return { label: label + ' (symlink)', nodes: [] } + } + + return { + label: label, + nodes: d.children.map(function (kid) { + return archyize(kid, seen) + }) + } +} + +test('cleanup', function (t) { + cleanup() + t.end() +}) diff --git a/node_modules/read-package-tree/test/fixtures/bad/package.json b/node_modules/read-package-tree/test/fixtures/bad/package.json new file mode 100644 index 000000000..21d815ec3 --- /dev/null +++ b/node_modules/read-package-tree/test/fixtures/bad/package.json @@ -0,0 +1,2 @@ +{ + "NOPE" diff --git a/node_modules/read-package-tree/test/fixtures/deep-archy.txt b/node_modules/read-package-tree/test/fixtures/deep-archy.txt new file mode 100644 index 000000000..630eab1a4 --- /dev/null +++ b/node_modules/read-package-tree/test/fixtures/deep-archy.txt @@ -0,0 +1,11 @@ +root@1.2.3 test/fixtures/deeproot/root +├─┬ @scope/x@1.2.3 test/fixtures/deeproot/root/node_modules/@scope/x +│ └─┬ glob@4.0.5 test/fixtures/deeproot/root/node_modules/@scope/x/node_modules/glob +│ ├── graceful-fs@3.0.2 test/fixtures/deeproot/root/node_modules/@scope/x/node_modules/glob/node_modules/graceful-fs +│ ├── inherits@2.0.1 test/fixtures/deeproot/root/node_modules/@scope/x/node_modules/glob/node_modules/inherits +│ ├─┬ minimatch@1.0.0 test/fixtures/deeproot/root/node_modules/@scope/x/node_modules/glob/node_modules/minimatch +│ │ ├── lru-cache@2.5.0 test/fixtures/deeproot/root/node_modules/@scope/x/node_modules/glob/node_modules/minimatch/node_modules/lru-cache +│ │ └── sigmund@1.0.0 test/fixtures/deeproot/root/node_modules/@scope/x/node_modules/glob/node_modules/minimatch/node_modules/sigmund +│ └── once@1.3.0 test/fixtures/deeproot/root/node_modules/@scope/x/node_modules/glob/node_modules/once +├── @scope/y@1.2.3 test/fixtures/deeproot/root/node_modules/@scope/y +└── foo@1.2.3 test/fixtures/deeproot/root/node_modules/foo
\ No newline at end of file diff --git a/node_modules/read-package-tree/test/fixtures/deep/.keep b/node_modules/read-package-tree/test/fixtures/deep/.keep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/node_modules/read-package-tree/test/fixtures/deep/.keep diff --git a/node_modules/read-package-tree/test/fixtures/empty/node_modules/foo/package.json b/node_modules/read-package-tree/test/fixtures/empty/node_modules/foo/package.json new file mode 100644 index 000000000..98232c64f --- /dev/null +++ b/node_modules/read-package-tree/test/fixtures/empty/node_modules/foo/package.json @@ -0,0 +1 @@ +{ diff --git a/node_modules/read-package-tree/test/fixtures/linkedroot-archy.txt b/node_modules/read-package-tree/test/fixtures/linkedroot-archy.txt new file mode 100644 index 000000000..e34a46031 --- /dev/null +++ b/node_modules/read-package-tree/test/fixtures/linkedroot-archy.txt @@ -0,0 +1,11 @@ +root@1.2.3 test/fixtures/linkedroot +├─┬ @scope/x@1.2.3 test/fixtures/linkedroot/node_modules/@scope/x +│ └─┬ glob@4.0.5 test/fixtures/linkedroot/node_modules/@scope/x/node_modules/glob +│ ├── graceful-fs@3.0.2 test/fixtures/linkedroot/node_modules/@scope/x/node_modules/glob/node_modules/graceful-fs +│ ├── inherits@2.0.1 test/fixtures/linkedroot/node_modules/@scope/x/node_modules/glob/node_modules/inherits +│ ├─┬ minimatch@1.0.0 test/fixtures/linkedroot/node_modules/@scope/x/node_modules/glob/node_modules/minimatch +│ │ ├── lru-cache@2.5.0 test/fixtures/linkedroot/node_modules/@scope/x/node_modules/glob/node_modules/minimatch/node_modules/lru-cache +│ │ └── sigmund@1.0.0 test/fixtures/linkedroot/node_modules/@scope/x/node_modules/glob/node_modules/minimatch/node_modules/sigmund +│ └── once@1.3.0 test/fixtures/linkedroot/node_modules/@scope/x/node_modules/glob/node_modules/once +├── @scope/y@1.2.3 test/fixtures/linkedroot/node_modules/@scope/y +└── foo@1.2.3 test/fixtures/linkedroot/node_modules/foo
\ No newline at end of file diff --git a/node_modules/read-package-tree/test/fixtures/other/archy.txt b/node_modules/read-package-tree/test/fixtures/other/archy.txt new file mode 100644 index 000000000..23666226c --- /dev/null +++ b/node_modules/read-package-tree/test/fixtures/other/archy.txt @@ -0,0 +1,2 @@ +test/fixtures/other +└── glob@4.0.5 test/fixtures/other/node_modules/glob (symlink)
\ No newline at end of file diff --git a/node_modules/read-package-tree/test/fixtures/other/node_modules/.bin b/node_modules/read-package-tree/test/fixtures/other/node_modules/.bin new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/node_modules/read-package-tree/test/fixtures/other/node_modules/.bin diff --git a/node_modules/read-package-tree/test/fixtures/root/archy.txt b/node_modules/read-package-tree/test/fixtures/root/archy.txt new file mode 100644 index 000000000..1aacd3f0b --- /dev/null +++ b/node_modules/read-package-tree/test/fixtures/root/archy.txt @@ -0,0 +1,11 @@ +root@1.2.3 test/fixtures/root +├─┬ @scope/x@1.2.3 test/fixtures/root/node_modules/@scope/x +│ └─┬ glob@4.0.5 test/fixtures/root/node_modules/@scope/x/node_modules/glob +│ ├── graceful-fs@3.0.2 test/fixtures/root/node_modules/@scope/x/node_modules/glob/node_modules/graceful-fs +│ ├── inherits@2.0.1 test/fixtures/root/node_modules/@scope/x/node_modules/glob/node_modules/inherits +│ ├─┬ minimatch@1.0.0 test/fixtures/root/node_modules/@scope/x/node_modules/glob/node_modules/minimatch +│ │ ├── lru-cache@2.5.0 test/fixtures/root/node_modules/@scope/x/node_modules/glob/node_modules/minimatch/node_modules/lru-cache +│ │ └── sigmund@1.0.0 test/fixtures/root/node_modules/@scope/x/node_modules/glob/node_modules/minimatch/node_modules/sigmund +│ └── once@1.3.0 test/fixtures/root/node_modules/@scope/x/node_modules/glob/node_modules/once +├── @scope/y@1.2.3 test/fixtures/root/node_modules/@scope/y +└── foo@1.2.3 test/fixtures/root/node_modules/foo
\ No newline at end of file diff --git a/node_modules/read-package-tree/test/fixtures/root/package.json b/node_modules/read-package-tree/test/fixtures/root/package.json new file mode 100644 index 000000000..010347cee --- /dev/null +++ b/node_modules/read-package-tree/test/fixtures/root/package.json @@ -0,0 +1,2 @@ +{"name":"root", + "version":"1.2.3"}
\ No newline at end of file diff --git a/node_modules/read-package-tree/test/fixtures/selflink/archy.txt b/node_modules/read-package-tree/test/fixtures/selflink/archy.txt new file mode 100644 index 000000000..307618ce1 --- /dev/null +++ b/node_modules/read-package-tree/test/fixtures/selflink/archy.txt @@ -0,0 +1,13 @@ +selflink@1.2.3 test/fixtures/selflink +├── @scope/y@1.2.3 test/fixtures/selflink/node_modules/@scope/y +├─┬ @scope/z@1.2.3 test/fixtures/selflink/node_modules/@scope/z +│ └── glob@4.0.5 test/fixtures/selflink/node_modules/foo/node_modules/glob (symlink) +└─┬ foo@1.2.3 test/fixtures/selflink/node_modules/foo + ├─┬ glob@4.0.5 test/fixtures/selflink/node_modules/foo/node_modules/glob + │ ├── graceful-fs@3.0.2 test/fixtures/selflink/node_modules/foo/node_modules/glob/node_modules/graceful-fs + │ ├── inherits@2.0.1 test/fixtures/selflink/node_modules/foo/node_modules/glob/node_modules/inherits + │ ├─┬ minimatch@1.0.0 test/fixtures/selflink/node_modules/foo/node_modules/glob/node_modules/minimatch + │ │ ├── lru-cache@2.5.0 test/fixtures/selflink/node_modules/foo/node_modules/glob/node_modules/minimatch/node_modules/lru-cache + │ │ └── sigmund@1.0.0 test/fixtures/selflink/node_modules/foo/node_modules/glob/node_modules/minimatch/node_modules/sigmund + │ └── once@1.3.0 test/fixtures/selflink/node_modules/foo/node_modules/glob/node_modules/once + └── selflink@1.2.3 test/fixtures/selflink (symlink) diff --git a/node_modules/read-package-tree/test/fixtures/selflink/package.json b/node_modules/read-package-tree/test/fixtures/selflink/package.json new file mode 100644 index 000000000..5bbf35e55 --- /dev/null +++ b/node_modules/read-package-tree/test/fixtures/selflink/package.json @@ -0,0 +1,2 @@ +{"name":"selflink", + "version":"1.2.3"} |