Skip to content
This repository was archived by the owner on Jan 20, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion lib/arborist/build-ideal-tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
}
Expand Down
17 changes: 14 additions & 3 deletions lib/printable.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
}

Expand Down
18 changes: 14 additions & 4 deletions lib/shrinkwrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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

Expand Down
Loading