Skip to content

Commit 8fd614a

Browse files
nlfwraithgar
authored andcommitted
fix: use promiseSpawn.open instead of opener
1 parent 41843ad commit 8fd614a

File tree

11 files changed

+81
-87
lines changed

11 files changed

+81
-87
lines changed

lib/utils/open-url-prompt.js

+2-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const readline = require('readline')
2-
const opener = require('opener')
2+
const promiseSpawn = require('@npmcli/promise-spawn')
33

44
function print (npm, title, url) {
55
const json = npm.config.get('json')
@@ -64,15 +64,7 @@ const promptOpen = async (npm, url, title, prompt, emitter) => {
6464
}
6565

6666
const command = browser === true ? null : browser
67-
await new Promise((resolve, reject) => {
68-
opener(url, { command }, err => {
69-
if (err) {
70-
return reject(err)
71-
}
72-
73-
return resolve()
74-
})
75-
})
67+
await promiseSpawn.open(url, { command })
7668
}
7769

7870
module.exports = promptOpen

lib/utils/open-url.js

+7-11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const opener = require('opener')
1+
const promiseSpawn = require('@npmcli/promise-spawn')
22

33
const { URL } = require('url')
44

@@ -37,18 +37,14 @@ const open = async (npm, url, errMsg, isFile) => {
3737
}
3838

