Skip to content

Commit ad30872

Browse files
committed
fix(did-you-mean): succeed if cwd is not a package
The did-you-mean code was trying to parse a local package.json to suggest scripts and bins, which was causing an exception if you ran npm outside of a directory with a valid package.json. This fixes that.
1 parent ac8e4ad commit ad30872

File tree

2 files changed

+30
-18
lines changed

2 files changed

+30
-18
lines changed

lib/utils/did-you-mean.js

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,26 @@ const readJson = require('read-package-json-fast')
33
const { cmdList } = require('./cmd-list.js')
44

55
const didYouMean = async (npm, path, scmd) => {
6-
const bestCmd = cmdList
6+
let best = cmdList
77
.filter(cmd => distance(scmd, cmd) < scmd.length * 0.4 && scmd !== cmd)
88
.map(str => ` npm ${str} # ${npm.commands[str].description}`)
99

10-
const pkg = await readJson(`${path}/package.json`)
11-
const { scripts } = pkg
1210
// We would already be suggesting this in `npm x` so omit them here
1311
const runScripts = ['stop', 'start', 'test', 'restart']
14-
const bestRun = Object.keys(scripts || {})
15-
.filter(cmd => distance(scmd, cmd) < scmd.length * 0.4 &&
16-
!runScripts.includes(cmd))
17-
.map(str => ` npm run ${str} # run the "${str}" package script`)
18-
19-
const { bin } = pkg
20-
const bestBin = Object.keys(bin || {})
21-
.filter(cmd => distance(scmd, cmd) < scmd.length * 0.4)
22-
.map(str => ` npm exec ${str} # run the "${str}" command from either this or a remote npm package`)
23-
24-
const best = [...bestCmd, ...bestRun, ...bestBin]
12+
try {
13+
const { bin, scripts } = await readJson(`${path}/package.json`)
14+
best = best.concat(
15+
Object.keys(scripts || {})
16+
.filter(cmd => distance(scmd, cmd) < scmd.length * 0.4 &&
17+
!runScripts.includes(cmd))
18+
.map(str => ` npm run ${str} # run the "${str}" package script`),
19+
Object.keys(bin || {})
20+
.filter(cmd => distance(scmd, cmd) < scmd.length * 0.4)
21+
.map(str => ` npm exec ${str} # run the "${str}" command from either this or a remote npm package`)
22+
)
23+
} catch (_) {
24+
// gracefully ignore not being in a folder w/ a package.json
25+
}
2526

2627
if (best.length === 0)
2728
return ''

test/lib/utils/did-you-mean.js

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,34 @@ const npm = require('../../../lib/npm.js')
33

44
const dym = require('../../../lib/utils/did-you-mean.js')
55
t.test('did-you-mean', t => {
6+
const testdir = t.testdir({
7+
'package.json': JSON.stringify({
8+
bin: {
9+
npx: 'exists',
10+
},
11+
scripts: {
12+
install: 'exists',
13+
posttest: 'exists',
14+
},
15+
}),
16+
})
617
npm.load(err => {
718
t.notOk(err)
819
t.test('nistall', async t => {
9-
const result = await dym(npm, npm.localPrefix, 'nistall')
20+
const result = await dym(npm, testdir, 'nistall')
1021
t.match(result, 'npm install')
1122
})
1223
t.test('sttest', async t => {
13-
const result = await dym(npm, npm.localPrefix, 'sttest')
24+
const result = await dym(npm, testdir, 'sttest')
1425
t.match(result, 'npm test')
1526
t.match(result, 'npm run posttest')
1627
})
1728
t.test('npz', async t => {
18-
const result = await dym(npm, npm.localPrefix, 'npxx')
29+
const result = await dym(npm, testdir, 'npxx')
1930
t.match(result, 'npm exec npx')
2031
})
2132
t.test('qwuijbo', async t => {
22-
const result = await dym(npm, npm.localPrefix, 'qwuijbo')
33+
const result = await dym(npm, testdir, 'qwuijbo')
2334
t.match(result, '')
2435
})
2536
t.end()

0 commit comments

Comments
 (0)