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:
authorRebecca Turner <turner@mikomi.org>2014-09-30 00:11:02 +0400
committerRebecca Turner <me@re-becca.org>2015-06-26 03:26:36 +0300
commit9ada7beefc1e1b166395494cd242398424451e55 (patch)
treeb9b0de33d13112350310b2fb9805ffe8e0ce2017 /node_modules/read-package-tree
parent7e5da238ee869201fdb9027c27b79b0f76b440a8 (diff)
read-package-tree@4.1.0
Diffstat (limited to 'node_modules/read-package-tree')
-rw-r--r--node_modules/read-package-tree/LICENSE15
-rw-r--r--node_modules/read-package-tree/README.md56
-rw-r--r--node_modules/read-package-tree/package.json62
-rw-r--r--node_modules/read-package-tree/rpt.js183
-rw-r--r--node_modules/read-package-tree/test/basic.js135
-rw-r--r--node_modules/read-package-tree/test/fixtures/bad/package.json2
-rw-r--r--node_modules/read-package-tree/test/fixtures/deep-archy.txt11
-rw-r--r--node_modules/read-package-tree/test/fixtures/deep/.keep0
-rw-r--r--node_modules/read-package-tree/test/fixtures/empty/node_modules/foo/package.json1
-rw-r--r--node_modules/read-package-tree/test/fixtures/linkedroot-archy.txt11
-rw-r--r--node_modules/read-package-tree/test/fixtures/other/archy.txt2
-rw-r--r--node_modules/read-package-tree/test/fixtures/other/node_modules/.bin0
-rw-r--r--node_modules/read-package-tree/test/fixtures/root/archy.txt11
-rw-r--r--node_modules/read-package-tree/test/fixtures/root/package.json2
-rw-r--r--node_modules/read-package-tree/test/fixtures/selflink/archy.txt13
-rw-r--r--node_modules/read-package-tree/test/fixtures/selflink/package.json2
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"}