Skip to content

Commit

Permalink
fix: implement deduped
Browse files Browse the repository at this point in the history
  • Loading branch information
wraithgar committed Jul 18, 2022
1 parent ca4857f commit a1ed199
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 19 deletions.
8 changes: 4 additions & 4 deletions docs/content/using-npm/dependency-selectors.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ The [`npm query`](/commands/npm-query) commmand exposes a new dependency selecto
- `.dev` dependency found in the `devDependencies` section of `package.json`, or is a child of said dependency
- `.optional` dependency found in the `optionalDependencies` section of `package.json`, or has `"optional": true` set in its entry in the `peerDependenciesMeta` section of `package.json`, or a child of said dependency
- `.peer` dependency found in the `peerDependencies` section of `package.json`
- `.workspace` dependency found in the `workspaces` section of `package.json`
- `.workspace` dependency found in the [`workspaces`](https://docs.npmjs.com/cli/v8/using-npm/workspaces) section of `package.json`
- `.bundled` dependency found in the `bundleDependencies` section of `package.json`, or is a child of said dependency

#### Pseudo Selectors
Expand All @@ -52,9 +52,9 @@ The [`npm query`](/commands/npm-query) commmand exposes a new dependency selecto
- [`:scope`](https://developer.mozilla.org/en-US/docs/Web/CSS/:scope) matches node/dependency it was queried against
- [`:empty`](https://developer.mozilla.org/en-US/docs/Web/CSS/:empty) when a dependency has no dependencies
- [`:private`](https://docs.npmjs.com/cli/v8/configuring-npm/package-json#private) when a dependency is private
- `:link` when a dependency is linked
- `:deduped` when a dependency has been deduped
- `:override` when a dependency is an override
- `:link` when a dependency is linked (for instance, workspaces or packages manually [`linked`](https://docs.npmjs.com/cli/v8/commands/npm-link)
- `:deduped` when a dependency has been deduped (note that this does *not* always mean the dependency has been hoisted to the root of node_modules)
- `:override` when a dependency is an override (not implemented yet)
- `:extraneous` when a dependency exists but is not defined as a dependency of any node
- `:invalid` when a dependency version is out of its ancestors specified range
- `:missing` when a dependency is not found on disk
Expand Down
12 changes: 6 additions & 6 deletions lib/commands/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ class QuerySelectorItem {
this.to = []
this.dev = node.target.dev
this.inBundle = node.target.inBundle
this.deduped = this.from.length > 1
for (const edge of node.target.edgesIn) {
this.from.push(edge.from.location)
}
for (const [, edge] of node.target.edgesOut) {
this.to.push(edge.to.location)
if (edge.to) {
this.to.push(edge.to.location)
}
}
}
}
Expand Down Expand Up @@ -89,11 +92,8 @@ class Query extends BaseCommand {
// builds a normalized inventory
buildResponse (items) {
for (const node of items) {
if (!this.#seen.has(node.target.location)) {
const item = new QuerySelectorItem(node)
this.#response.push(item)
this.#seen.add(item.realpath)
}
const item = new QuerySelectorItem(node)
this.#response.push(item)
}
}
}
Expand Down
83 changes: 74 additions & 9 deletions tap-snapshots/test/lib/commands/query.js.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ exports[`test/lib/commands/query.js TAP global > should return global package 1`
],
"to": [],
"dev": false,
"inBundle": false
"inBundle": false,
"deduped": false
}
]
`
Expand Down Expand Up @@ -49,7 +50,8 @@ exports[`test/lib/commands/query.js TAP include-workspace-root > should return w
"node_modules/b"
],
"dev": false,
"inBundle": false
"inBundle": false,
"deduped": false
},
{
"name": "c",
Expand All @@ -63,7 +65,8 @@ exports[`test/lib/commands/query.js TAP include-workspace-root > should return w
"from": [],
"to": [],
"dev": false,
"inBundle": false
"inBundle": false,
"deduped": false
}
]
`
Expand All @@ -82,7 +85,8 @@ exports[`test/lib/commands/query.js TAP linked node > should return linked node
"from": [],
"to": [],
"dev": false,
"inBundle": false
"inBundle": false,
"deduped": false
},
{
"name": "a",
Expand All @@ -96,7 +100,61 @@ exports[`test/lib/commands/query.js TAP linked node > should return linked node
"from": [],
"to": [],
"dev": false,
"inBundle": false
"inBundle": false,
"deduped": false
}
]
`

exports[`test/lib/commands/query.js TAP recursive tree > should return everything in the tree, accounting for recursion 1`] = `
[
{
"name": "project",
"dependencies": {
"a": "^1.0.0",
"b": "^1.0.0"
},
"pkgid": "project@",
"location": "",
"path": "{CWD}/test/lib/commands/tap-testdir-query-recursive-tree/prefix",
"realpath": "{CWD}/test/lib/commands/tap-testdir-query-recursive-tree/prefix",
"resolved": null,
"from": [],
"to": [
"node_modules/a",
"node_modules/b"
],
"dev": false,
"inBundle": false,
"deduped": false
},
{
"pkgid": "a@",
"location": "node_modules/a",
"path": "{CWD}/test/lib/commands/tap-testdir-query-recursive-tree/prefix/node_modules/a",
"realpath": "{CWD}/test/lib/commands/tap-testdir-query-recursive-tree/prefix/node_modules/a",
"resolved": null,
"from": [
""
],
"to": [],
"dev": false,
"inBundle": false,
"deduped": false
},
{
"pkgid": "b@",
"location": "node_modules/b",
"path": "{CWD}/test/lib/commands/tap-testdir-query-recursive-tree/prefix/node_modules/b",
"realpath": "{CWD}/test/lib/commands/tap-testdir-query-recursive-tree/prefix/node_modules/b",
"resolved": null,
"from": [
""
],
"to": [],
"dev": false,
"inBundle": false,
"deduped": false
}
]
`
Expand All @@ -109,6 +167,9 @@ exports[`test/lib/commands/query.js TAP simple query > should return root object
"a": "^1.0.0",
"b": "^1.0.0"
},
"peerDependencies": {
"c": "1.0.0"
},
"pkgid": "project@",
"location": "",
"path": "{CWD}/test/lib/commands/tap-testdir-query-simple-query/prefix",
Expand All @@ -120,7 +181,8 @@ exports[`test/lib/commands/query.js TAP simple query > should return root object
"node_modules/b"
],
"dev": false,
"inBundle": false
"inBundle": false,
"deduped": false
},
{
"pkgid": "a@",
Expand All @@ -133,7 +195,8 @@ exports[`test/lib/commands/query.js TAP simple query > should return root object
],
"to": [],
"dev": false,
"inBundle": false
"inBundle": false,
"deduped": false
},
{
"pkgid": "b@",
Expand All @@ -146,7 +209,8 @@ exports[`test/lib/commands/query.js TAP simple query > should return root object
],
"to": [],
"dev": false,
"inBundle": false
"inBundle": false,
"deduped": false
}
]
`
Expand All @@ -165,7 +229,8 @@ exports[`test/lib/commands/query.js TAP workspace query > should return workspac
"from": [],
"to": [],
"dev": false,
"inBundle": false
"inBundle": false,
"deduped": false
}
]
`
31 changes: 31 additions & 0 deletions test/lib/commands/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,44 @@ t.test('simple query', async t => {
a: '^1.0.0',
b: '^1.0.0',
},
peerDependencies: {
c: '1.0.0',
},
}),
},
})
await npm.exec('query', [':root, :root > *'])
t.matchSnapshot(joinedOutput(), 'should return root object and direct children')
})

