Skip to content

Commit 4b7f558

Browse files
committed
fix: workspace query bug
Fixes a query bug which omits some dependencies in scenarios where a workspace has a dependency on another workspace in the project. Signed-off-by: Brian DeHamer <bdehamer@github.com>
1 parent 1c93c44 commit 4b7f558

File tree

2 files changed

+26
-14
lines changed

2 files changed

+26
-14
lines changed

workspaces/arborist/lib/query-selector-all.js

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -710,25 +710,33 @@ const hasParent = (node, compareNodes) => {
710710
return false
711711
}
712712

713-
// checks if a given node is a descendant of any of the nodes provided in the
714-
// compareNodes array
715-
const hasAscendant = (node, compareNodes, seen = new Set()) => {
716-
// TODO (future) loop over ancestry property
717-
if (hasParent(node, compareNodes)) {
718-
return true
713+
// checks if a given node is a child of the provided compareNode
714+
const isChild = (node, compareNode) => {
715+
for (const edge of compareNode.edgesOut.values()) {
716+
if (edge.to === node || edge.to?.target === node) {
717+
return true
718+
}
719719
}
720+
return false
721+
}
720722

721-
if (node.isTop && node.resolveParent) {
722-
return hasAscendant(node.resolveParent, compareNodes)
723+
// checks if a given node is the descendant of the provided compareNode
724+
const isDescendant = (node, compareNode, seen = new Set()) => {
725+
// Direct child
726+
if (isChild(node, compareNode)) {
727+
return true
723728
}
724-
for (const edge of node.edgesIn) {
725-
// TODO Need a test with an infinite loop
729+
730+
// Loop through edgesOut of compareNode to see if there is a path to node
731+
for (const edge of compareNode.edgesOut.values()) {
726732
if (seen.has(edge)) {
727733
continue
728734
}
729735
seen.add(edge)
730-
if (edge && edge.from && hasAscendant(edge.from, compareNodes, seen)) {
731-
return true
736+
if (edge.to) {
737+
if (isDescendant(node, edge.to.isLink ? edge.to.target : edge.to, seen)) {
738+
return true
739+
}
732740
}
733741
}
734742
return false
@@ -741,7 +749,9 @@ const combinators = {
741749
},
742750
// any descendant
743751
' ' (prevResults, nextResults) {
744-
return nextResults.filter(node => hasAscendant(node, prevResults))
752+
return nextResults.filter(node =>
753+
prevResults.some(compareNode => isDescendant(node, compareNode))
754+
)
745755
},
746756
// sibling
747757
'~' (prevResults, nextResults) {

workspaces/arborist/test/query-selector-all.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ t.test('query-selector-all', async t => {
2424
│ └── lorem@1.0.0 (production dep of baz)
2525
├── abbrev@1.1.1 (production dep of query-selector-all-tests)
2626
├─┬ b@1.0.0 -> ./b (workspace)
27+
│ ├── a@2.0.0 (dev dep of b, deduped)
2728
│ └── bar@2.0.0 (production dep of b, deduped)
2829
├─┬ bar@2.0.0 (production dep of query-selector-all-tests)
2930
│ └── moo@3.0.0 (production dep of bar)
@@ -513,7 +514,7 @@ t.test('query-selector-all', async t => {
513514
['*:has(* > #bar:semver(1.4.0))', ['foo@2.2.2']],
514515
['*:has(> #bar:semver(1.4.0))', ['foo@2.2.2']],
515516
['.workspace:has(> * > #lorem)', ['a@1.0.0']],
516-
['.workspace:has(* #lorem, ~ #b)', ['a@1.0.0']],
517+
['.workspace:has(* #lorem, ~ #b)', ['a@1.0.0', 'b@1.0.0']],
517518

518519
// is pseudo
519520
[':is(#a, #b) > *', ['a@1.0.0', 'bar@2.0.0', 'baz@1.0.0']],
@@ -960,5 +961,6 @@ t.test('query-selector-all', async t => {
960961
[':root #bar:semver(1) ~ *', ['dash-separated-pkg@1.0.0']],
961962
['#bar:semver(2), #foo', ['bar@2.0.0', 'foo@2.2.2']],
962963
['#a, #bar:semver(2), #foo:semver(2.2.2)', ['a@1.0.0', 'bar@2.0.0', 'foo@2.2.2']],
964+
['#b *', ['a@1.0.0', 'bar@2.0.0', 'baz@1.0.0', 'lorem@1.0.0', 'moo@3.0.0']],
963965
])
964966
})

0 commit comments

Comments
 (0)