3939
const command = browser === true ? null : browser
40-
await new Promise((resolve, reject) => {
41-
opener(url, { command }, (err) => {
42-
if (err) {
43-
if (err.code === 'ENOENT') {
44-
printAlternateMsg()
45-
} else {
46-
return reject(err)
47-
}
40+
await promiseSpawn.open(url, { command })
41+
.catch((err) => {
42+
if (err.code !== 'ENOENT') {
43+
throw err
4844
}
49-
return resolve()
45+
46+
printAlternateMsg()
5047
})
51-
})
5248
}
5349

5450
module.exports = open

smoke-tests/test/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ const exec = async (...args) => {
9393
env: {
9494
HOME: path,
9595
PATH: `${PATH}:${binLocation}`,
96+
COMSPEC: process.env.COMSPEC,
9697
},
9798
stdioString: true,
9899
encoding: 'utf-8',

test/fixtures/sandbox.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -166,14 +166,14 @@ class Sandbox extends EventEmitter {
166166
// replace default config values with placeholders
167167
for (const name of redactedDefaults) {
168168
const value = this[_npm].config.defaults[name]
169-
clean = clean.split(value).join(`{${name.toUpperCase()}}`)
169+
clean = clean.split(normalize(value)).join(`{${name.toUpperCase()}}`)
170170
}
171171

172172
// replace vague default config values that are present within quotes
173173
// with placeholders
174174
for (const name of vagueRedactedDefaults) {
175175
const value = this[_npm].config.defaults[name]
176-
clean = clean.split(`"${value}"`).join(`"{${name.toUpperCase()}}"`)
176+
clean = clean.split(`"${normalize(value)}"`).join(`"{${name.toUpperCase()}}"`)
177177
}
178178
}
179179

test/lib/commands/edit.js

+23-20
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,11 @@ const { load: loadMockNpm } = require('../../fixtures/mock-npm')
55

66
const spawk = tspawk(t)
77

8-
// TODO this ... smells. npm "script-shell" config mentions defaults but those
9-
// are handled by run-script, not npm. So for now we have to tie tests to some
10-
// pretty specific internals of runScript
11-
const makeSpawnArgs = require('@npmcli/run-script/lib/make-spawn-args.js')
12-
138
const npmConfig = {
149
config: {
1510
'ignore-scripts': false,
1611
editor: 'testeditor',
12+
scriptShell: process.platform === 'win32' ? process.env.COMSPEC : 'sh',
1713
},
1814
prefixDir: {
1915
node_modules: {
@@ -34,30 +30,34 @@ const npmConfig = {
3430
},
3531
}
3632

33+
const isCmdRe = /(?:^|\\)cmd(?:\.exe)?$/i
34+
3735
t.test('npm edit', async t => {
3836
const { npm, joinedOutput } = await loadMockNpm(t, npmConfig)
3937

4038
const semverPath = path.resolve(npm.prefix, 'node_modules', 'semver')
41-
const [scriptShell, scriptArgs] = makeSpawnArgs({
42-
event: 'install',
43-
path: npm.prefix,
44-
cmd: 'testinstall',
45-
})
4639
spawk.spawn('testeditor', [semverPath])
40+
41+
const scriptShell = npm.config.get('scriptShell')
42+
const scriptArgs = isCmdRe.test(scriptShell)
43+
? ['/d', '/s', '/c', 'testinstall']
44+
: ['-c', 'testinstall']
4745
spawk.spawn(scriptShell, scriptArgs, { cwd: semverPath })
46+
4847
await npm.exec('edit', ['semver'])
4948
t.match(joinedOutput(), 'rebuilt dependencies successfully')
5049
})
5150

5251
t.test('rebuild failure', async t => {
5352
const { npm } = await loadMockNpm(t, npmConfig)
53+
5454
const semverPath = path.resolve(npm.prefix, 'node_modules', 'semver')
55-
const [scriptShell, scriptArgs] = makeSpawnArgs({
56-
event: 'install',
57-
path: npm.prefix,
58-
cmd: 'testinstall',
59-
})
6055
spawk.spawn('testeditor', [semverPath])
56+
57+
const scriptShell = npm.config.get('scriptShell')
58+
const scriptArgs = isCmdRe.test(scriptShell)
59+
? ['/d', '/s', '/c', 'testinstall']
60+
: ['-c', 'testinstall']
6161
spawk.spawn(scriptShell, scriptArgs, { cwd: semverPath }).exit(1).stdout('test error')
6262
await t.rejects(
6363
npm.exec('edit', ['semver']),
@@ -67,8 +67,10 @@ t.test('rebuild failure', async t => {
6767

6868
t.test('editor failure', async t => {
6969
const { npm } = await loadMockNpm(t, npmConfig)
70+
7071
const semverPath = path.resolve(npm.prefix, 'node_modules', 'semver')
7172
spawk.spawn('testeditor', [semverPath]).exit(1).stdout('test editor failure')
73+
7274
await t.rejects(
7375
npm.exec('edit', ['semver']),
7476
{ message: 'editor process exited with code: 1' }
@@ -85,13 +87,14 @@ t.test('npm edit editor has flags', async t => {
8587
})
8688

8789
const semverPath = path.resolve(npm.prefix, 'node_modules', 'semver')
88-
const [scriptShell, scriptArgs] = makeSpawnArgs({
89-
event: 'install',
90-
path: npm.prefix,
91-
cmd: 'testinstall',
92-
})
9390
spawk.spawn('testeditor', ['--flag', semverPath])
91+
92+
const scriptShell = npm.config.get('scriptShell')
93+
const scriptArgs = isCmdRe.test(scriptShell)
94+
? ['/d', '/s', '/c', 'testinstall']
95+
: ['-c', 'testinstall']
9496
spawk.spawn(scriptShell, scriptArgs, { cwd: semverPath })
97+
9598
await npm.exec('edit', ['semver'])
9699
})
97100

test/lib/commands/restart.js

+7-11
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ const { load: loadMockNpm } = require('../../fixtures/mock-npm')
44

55
const spawk = tspawk(t)
66

7-
// TODO this ... smells. npm "script-shell" config mentions defaults but those
8-
// are handled by run-script, not npm. So for now we have to tie tests to some
9-
// pretty specific internals of runScript
10-
const makeSpawnArgs = require('@npmcli/run-script/lib/make-spawn-args.js')
7+
const isCmdRe = /(?:^|\\)cmd(?:\.exe)?$/i
118

129
t.test('should run restart script from package.json', async t => {
1310
const { npm } = await loadMockNpm(t, {
@@ -22,15 +19,14 @@ t.test('should run restart script from package.json', async t => {
2219
},
2320
config: {
2421
loglevel: 'silent',
22+
scriptShell: process.platform === 'win32' ? process.env.COMSPEC : 'sh',
2523
},
2624
})
27-
const [scriptShell, scriptArgs] = makeSpawnArgs({
28-
path: npm.prefix,
29-
cmd: 'node ./test-restart.js',
30-
})
31-
let scriptContent = scriptArgs.pop()
32-
scriptContent += ' foo'
33-
scriptArgs.push(scriptContent)
25+
26+
const scriptShell = npm.config.get('scriptShell')
27+
const scriptArgs = isCmdRe.test(scriptShell)
28+
? ['/d', '/s', '/c', 'node ./test-restart.js foo']
29+
: ['-c', 'node ./test-restart.js foo']
3430
const script = spawk.spawn(scriptShell, scriptArgs)
3531
await npm.exec('restart', ['foo'])
3632
t.ok(script.called, 'script ran')

test/lib/commands/start.js

+7-9
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ const { load: loadMockNpm } = require('../../fixtures/mock-npm')
44

55
const spawk = tspawk(t)
66

7-
// TODO this ... smells. npm "script-shell" config mentions defaults but those
8-
// are handled by run-script, not npm. So for now we have to tie tests to some
9-
// pretty specific internals of runScript
10-
const makeSpawnArgs = require('@npmcli/run-script/lib/make-spawn-args.js')
7+
const isCmdRe = /(?:^|\\)cmd(?:\.exe)?$/i
118

129
t.test('should run start script from package.json', async t => {
1310
const { npm } = await loadMockNpm(t, {
@@ -22,13 +19,14 @@ t.test('should run start script from package.json', async t => {
2219
},
2320
config: {
2421
loglevel: 'silent',
22+
scriptShell: process.platform === 'win32' ? process.env.COMSPEC : 'sh',
2523
},
2624
})
27-
const [scriptShell, scriptArgs] = makeSpawnArgs({ path: npm.prefix, cmd: 'node ./test-start.js' })
28-
// we're calling the script with 'foo' as an argument, so add that to the script
29-
let scriptContent = scriptArgs.pop()
30-
scriptContent += ' foo'
31-
scriptArgs.push(scriptContent)
25+
26+
const scriptShell = npm.config.get('scriptShell')
27+
const scriptArgs = isCmdRe.test(scriptShell)
28+
? ['/d', '/s', '/c', 'node ./test-start.js foo']
29+
: ['-c', 'node ./test-start.js foo']
3230
const script = spawk.spawn(scriptShell, scriptArgs)
3331
await npm.exec('start', ['foo'])
3432
t.ok(script.called, 'script ran')

test/lib/commands/stop.js

+7-8
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ const { load: loadMockNpm } = require('../../fixtures/mock-npm')
44

55
const spawk = tspawk(t)
66

7-
// TODO this ... smells. npm "script-shell" config mentions defaults but those
8-
// are handled by run-script, not npm. So for now we have to tie tests to some
9-
// pretty specific internals of runScript
10-
const makeSpawnArgs = require('@npmcli/run-script/lib/make-spawn-args.js')
7+
const isCmdRe = /(?:^|\\)cmd(?:\.exe)?$/i
118

129
t.test('should run stop script from package.json', async t => {
1310
const { npm } = await loadMockNpm(t, {
@@ -22,12 +19,14 @@ t.test('should run stop script from package.json', async t => {
2219
},
2320
config: {
2421
loglevel: 'silent',
22+
scriptShell: process.platform === 'win32' ? process.env.COMSPEC : 'sh',
2523
},
2624
})
27-
const [scriptShell, scriptArgs] = makeSpawnArgs({ path: npm.prefix, cmd: 'node ./test-stop.js' })
28-
let scriptContent = scriptArgs.pop()
29-
scriptContent += ' foo'
30-
scriptArgs.push(scriptContent)
25+
26+
const scriptShell = npm.config.get('scriptShell')
27+
const scriptArgs = isCmdRe.test(scriptShell)
28+
? ['/d', '/s', '/c', 'node ./test-stop.js foo']
29+
: ['-c', 'node ./test-stop.js foo']
3130
const script = spawk.spawn(scriptShell, scriptArgs)
3231
await npm.exec('stop', ['foo'])
3332
t.ok(script.called, 'script ran')

test/lib/commands/test.js

+7-8
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ const { load: loadMockNpm } = require('../../fixtures/mock-npm')
44

55
const spawk = tspawk(t)
66

7-
// TODO this ... smells. npm "script-shell" config mentions defaults but those
8-
// are handled by run-script, not npm. So for now we have to tie tests to some
9-
// pretty specific internals of runScript
10-
const makeSpawnArgs = require('@npmcli/run-script/lib/make-spawn-args.js')
7+
const isCmdRe = /(?:^|\\)cmd(?:\.exe)?$/i
118

129
t.test('should run test script from package.json', async t => {
1310
const { npm } = await loadMockNpm(t, {
@@ -22,12 +19,14 @@ t.test('should run test script from package.json', async t => {
2219
},
2320
config: {
2421
loglevel: 'silent',
22+
scriptShell: process.platform === 'win32' ? process.env.COMSPEC : 'sh',
2523
},
2624
})
27-
const [scriptShell, scriptArgs] = makeSpawnArgs({ path: npm.prefix, cmd: 'node ./test-test.js' })
28-
let scriptContent = scriptArgs.pop()
29-
scriptContent += ' foo'
30-
scriptArgs.push(scriptContent)
25+
26+
const scriptShell = npm.config.get('scriptShell')
27+
const scriptArgs = isCmdRe.test(scriptShell)
28+
? ['/d', '/s', '/c', 'node ./test-test.js foo']
29+
: ['-c', 'node ./test-test.js foo']
3130
const script = spawk.spawn(scriptShell, scriptArgs)
3231
await npm.exec('test', ['foo'])
3332
t.ok(script.called, 'script ran')

test/lib/utils/open-url-prompt.js

+9-4
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,13 @@ const npm = {
2121
let openerUrl = null
2222
let openerOpts = null
2323
let openerResult = null
24-
const opener = (url, opts, cb) => {
24+
25+
const open = async (url, options) => {
2526
openerUrl = url
26-
openerOpts = opts
27-
return cb(openerResult)
27+
openerOpts = options
28+
if (openerResult) {
29+
throw openerResult
30+
}
2831
}
2932

3033
let questionShouldResolve = true
@@ -47,7 +50,9 @@ const readline = {
4750
}
4851

4952
const openUrlPrompt = t.mock('../../../lib/utils/open-url-prompt.js', {
50-
opener,
53+
'@npmcli/promise-spawn': {
54+
open,
55+
},
5156
readline,
5257
})
5358

test/lib/utils/open-url.js

+9-4
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,19 @@ const npm = {
1919
let openerUrl = null
2020
let openerOpts = null
2121
let openerResult = null
22-
const opener = (url, opts, cb) => {
22+
23+
const open = async (url, options) => {
2324
openerUrl = url
24-
openerOpts = opts
25-
return cb(openerResult)
25+
openerOpts = options
26+
if (openerResult) {
27+
throw openerResult
28+
}
2629
}
2730

2831
const openUrl = t.mock('../../../lib/utils/open-url.js', {
29-
opener,
32+
'@npmcli/promise-spawn': {
33+
open,
34+
},
3035
})
3136

3237
t.test('opens a url', async t => {

0 commit comments

Comments
 (0)