diff options
Diffstat (limited to 'deps/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js')
-rw-r--r-- | deps/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js index 7ef42289d29..cda7f8acfb5 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js @@ -9,6 +9,9 @@ const { resolve, dirname } = require('path') const { promisify } = require('util') const treeCheck = require('../tree-check.js') const readdir = promisify(require('readdir-scoped-modules')) +const fs = require('fs') +const lstat = promisify(fs.lstat) +const readlink = promisify(fs.readlink) const { depth } = require('treeverse') const { @@ -407,7 +410,14 @@ module.exports = cls => class IdealTreeBuilder extends cls { if (this[_updateAll] || updateName) { if (updateName) globalExplicitUpdateNames.push(name) - tree.package.dependencies[name] = '*' + const dir = resolve(nm, name) + const st = await lstat(dir).catch(/* istanbul ignore next */ er => null) + if (st && st.isSymbolicLink()) { + const target = await readlink(dir) + const real = resolve(dirname(dir), target) + tree.package.dependencies[name] = `file:${real}` + } else + tree.package.dependencies[name] = '*' } } } @@ -982,7 +992,6 @@ This is a one-time fix-up, please be patient... // 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 const spec = npa.resolve(edge.name, edge.spec, edge.from.path) const first = await this[_nodeFromSpec](edge.name, spec, parent, edge) @@ -1013,19 +1022,18 @@ This is a one-time fix-up, please be patient... required.has(secondEdge.from) && secondEdge.type !== 'peerOptional')) required.add(node) - // handle otherwise unresolvable dependency nesting loops by - // creating a symbolic link - // a1 -> b1 -> a2 -> b2 -> a1 -> ... - // instead of nesting forever, when the loop occurs, create - // a symbolic link to the earlier instance - for (let p = edge.from.resolveParent; p; p = p.resolveParent) { - if (p.matches(node) && !p.isTop) - return new Link({ parent: realParent, target: p }) - } - // keep track of the thing that caused this node to be included. const src = parent.sourceReference this[_peerSetSource].set(node, src) + + // do not load the peers along with the set if this is a global top pkg + // otherwise we'll be tempted to put peers as other top-level installed + // things, potentially clobbering what's there already, which is not + // what we want. the missing edges will be picked up on the next pass. + if (this[_global] && edge.from.isProjectRoot) + return node + + // otherwise, we have to make sure that our peers can go along with us. return this[_loadPeerSet](node, required) } |