Skip to content

Commit

Permalink
fix: run input.start around help and openining urls
Browse files Browse the repository at this point in the history
This also refactors open url and open url prompt to
the same file.
  • Loading branch information
lukekarrys committed Apr 30, 2024
1 parent 3ec86a0 commit f66808b
Show file tree
Hide file tree
Showing 13 changed files with 344 additions and 359 deletions.
3 changes: 1 addition & 2 deletions lib/commands/fund.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ const { output } = require('proc-log')
const npa = require('npm-package-arg')
const { depth } = require('treeverse')
const { readTree: getFundingInfo, normalizeFunding, isValidFunding } = require('libnpmfund')

const openUrl = require('../utils/open-url.js')
const { openUrl } = require('../utils/open-url.js')
const ArboristWorkspaceCmd = require('../arborist-cmd.js')

const getPrintableName = ({ name, version }) => {
Expand Down
10 changes: 6 additions & 4 deletions lib/commands/help.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
const spawn = require('@npmcli/promise-spawn')
const path = require('path')
const openUrl = require('../utils/open-url.js')
const { openUrl } = require('../utils/open-url.js')
const { glob } = require('glob')
const { output } = require('proc-log')
const { output, input } = require('proc-log')
const localeCompare = require('@isaacs/string-locale-compare')('en')
const { deref } = require('../utils/cmd-list.js')
const BaseCommand = require('../base-cmd.js')
Expand Down Expand Up @@ -95,13 +95,15 @@ class Help extends BaseCommand {
args = ['emacsclient', ['-e', `(woman-find-file '${man}')`]]
}

return spawn(...args, { stdio: 'inherit' }).catch(err => {
try {
await input.start(() => spawn(...args, { stdio: 'inherit' }))
} catch (err) {
if (err.code) {
throw new Error(`help process exited with code: ${err.code}`)
} else {
throw err
}
})
}
}

// Returns the path to the html version of the man page
Expand Down
2 changes: 1 addition & 1 deletion lib/package-url-cmd.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const pacote = require('pacote')
const openUrl = require('./utils/open-url.js')
const { openUrl } = require('./utils/open-url.js')
const { log } = require('proc-log')
const BaseCommand = require('./base-cmd.js')

Expand Down
2 changes: 1 addition & 1 deletion lib/utils/auth.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const profile = require('npm-profile')
const { log } = require('proc-log')
const openUrlPrompt = require('../utils/open-url-prompt.js')
const { openUrlPrompt } = require('../utils/open-url.js')
const read = require('../utils/read-user-info.js')
const otplease = require('../utils/otplease.js')

Expand Down
66 changes: 0 additions & 66 deletions lib/utils/open-url-prompt.js

This file was deleted.

109 changes: 79 additions & 30 deletions lib/utils/open-url.js
Original file line number Diff line number Diff line change
@@ -1,51 +1,100 @@
const promiseSpawn = require('@npmcli/promise-spawn')
const { output } = require('proc-log')

const { output, input } = require('proc-log')
const { URL } = require('url')
const readline = require('readline')

const assertValidUrl = (url) => {
try {
if (!/^https?:$/.test(new URL(url).protocol)) {
throw new Error()
}
} catch {
throw new Error('Invalid URL: ' + url)
}
}

const outputMsg = (json, title, url) => {
const msg = json ? JSON.stringify({ title, url }) : `${title}:\n${url}\n`
output.standard(msg)
}

// attempt to open URL in web-browser, print address otherwise:
const open = async (npm, url, errMsg, isFile) => {
const openUrl = async (npm, url, title, isFile) => {
url = encodeURI(url)
const browser = npm.config.get('browser')

function printAlternateMsg () {
const json = npm.config.get('json')
const alternateMsg = json
? JSON.stringify({
title: errMsg,
url,
}, null, 2)
: `${errMsg}:\n ${url}\n`

output.standard(alternateMsg)
}
const json = npm.config.get('json')

if (browser === false) {
printAlternateMsg()
outputMsg(json, title, url)
return
}

// We pass this in as true from the help command so we know we don't have to
// check the protocol
if (!isFile) {
try {
if (!/^https?:$/.test(new URL(url).protocol)) {
throw new Error()
}
} catch {
throw new Error('Invalid URL: ' + url)
assertValidUrl(url)
}

try {
await input.start(() => promiseSpawn.open(url, {
command: browser === true ? null : browser,
}))
} catch (err) {
if (err.code !== 127) {
throw err
}
outputMsg(json, title, url)
}
}

// Prompt to open URL in browser if possible
const openUrlPrompt = async (npm, url, title, prompt, emitter) => {
const browser = npm.config.get('browser')
const json = npm.config.get('json')
const isInteractive = process.stdin.isTTY === true && process.stdout.isTTY === true

assertValidUrl(url)
outputMsg(json, title, url)

if (browser === false || !isInteractive) {
return
}

const command = browser === true ? null : browser
await promiseSpawn.open(url, { command })
.catch((err) => {
if (err.code !== 127) {
throw err
}
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
})

printAlternateMsg()
const tryOpen = await input.read(() => new Promise(resolve => {
rl.on('SIGINT', () => {
rl.close()
resolve('SIGINT')
})

rl.question(prompt, () => {
resolve(true)
})

if (emitter && emitter.addListener) {
emitter.addListener('abort', () => {
rl.close()
resolve(false)
})
}
}))

if (tryOpen === 'SIGINT') {
throw new Error('canceled')
}

if (!tryOpen) {
return
}

await openUrl(npm, url, 'Browser unavailable. Please open the URL manually')
}

module.exports = open
module.exports = {
openUrl,
openUrlPrompt,
}
2 changes: 1 addition & 1 deletion lib/utils/otplease.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ async function otplease (npm, opts, fn) {

if (isWebOTP(err)) {
const webAuth = require('./web-auth')
const openUrlPrompt = require('./open-url-prompt')
const { openUrlPrompt } = require('./open-url')

const openerPromise = (url, emitter) =>
openUrlPrompt(
Expand Down
2 changes: 1 addition & 1 deletion test/lib/commands/bugs.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ t.test('open bugs urls & emails', async t => {
const { npm } = await loadMockNpm(t, {
mocks: {
pacote,
'{LIB}/utils/open-url.js': openUrl,
'{LIB}/utils/open-url.js': { openUrl },
},
})

Expand Down
2 changes: 1 addition & 1 deletion test/lib/commands/docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ const setup = async (t, { prefixDir = fixtures.pkg, config } = {}) => {
const res = await mockNpm(t, {
prefixDir,
mocks: {
'{LIB}/utils/open-url.js': openUrl,
'{LIB}/utils/open-url.js': { openUrl },
},
config,
})
Expand Down
4 changes: 2 additions & 2 deletions test/lib/commands/repo.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,10 @@ const loadMockNpm = async (t, prefixDir, config = {}) => {
const mock = await mockNpm(t, {
command: 'repo',
mocks: {
'{LIB}/utils/open-url.js': async (_, url) => {
'{LIB}/utils/open-url.js': { openUrl: async (_, url) => {
opened[url] = opened[url] || 0
opened[url]++
},
} },
},
config,
prefixDir,
Expand Down
Loading

0 comments on commit f66808b

Please sign in to comment.