mirror of
https://github.com/nodejs/node.git
synced 2025-05-13 19:50:17 +00:00

PR-URL: https://github.com/nodejs/node/pull/40055 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Beth Griggs <bgriggs@redhat.com>
156 lines
4.0 KiB
JavaScript
156 lines
4.0 KiB
JavaScript
const debug = require('./debug.js')
|
|
|
|
const checkTree = (tree, checkUnreachable = true) => {
|
|
const log = [['START TREE CHECK', tree.path]]
|
|
|
|
// this can only happen in tests where we have a "tree" object
|
|
// that isn't actually a tree.
|
|
if (!tree.root || !tree.root.inventory) {
|
|
return tree
|
|
}
|
|
|
|
const { inventory } = tree.root
|
|
const seen = new Set()
|
|
const check = (node, via = tree, viaType = 'self') => {
|
|
log.push([
|
|
'CHECK',
|
|
node && node.location,
|
|
via && via.location,
|
|
viaType,
|
|
'seen=' + seen.has(node),
|
|
'promise=' + !!(node && node.then),
|
|
'root=' + !!(node && node.isRoot),
|
|
])
|
|
|
|
if (!node || seen.has(node) || node.then) {
|
|
return
|
|
}
|
|
|
|
seen.add(node)
|
|
|
|
if (node.isRoot && node !== tree.root) {
|
|
throw Object.assign(new Error('double root'), {
|
|
node: node.path,
|
|
realpath: node.realpath,
|
|
tree: tree.path,
|
|
root: tree.root.path,
|
|
via: via.path,
|
|
viaType,
|
|
log,
|
|
})
|
|
}
|
|
|
|
if (node.root !== tree.root) {
|
|
throw Object.assign(new Error('node from other root in tree'), {
|
|
node: node.path,
|
|
realpath: node.realpath,
|
|
tree: tree.path,
|
|
root: tree.root.path,
|
|
via: via.path,
|
|
viaType,
|
|
otherRoot: node.root && node.root.path,
|
|
log,
|
|
})
|
|
}
|
|
|
|
if (!node.isRoot && node.inventory.size !== 0) {
|
|
throw Object.assign(new Error('non-root has non-zero inventory'), {
|
|
node: node.path,
|
|
tree: tree.path,
|
|
root: tree.root.path,
|
|
via: via.path,
|
|
viaType,
|
|
inventory: [...node.inventory.values()].map(node =>
|
|
[node.path, node.location]),
|
|
log,
|
|
})
|
|
}
|
|
|
|
if (!node.isRoot && !inventory.has(node) && !node.dummy) {
|
|
throw Object.assign(new Error('not in inventory'), {
|
|
node: node.path,
|
|
tree: tree.path,
|
|
root: tree.root.path,
|
|
via: via.path,
|
|
viaType,
|
|
log,
|
|
})
|
|
}
|
|
|
|
const devEdges = [...node.edgesOut.values()].filter(e => e.dev)
|
|
if (!node.isTop && devEdges.length) {
|
|
throw Object.assign(new Error('dev edges on non-top node'), {
|
|
node: node.path,
|
|
tree: tree.path,
|
|
root: tree.root.path,
|
|
via: via.path,
|
|
viaType,
|
|
devEdges: devEdges.map(e => [e.type, e.name, e.spec, e.error]),
|
|
log,
|
|
})
|
|
}
|
|
|
|
if (node.path === tree.root.path && node !== tree.root) {
|
|
throw Object.assign(new Error('node with same path as root'), {
|
|
node: node.path,
|
|
tree: tree.path,
|
|
root: tree.root.path,
|
|
via: via.path,
|
|
viaType,
|
|
log,
|
|
})
|
|
}
|
|
|
|
if (!node.isLink && node.path !== node.realpath) {
|
|
throw Object.assign(new Error('non-link with mismatched path/realpath'), {
|
|
node: node.path,
|
|
tree: tree.path,
|
|
realpath: node.realpath,
|
|
root: tree.root.path,
|
|
via: via.path,
|
|
viaType,
|
|
log,
|
|
})
|
|
}
|
|
|
|
const { parent, fsParent, target } = node
|
|
check(parent, node, 'parent')
|
|
check(fsParent, node, 'fsParent')
|
|
check(target, node, 'target')
|
|
log.push(['CHILDREN', node.location, ...node.children.keys()])
|
|
for (const kid of node.children.values()) {
|
|
check(kid, node, 'children')
|
|
}
|
|
for (const kid of node.fsChildren) {
|
|
check(kid, node, 'fsChildren')
|
|
}
|
|
for (const link of node.linksIn) {
|
|
check(link, node, 'linksIn')
|
|
}
|
|
for (const top of node.tops) {
|
|
check(top, node, 'tops')
|
|
}
|
|
log.push(['DONE', node.location])
|
|
}
|
|
check(tree)
|
|
if (checkUnreachable) {
|
|
for (const node of inventory.values()) {
|
|
if (!seen.has(node) && node !== tree.root) {
|
|
throw Object.assign(new Error('unreachable in inventory'), {
|
|
node: node.path,
|
|
realpath: node.realpath,
|
|
location: node.location,
|
|
root: tree.root.path,
|
|
tree: tree.path,
|
|
log,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
return tree
|
|
}
|
|
|
|
// should only ever run this check in debug mode
|
|
module.exports = tree => tree
|
|
debug(() => module.exports = checkTree)
|