Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

fix(refactor): use output.buffer and set explicit json mode in query #7534

Merged
merged 1 commit into from
May 17, 2024
Merged
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
73 changes: 37 additions & 36 deletions lib/commands/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,70 +51,71 @@ class Query extends BaseCommand {
'expect-results',
]

get parsedResponse () {
return JSON.stringify(this.#response, null, 2)
constructor (...args) {
super(...args)
this.npm.config.set('json', true)
}

async exec (args) {
// one dir up from wherever node_modules lives
const where = resolve(this.npm.dir, '..')
const packageLock = this.npm.config.get('package-lock-only')
const Arborist = require('@npmcli/arborist')
const opts = {
const arb = new Arborist({
...this.npm.flatOptions,
path: where,
forceActual: true,
}
const arb = new Arborist(opts)
// one dir up from wherever node_modules lives
path: resolve(this.npm.dir, '..'),
forceActual: !packageLock,
})
let tree
if (this.npm.config.get('package-lock-only')) {
if (packageLock) {
try {
tree = await arb.loadVirtual()
} catch (err) {
log.verbose('loadVirtual', err.stack)
/* eslint-disable-next-line max-len */
throw this.usageError('A package lock or shrinkwrap file is required in package-lock-only mode')
throw this.usageError(
'A package lock or shrinkwrap file is required in package-lock-only mode'
)
}
} else {
tree = await arb.loadActual(opts)
tree = await arb.loadActual()
}
const items = await tree.querySelectorAll(args[0], this.npm.flatOptions)
this.buildResponse(items)

this.checkExpected(this.#response.length)
output.standard(this.parsedResponse)
await this.#queryTree(tree, args[0])
this.#output()
}

async execWorkspaces (args) {
await this.setWorkspaces()
const Arborist = require('@npmcli/arborist')
const opts = {
const arb = new Arborist({
...this.npm.flatOptions,
path: this.npm.prefix,
})
// FIXME: Workspace support in query does not work as expected so this does not
// do the same package-lock-only check as this.exec().
// https://github.com/npm/cli/pull/6732#issuecomment-1708804921
const tree = await arb.loadActual()
for (const path of this.workspacePaths) {
const wsTree = path === tree.root.path
? tree // --includes-workspace-root
: await tree.querySelectorAll(`.workspace:path(${path})`).then(r => r[0].target)
await this.#queryTree(wsTree, args[0])
}
const arb = new Arborist(opts)
const tree = await arb.loadActual(opts)
for (const workspacePath of this.workspacePaths) {
let items
if (workspacePath === tree.root.path) {
// include-workspace-root
items = await tree.querySelectorAll(args[0])
} else {
const [workspace] = await tree.querySelectorAll(`.workspace:path(${workspacePath})`)
items = await workspace.target.querySelectorAll(args[0], this.npm.flatOptions)
}
this.buildResponse(items)
}
this.#output()
}

#output () {
this.checkExpected(this.#response.length)
output.standard(this.parsedResponse)
output.buffer(this.#response)
}

// builds a normalized inventory
buildResponse (items) {
async #queryTree (tree, arg) {
const items = await tree.querySelectorAll(arg, this.npm.flatOptions)
for (const node of items) {
if (!node.target.location || !this.#seen.has(node.target.location)) {
const { location } = node.target
if (!location || !this.#seen.has(location)) {
const item = new QuerySelectorItem(node)
this.#response.push(item)
if (node.target.location) {
if (location) {
this.#seen.add(item.location)
}
}
Expand Down
Loading