Skip to content

Commit 2f5392a

Browse files
authored
fix: make npm run autocomplete work with workspaces (#8135)
PR makes `npm run` completion to take workspaces into account in case of cwd is inside workspace dir it will autocompletes from `scripts` section of nearest workspace's package. Former behavoiur was to autocomplete everything from workspace root package, it has no sense since when you are in workspace directory script which will be suggested in such manner will not work. So there was a mismatch between the script launch and the autocomplete hint areas. ## References Fixes [#7114](#7114)
1 parent 679bc4a commit 2f5392a

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

lib/commands/run-script.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,11 @@ class RunScript extends BaseCommand {
2626
static async completion (opts, npm) {
2727
const argv = opts.conf.argv.remain
2828
if (argv.length === 2) {
29-
const { content: { scripts = {} } } = await pkgJson.normalize(npm.localPrefix)
29+
const workspacePrefixes = npm.config.get('workspace', 'default')
30+
const localPrefix = workspacePrefixes.length
31+
? workspacePrefixes[0]
32+
: npm.localPrefix
33+
const { content: { scripts = {} } } = await pkgJson.normalize(localPrefix)
3034
.catch(() => ({ content: {} }))
3135
if (opts.isFish) {
3236
return Object.keys(scripts).map(s => `${s}\t${scripts[s].slice(0, 30)}`)

test/lib/commands/run-script.js

+19
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const { resolve } = require('node:path')
33
const realRunScript = require('@npmcli/run-script')
44
const mockNpm = require('../../fixtures/mock-npm')
55
const { cleanCwd } = require('../../fixtures/clean-snapshot')
6+
const path = require('node:path')
67

78
const mockRs = async (t, { windows = false, runScript, ...opts } = {}) => {
89
let RUN_SCRIPTS = []
@@ -511,6 +512,7 @@ t.test('workspaces', async t => {
511512
prefixDir,
512513
workspaces = true,
513514
exec = [],
515+
chdir = ({ prefix }) => prefix,
514516
...config
515517
} = {}) => {
516518
const mock = await mockRs(t, {
@@ -574,6 +576,7 @@ t.test('workspaces', async t => {
574576
...Array.isArray(workspaces) ? { workspace: workspaces } : { workspaces },
575577
...config,
576578
},
579+
chdir,
577580
runScript,
578581
})
579582
if (exec) {
@@ -582,6 +585,22 @@ t.test('workspaces', async t => {
582585
return mock
583586
}
584587

588+
t.test('completion', async t => {
589+
t.test('in root dir', async t => {
590+
const { runScript } = await mockWorkspaces(t)
591+
const res = await runScript.completion({ conf: { argv: { remain: ['npm', 'run'] } } })
592+
t.strictSame(res, [])
593+
})
594+
595+
t.test('in workspace dir', async t => {
596+
const { runScript } = await mockWorkspaces(t, {
597+
chdir: ({ prefix }) => path.join(prefix, 'packages/c'),
598+
})
599+
const res = await runScript.completion({ conf: { argv: { remain: ['npm', 'run'] } } })
600+
t.strictSame(res, ['test', 'posttest', 'lorem'])
601+
})
602+
})
603+
585604
t.test('list all scripts', async t => {
586605
const { joinedOutput } = await mockWorkspaces(t)
587606
t.matchSnapshot(joinedOutput())

0 commit comments

Comments
 (0)