diff --git a/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js b/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js index 412d6ce8b7119..f7e5b7e322dd7 100644 --- a/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js +++ b/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js @@ -883,6 +883,8 @@ This is a one-time fix-up, please be patient... // create a virtual root node with the same deps as the node that // is requesting this one, so that we can get all the peer deps in // a context where they're likely to be resolvable. + // Note that the virtual root will also have virtual copies of the + // targets of any child Links, so that they resolve appropriately. const parent = parent_ || this[_virtualRoot](edge.from) const realParent = edge.peer ? edge.from.resolveParent : edge.from @@ -936,11 +938,23 @@ This is a one-time fix-up, please be patient... return this[_virtualRoots].get(node) const vr = new Node({ - path: '/virtual-root', + path: node.realpath, sourceReference: node, legacyPeerDeps: this.legacyPeerDeps, }) + // also need to set up any targets from any link deps, so that + // they are properly reflected in the virtual environment + for (const child of node.children.values()) { + if (child.isLink) { + new Node({ + path: child.realpath, + sourceReference: child.target, + root: vr, + }) + } + } + this[_virtualRoots].set(node, vr) return vr } diff --git a/node_modules/@npmcli/arborist/lib/printable.js b/node_modules/@npmcli/arborist/lib/printable.js index fb73c7c2bc434..588121dbc4283 100644 --- a/node_modules/@npmcli/arborist/lib/printable.js +++ b/node_modules/@npmcli/arborist/lib/printable.js @@ -63,6 +63,13 @@ class ArboristNode { } } +class ArboristVirtualNode extends ArboristNode { + constructor (tree, path) { + super(tree, path) + this.sourceReference = printableTree(tree.sourceReference, path) + } +} + class ArboristLink extends ArboristNode { constructor (tree, path) { super(tree, path) @@ -119,10 +126,14 @@ class EdgeIn extends Edge { } const printableTree = (tree, path = []) => { - if (path.includes(tree)) - return { location: tree.location } + const Cls = tree.isLink ? ArboristLink + : tree.sourceReference ? ArboristVirtualNode + : ArboristNode + if (path.includes(tree)) { + const obj = Object.create(Cls.prototype) + return Object.assign(obj, { location: tree.location }) + } path.push(tree) - const Cls = tree.isLink ? ArboristLink : ArboristNode return new Cls(tree, path) } diff --git a/node_modules/@npmcli/arborist/lib/shrinkwrap.js b/node_modules/@npmcli/arborist/lib/shrinkwrap.js index 828b9f328232e..342e78e9e3a7b 100644 --- a/node_modules/@npmcli/arborist/lib/shrinkwrap.js +++ b/node_modules/@npmcli/arborist/lib/shrinkwrap.js @@ -41,6 +41,7 @@ const readFile = promisify(fs.readFile) const writeFile = promisify(fs.writeFile) const stat = promisify(fs.stat) const readdir_ = promisify(fs.readdir) +const readlink = promisify(fs.readlink) // XXX remove when drop support for node v10 const lstat = promisify(fs.lstat) @@ -176,10 +177,19 @@ const assertNoNewer = async (path, data, lockTime, dir = path, seen = null) => { : readdir(parent, { withFileTypes: true }) return children.catch(() => []) - .then(ents => Promise.all( - ents.filter(ent => ent.isDirectory() && !/^\./.test(ent.name)) - .map(ent => assertNoNewer(path, data, lockTime, resolve(parent, ent.name), seen)) - )).then(() => { + .then(ents => Promise.all(ents.map(async ent => { + const child = resolve(parent, ent.name) + if (ent.isDirectory() && !/^\./.test(ent.name)) + await assertNoNewer(path, data, lockTime, child, seen) + else if (ent.isSymbolicLink()) { + const target = resolve(parent, await readlink(child)) + const tstat = await stat(target).catch(() => null) + seen.add(relpath(path, child)) + if (tstat && tstat.isDirectory() && !seen.has(relpath(path, target))) + await assertNoNewer(path, data, lockTime, target, seen) + } + }))) + .then(() => { if (dir !== path) return diff --git a/node_modules/@npmcli/arborist/package.json b/node_modules/@npmcli/arborist/package.json index 35623f90c44ed..bff10db4b0dd8 100644 --- a/node_modules/@npmcli/arborist/package.json +++ b/node_modules/@npmcli/arborist/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/arborist", - "version": "2.2.7", + "version": "2.2.8", "description": "Manage node_modules trees", "dependencies": { "@npmcli/installed-package-contents": "^1.0.7", diff --git a/package-lock.json b/package-lock.json index 94fd78e92bdac..23fc144462427 100644 --- a/package-lock.json +++ b/package-lock.json @@ -252,7 +252,7 @@ ], "license": "Artistic-2.0", "dependencies": { - "@npmcli/arborist": "^2.2.7", + "@npmcli/arborist": "^2.2.8", "@npmcli/ci-detect": "^1.2.0", "@npmcli/config": "^1.2.9", "@npmcli/run-script": "^1.8.3", @@ -812,9 +812,9 @@ } }, "node_modules/@npmcli/arborist": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/@npmcli/arborist/-/arborist-2.2.7.tgz", - "integrity": "sha512-NulX/tVu45PIXO4DSNpVQkLrN94OjzAUxgLQ7Vsdb1macSmklJwQF0+4jBgC2riMpdWJP+IiFsxg1k9T9RoRRg==", + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/@npmcli/arborist/-/arborist-2.2.8.tgz", + "integrity": "sha512-Wct6W0oXYqc0SU3ad2zr3xIZ0+mOcBRO/hO4JpuYalKIwha+X6es8pj7iexZKLU7ichBSdkEqo+3dqeJg1+qVQ==", "inBundle": true, "dependencies": { "@npmcli/installed-package-contents": "^1.0.7", @@ -10961,9 +10961,9 @@ "dev": true }, "@npmcli/arborist": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/@npmcli/arborist/-/arborist-2.2.7.tgz", - "integrity": "sha512-NulX/tVu45PIXO4DSNpVQkLrN94OjzAUxgLQ7Vsdb1macSmklJwQF0+4jBgC2riMpdWJP+IiFsxg1k9T9RoRRg==", + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/@npmcli/arborist/-/arborist-2.2.8.tgz", + "integrity": "sha512-Wct6W0oXYqc0SU3ad2zr3xIZ0+mOcBRO/hO4JpuYalKIwha+X6es8pj7iexZKLU7ichBSdkEqo+3dqeJg1+qVQ==", "requires": { "@npmcli/installed-package-contents": "^1.0.7", "@npmcli/map-workspaces": "^1.0.2", diff --git a/package.json b/package.json index f8317154f932e..b21b2fba531ef 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "./package.json": "./package.json" }, "dependencies": { - "@npmcli/arborist": "^2.2.7", + "@npmcli/arborist": "^2.2.8", "@npmcli/ci-detect": "^1.2.0", "@npmcli/config": "^1.2.9", "@npmcli/run-script": "^1.8.3",