t.test('recursive tree', async t => {
const { npm, joinedOutput } = await loadMockNpm(t, {
prefixDir: {
node_modules: {
a: {
name: 'a',
version: '1.0.0',
},
b: {
name: 'b',
version: '^2.0.0',
dependencies: {
a: '1.0.0',
},
},
},
'package.json': JSON.stringify({
name: 'project',
dependencies: {
a: '^1.0.0',
b: '^1.0.0',
},
}),
},
})
await npm.exec('query', ['*'])
t.matchSnapshot(joinedOutput(), 'should return everything in the tree, accounting for recursion')
})
t.test('workspace query', async t => {
const { npm, joinedOutput } = await loadMockNpm(t, {
config: {
Expand Down
4 changes: 4 additions & 0 deletions workspaces/arborist/lib/query-selector-all.js
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,10 @@ class Results {
return found
})
}

dedupedPseudo () {
return this.initialItems.filter(node => node.target.edgesIn.size > 1)
}
}

// operators for attribute selectors
Expand Down
5 changes: 5 additions & 0 deletions workspaces/arborist/test/query-selector-all.js
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,11 @@ t.test('query-selector-all', async t => {
[':invalid', ['lorem@1.0.0']],
[':link', ['a@1.0.0', 'b@1.0.0']],
[':link', ['a@1.0.0', 'b@1.0.0']],
[':deduped', [
'bar@2.0.0',
'moo@3.0.0',
'recur@1.0.0',
]],
[':missing', ['missing-dep@^1.0.0']],
[':private', ['b@1.0.0']],

Expand Down

0 comments on commit a1ed199

Please sign in to comment.