diff --git a/DEPENDENCIES.md b/DEPENDENCIES.md index 170be45ba13d9..4fc45a8c584ea 100644 --- a/DEPENDENCIES.md +++ b/DEPENDENCIES.md @@ -228,6 +228,7 @@ graph LR; npmcli-run-script-->npmcli-node-gyp["@npmcli/node-gyp"]; npmcli-run-script-->npmcli-package-json["@npmcli/package-json"]; npmcli-run-script-->npmcli-promise-spawn["@npmcli/promise-spawn"]; + npmcli-run-script-->proc-log; npmcli-smoke-tests-->npmcli-eslint-config["@npmcli/eslint-config"]; npmcli-smoke-tests-->npmcli-mock-registry["@npmcli/mock-registry"]; npmcli-smoke-tests-->npmcli-promise-spawn["@npmcli/promise-spawn"]; @@ -700,6 +701,7 @@ graph LR; npmcli-run-script-->npmcli-node-gyp["@npmcli/node-gyp"]; npmcli-run-script-->npmcli-package-json["@npmcli/package-json"]; npmcli-run-script-->npmcli-promise-spawn["@npmcli/promise-spawn"]; + npmcli-run-script-->proc-log; npmcli-run-script-->which; npmcli-smoke-tests-->npmcli-eslint-config["@npmcli/eslint-config"]; npmcli-smoke-tests-->npmcli-mock-registry["@npmcli/mock-registry"]; diff --git a/lib/arborist-cmd.js b/lib/arborist-cmd.js index 2e300660ea468..d8cb25baf487e 100644 --- a/lib/arborist-cmd.js +++ b/lib/arborist-cmd.js @@ -1,4 +1,4 @@ -const log = require('proc-log') +const { log } = require('proc-log') // This is the base for all commands whose execWorkspaces just gets // a list of workspace names and passes it on to new Arborist() to diff --git a/lib/base-command.js b/lib/base-command.js index d7019001e43aa..a5fdadb60870e 100644 --- a/lib/base-command.js +++ b/lib/base-command.js @@ -4,7 +4,7 @@ const { relative } = require('path') const { definitions } = require('@npmcli/config/lib/definitions') const { aliases: cmdAliases } = require('./utils/cmd-list') -const log = require('proc-log') +const { log, output } = require('proc-log') class BaseCommand { static workspaces = false @@ -119,7 +119,7 @@ class BaseCommand { const { config } = this.npm if (config.get('usage')) { - return this.npm.output(this.usage) + return output.standard(this.usage) } const hasWsConfig = config.get('workspaces') || config.get('workspace').length diff --git a/lib/cli-entry.js b/lib/cli-entry.js index dd8e18add7ebc..9a5994aec19a3 100644 --- a/lib/cli-entry.js +++ b/lib/cli-entry.js @@ -18,7 +18,7 @@ module.exports = async (process, validateEngines) => { exitHandler.setNpm(npm) // only log node and npm paths in argv initially since argv can contain sensitive info. a cleaned version will be logged later - const log = require('proc-log') + const { log, output } = require('proc-log') log.verbose('cli', process.argv.slice(0, 2).join(' ')) log.info('using', 'npm@%s', npm.version) log.info('using', 'node@%s', process.version) @@ -41,7 +41,7 @@ module.exports = async (process, validateEngines) => { // npm -v if (npm.config.get('version', 'cli')) { - npm.output(npm.version) + output.standard(npm.version) return exitHandler() } @@ -53,7 +53,7 @@ module.exports = async (process, validateEngines) => { cmd = npm.argv.shift() if (!cmd) { - npm.output(npm.usage) + output.standard(npm.usage) process.exitCode = 1 return exitHandler() } @@ -64,8 +64,8 @@ module.exports = async (process, validateEngines) => { if (err.code === 'EUNKNOWNCOMMAND') { const didYouMean = require('./utils/did-you-mean.js') const suggestions = await didYouMean(npm.localPrefix, cmd) - npm.output(`Unknown command: "${cmd}"${suggestions}\n`) - npm.output('To see a list of supported npm commands, run:\n npm help') + output.standard(`Unknown command: "${cmd}"${suggestions}\n`) + output.standard('To see a list of supported npm commands, run:\n npm help') process.exitCode = 1 return exitHandler() } diff --git a/lib/commands/access.js b/lib/commands/access.js index 4594241b402b7..20565e274398e 100644 --- a/lib/commands/access.js +++ b/lib/commands/access.js @@ -1,5 +1,6 @@ const libnpmaccess = require('libnpmaccess') const npa = require('npm-package-arg') +const { output } = require('proc-log') const pkgJson = require('@npmcli/package-json') const localeCompare = require('@isaacs/string-locale-compare')('en') @@ -197,7 +198,7 @@ class Access extends BaseCommand { } #output (items, limiter) { - const output = {} + const outputs = {} const lookup = { __proto__: null, read: 'read-only', @@ -205,14 +206,14 @@ class Access extends BaseCommand { } for (const item in items) { const val = items[item] - output[item] = lookup[val] || val + outputs[item] = lookup[val] || val } if (this.npm.config.get('json')) { - this.npm.output(JSON.stringify(output, null, 2)) + output.standard(JSON.stringify(outputs, null, 2)) } else { - for (const item of Object.keys(output).sort(localeCompare)) { + for (const item of Object.keys(outputs).sort(localeCompare)) { if (!limiter || limiter === item) { - this.npm.output(`${item}: ${output[item]}`) + output.standard(`${item}: ${outputs[item]}`) } } } diff --git a/lib/commands/adduser.js b/lib/commands/adduser.js index 8dfa67555ec34..842819f2bf44b 100644 --- a/lib/commands/adduser.js +++ b/lib/commands/adduser.js @@ -1,4 +1,4 @@ -const log = require('proc-log') +const { log, output } = require('proc-log') const { redactLog: replaceInfo } = require('@npmcli/redact') const auth = require('../utils/auth.js') @@ -44,7 +44,7 @@ class AddUser extends BaseCommand { await this.npm.config.save('user') - this.npm.output(message) + output.standard(message) } } module.exports = AddUser diff --git a/lib/commands/audit.js b/lib/commands/audit.js index 9eece15c211f0..0ec4eec44a77e 100644 --- a/lib/commands/audit.js +++ b/lib/commands/audit.js @@ -8,7 +8,7 @@ const tufClient = require('@sigstore/tuf') const ArboristWorkspaceCmd = require('../arborist-cmd.js') const auditError = require('../utils/audit-error.js') -const log = require('proc-log') +const { log, output } = require('proc-log') const reifyFinish = require('../utils/reify-finish.js') const sortAlphabetically = (a, b) => localeCompare(a.name, b.name) @@ -65,7 +65,7 @@ class VerifySignatures { } if (this.npm.config.get('json')) { - this.npm.output(JSON.stringify({ + output.standard(JSON.stringify({ invalid, missing, }, null, 2)) @@ -77,91 +77,91 @@ class VerifySignatures { const auditedPlural = this.auditedWithKeysCount > 1 ? 's' : '' const timing = `audited ${this.auditedWithKeysCount} package${auditedPlural} in ` + `${Math.floor(Number(elapsed) / 1e9)}s` - this.npm.output(timing) - this.npm.output('') + output.standard(timing) + output.standard('') const verifiedBold = this.npm.chalk.bold('verified') if (this.verifiedSignatureCount) { if (this.verifiedSignatureCount === 1) { /* eslint-disable-next-line max-len */ - this.npm.output(`${this.verifiedSignatureCount} package has a ${verifiedBold} registry signature`) + output.standard(`${this.verifiedSignatureCount} package has a ${verifiedBold} registry signature`) } else { /* eslint-disable-next-line max-len */ - this.npm.output(`${this.verifiedSignatureCount} packages have ${verifiedBold} registry signatures`) + output.standard(`${this.verifiedSignatureCount} packages have ${verifiedBold} registry signatures`) } - this.npm.output('') + output.standard('') } if (this.verifiedAttestationCount) { if (this.verifiedAttestationCount === 1) { /* eslint-disable-next-line max-len */ - this.npm.output(`${this.verifiedAttestationCount} package has a ${verifiedBold} attestation`) + output.standard(`${this.verifiedAttestationCount} package has a ${verifiedBold} attestation`) } else { /* eslint-disable-next-line max-len */ - this.npm.output(`${this.verifiedAttestationCount} packages have ${verifiedBold} attestations`) + output.standard(`${this.verifiedAttestationCount} packages have ${verifiedBold} attestations`) } - this.npm.output('') + output.standard('') } if (missing.length) { const missingClr = this.npm.chalk.bold(this.npm.chalk.red('missing')) if (missing.length === 1) { /* eslint-disable-next-line max-len */ - this.npm.output(`1 package has a ${missingClr} registry signature but the registry is providing signing keys:`) + output.standard(`1 package has a ${missingClr} registry signature but the registry is providing signing keys:`) } else { /* eslint-disable-next-line max-len */ - this.npm.output(`${missing.length} packages have ${missingClr} registry signatures but the registry is providing signing keys:`) + output.standard(`${missing.length} packages have ${missingClr} registry signatures but the registry is providing signing keys:`) } - this.npm.output('') + output.standard('') missing.map(m => - this.npm.output(`${this.npm.chalk.red(`${m.name}@${m.version}`)} (${m.registry})`) + output.standard(`${this.npm.chalk.red(`${m.name}@${m.version}`)} (${m.registry})`) ) } if (invalid.length) { if (missing.length) { - this.npm.output('') + output.standard('') } const invalidClr = this.npm.chalk.bold(this.npm.chalk.red('invalid')) // We can have either invalid signatures or invalid provenance const invalidSignatures = this.invalid.filter(i => i.code === 'EINTEGRITYSIGNATURE') if (invalidSignatures.length) { if (invalidSignatures.length === 1) { - this.npm.output(`1 package has an ${invalidClr} registry signature:`) + output.standard(`1 package has an ${invalidClr} registry signature:`) } else { /* eslint-disable-next-line max-len */ - this.npm.output(`${invalidSignatures.length} packages have ${invalidClr} registry signatures:`) + output.standard(`${invalidSignatures.length} packages have ${invalidClr} registry signatures:`) } - this.npm.output('') + output.standard('') invalidSignatures.map(i => - this.npm.output(`${this.npm.chalk.red(`${i.name}@${i.version}`)} (${i.registry})`) + output.standard(`${this.npm.chalk.red(`${i.name}@${i.version}`)} (${i.registry})`) ) - this.npm.output('') + output.standard('') } const invalidAttestations = this.invalid.filter(i => i.code === 'EATTESTATIONVERIFY') if (invalidAttestations.length) { if (invalidAttestations.length === 1) { - this.npm.output(`1 package has an ${invalidClr} attestation:`) + output.standard(`1 package has an ${invalidClr} attestation:`) } else { /* eslint-disable-next-line max-len */ - this.npm.output(`${invalidAttestations.length} packages have ${invalidClr} attestations:`) + output.standard(`${invalidAttestations.length} packages have ${invalidClr} attestations:`) } - this.npm.output('') + output.standard('') invalidAttestations.map(i => - this.npm.output(`${this.npm.chalk.red(`${i.name}@${i.version}`)} (${i.registry})`) + output.standard(`${this.npm.chalk.red(`${i.name}@${i.version}`)} (${i.registry})`) ) - this.npm.output('') + output.standard('') } if (invalid.length === 1) { /* eslint-disable-next-line max-len */ - this.npm.output(`Someone might have tampered with this package since it was published on the registry!`) + output.standard(`Someone might have tampered with this package since it was published on the registry!`) } else { /* eslint-disable-next-line max-len */ - this.npm.output(`Someone might have tampered with these packages since they were published on the registry!`) + output.standard(`Someone might have tampered with these packages since they were published on the registry!`) } - this.npm.output('') + output.standard('') } } @@ -463,7 +463,7 @@ class Audit extends ArboristWorkspaceCmd { chalk: this.npm.chalk, }) process.exitCode = process.exitCode || result.exitCode - this.npm.output(result.report) + output.standard(result.report) } } diff --git a/lib/commands/cache.js b/lib/commands/cache.js index 1566d004ccc22..8e9b33b3d1a49 100644 --- a/lib/commands/cache.js +++ b/lib/commands/cache.js @@ -7,7 +7,7 @@ const BaseCommand = require('../base-command.js') const npa = require('npm-package-arg') const jsonParse = require('json-parse-even-better-errors') const localeCompare = require('@isaacs/string-locale-compare')('en') -const log = require('proc-log') +const { log, output } = require('proc-log') const searchCachePackage = async (path, parsed, cacheKeys) => { /* eslint-disable-next-line max-len */ @@ -135,7 +135,7 @@ class Cache extends BaseCommand { log.warn(`Not Found: ${key}`) break } - this.npm.output(`Deleted: ${key}`) + output.standard(`Deleted: ${key}`) await cacache.rm.entry(cachePath, key) // XXX this could leave other entries without content! await cacache.rm.content(cachePath, entry.integrity) @@ -170,20 +170,20 @@ class Cache extends BaseCommand { ? `~${cache.slice(process.env.HOME.length)}` : cache const stats = await cacache.verify(cache) - this.npm.output(`Cache verified and compressed (${prefix})`) - this.npm.output(`Content verified: ${stats.verifiedContent} (${stats.keptSize} bytes)`) + output.standard(`Cache verified and compressed (${prefix})`) + output.standard(`Content verified: ${stats.verifiedContent} (${stats.keptSize} bytes)`) if (stats.badContentCount) { - this.npm.output(`Corrupted content removed: ${stats.badContentCount}`) + output.standard(`Corrupted content removed: ${stats.badContentCount}`) } if (stats.reclaimedCount) { /* eslint-disable-next-line max-len */ - this.npm.output(`Content garbage-collected: ${stats.reclaimedCount} (${stats.reclaimedSize} bytes)`) + output.standard(`Content garbage-collected: ${stats.reclaimedCount} (${stats.reclaimedSize} bytes)`) } if (stats.missingContent) { - this.npm.output(`Missing content: ${stats.missingContent}`) + output.standard(`Missing content: ${stats.missingContent}`) } - this.npm.output(`Index entries: ${stats.totalEntries}`) - this.npm.output(`Finished in ${stats.runTime.total / 1000}s`) + output.standard(`Index entries: ${stats.totalEntries}`) + output.standard(`Finished in ${stats.runTime.total / 1000}s`) } // npm cache ls [--package ...] @@ -203,10 +203,10 @@ class Cache extends BaseCommand { results.add(key) } } - [...results].sort(localeCompare).forEach(key => this.npm.output(key)) + [...results].sort(localeCompare).forEach(key => output.standard(key)) return } - cacheKeys.sort(localeCompare).forEach(key => this.npm.output(key)) + cacheKeys.sort(localeCompare).forEach(key => output.standard(key)) } } diff --git a/lib/commands/ci.js b/lib/commands/ci.js index 13fd402516032..9977c776ddf57 100644 --- a/lib/commands/ci.js +++ b/lib/commands/ci.js @@ -1,7 +1,7 @@ const reifyFinish = require('../utils/reify-finish.js') const runScript = require('@npmcli/run-script') const fs = require('fs/promises') -const log = require('proc-log') +const { log } = require('proc-log') const validateLockfile = require('../utils/validate-lockfile.js') const ArboristWorkspaceCmd = require('../arborist-cmd.js') @@ -109,7 +109,6 @@ class CI extends ArboristWorkspaceCmd { args: [], scriptShell, stdio: 'inherit', - banner: !this.npm.silent, event, }) } diff --git a/lib/commands/completion.js b/lib/commands/completion.js index 59113c50560bc..677d7fa2ec3fe 100644 --- a/lib/commands/completion.js +++ b/lib/commands/completion.js @@ -32,6 +32,7 @@ const fs = require('fs/promises') const nopt = require('nopt') const { resolve } = require('path') +const { output } = require('proc-log') const Npm = require('../npm.js') const { definitions, shorthands } = require('@npmcli/config/lib/definitions') @@ -185,7 +186,7 @@ class Completion extends BaseCommand { } if (compls.length > 0) { - this.npm.output(compls.join('\n')) + output.standard(compls.join('\n')) } } } diff --git a/lib/commands/config.js b/lib/commands/config.js index ebe5a9990accb..b1273120cf9ee 100644 --- a/lib/commands/config.js +++ b/lib/commands/config.js @@ -6,7 +6,7 @@ const ini = require('ini') const localeCompare = require('@isaacs/string-locale-compare')('en') const pkgJson = require('@npmcli/package-json') const { defaults, definitions } = require('@npmcli/config/lib/definitions') -const log = require('proc-log') +const { log, output } = require('proc-log') // These are the configs that we can nerf-dart. Not all of them currently even // *have* config definitions so we have to explicitly validate them here @@ -185,7 +185,7 @@ class Config extends BaseCommand { const pref = keys.length > 1 ? `${key}=` : '' out.push(pref + this.npm.config.get(key)) } - this.npm.output(out.join('\n')) + output.standard(out.join('\n')) } async del (keys) { @@ -282,7 +282,7 @@ ${defData} this.npm.config.repair(problems) const locations = [] - this.npm.output('The following configuration problems have been repaired:\n') + output.standard('The following configuration problems have been repaired:\n') const summary = problems.map(({ action, from, to, key, where }) => { // coverage disabled for else branch because it is intentionally omitted // istanbul ignore else @@ -295,7 +295,7 @@ ${defData} return `- \`${key}\` deleted from ${where} config` } }).join('\n') - this.npm.output(summary) + output.standard(summary) return await Promise.all(locations.map((location) => this.npm.config.save(location))) } @@ -354,7 +354,7 @@ ${defData} } } - this.npm.output(msg.join('\n').trim()) + output.standard(msg.join('\n').trim()) } async listJson () { @@ -366,7 +366,7 @@ ${defData} publicConf[key] = this.npm.config.get(key) } - this.npm.output(JSON.stringify(publicConf, null, 2)) + output.standard(JSON.stringify(publicConf, null, 2)) } } diff --git a/lib/commands/diff.js b/lib/commands/diff.js index c6b93d025bb52..e188a38505867 100644 --- a/lib/commands/diff.js +++ b/lib/commands/diff.js @@ -4,7 +4,7 @@ const libnpmdiff = require('libnpmdiff') const npa = require('npm-package-arg') const pacote = require('pacote') const pickManifest = require('npm-pick-manifest') -const log = require('proc-log') +const { log, output } = require('proc-log') const pkgJson = require('@npmcli/package-json') const BaseCommand = require('../base-command.js') @@ -64,7 +64,7 @@ class Diff extends BaseCommand { diffFiles: args, where: this.top, }) - return this.npm.output(res) + return output.standard(res) } async execWorkspaces (args) { diff --git a/lib/commands/dist-tag.js b/lib/commands/dist-tag.js index 2b71d9a7a6444..741890fc9cec7 100644 --- a/lib/commands/dist-tag.js +++ b/lib/commands/dist-tag.js @@ -1,7 +1,7 @@ const npa = require('npm-package-arg') const regFetch = require('npm-registry-fetch') const semver = require('semver') -const log = require('proc-log') +const { log, output } = require('proc-log') const otplease = require('../utils/otplease.js') const pkgJson = require('@npmcli/package-json') const BaseCommand = require('../base-command.js') @@ -120,7 +120,7 @@ class DistTag extends BaseCommand { spec, } await otplease(this.npm, reqOpts, o => regFetch(url, o)) - this.npm.output(`+${t}: ${spec.name}@${version}`) + output.standard(`+${t}: ${spec.name}@${version}`) } async remove (spec, tag, opts) { @@ -146,7 +146,7 @@ class DistTag extends BaseCommand { spec, } await otplease(this.npm, reqOpts, o => regFetch(url, o)) - this.npm.output(`-${tag}: ${spec.name}@${version}`) + output.standard(`-${tag}: ${spec.name}@${version}`) } async list (spec, opts) { @@ -167,7 +167,7 @@ class DistTag extends BaseCommand { const tags = await this.fetchTags(spec, opts) const msg = Object.keys(tags).map(k => `${k}: ${tags[k]}`).sort().join('\n') - this.npm.output(msg) + output.standard(msg) return tags } catch (err) { log.error('dist-tag ls', "Couldn't get dist-tag data for", spec) @@ -180,7 +180,7 @@ class DistTag extends BaseCommand { for (const name of this.workspaceNames) { try { - this.npm.output(`${name}:`) + output.standard(`${name}:`) await this.list(npa(name), this.npm.flatOptions) } catch (err) { // set the exitCode directly, but ignore the error diff --git a/lib/commands/doctor.js b/lib/commands/doctor.js index cc127287ae576..e3177f7a45544 100644 --- a/lib/commands/doctor.js +++ b/lib/commands/doctor.js @@ -7,7 +7,7 @@ const pacote = require('pacote') const { resolve } = require('path') const semver = require('semver') const { promisify } = require('util') -const log = require('proc-log') +const { log, output } = require('proc-log') const ping = require('../utils/ping.js') const { defaults } = require('@npmcli/config/lib/definitions') const lstat = promisify(fs.lstat) @@ -374,7 +374,7 @@ class Doctor extends BaseCommand { colWidths: [this.#checkWidth, 6], }) t.push(row) - this.npm.output(t.toString()) + output.standard(t.toString()) } actions (params) { diff --git a/lib/commands/exec.js b/lib/commands/exec.js index d532eca107c6c..f181bbb2ef6fe 100644 --- a/lib/commands/exec.js +++ b/lib/commands/exec.js @@ -65,7 +65,6 @@ class Exec extends BaseCommand { globalDir, chalk, } = this.npm - const output = this.npm.output.bind(this.npm) const scriptShell = this.npm.config.get('script-shell') || undefined const packages = this.npm.config.get('package') const yes = this.npm.config.get('yes') @@ -93,7 +92,6 @@ class Exec extends BaseCommand { globalPath, localBin, locationMsg, - output, packages, path, runPath, diff --git a/lib/commands/explain.js b/lib/commands/explain.js index 403274db68dfa..98ef356bfc1b3 100644 --- a/lib/commands/explain.js +++ b/lib/commands/explain.js @@ -3,6 +3,7 @@ const npa = require('npm-package-arg') const semver = require('semver') const { relative, resolve } = require('path') const validName = require('validate-npm-package-name') +const { output } = require('proc-log') const ArboristWorkspaceCmd = require('../arborist-cmd.js') class Explain extends ArboristWorkspaceCmd { @@ -75,9 +76,9 @@ class Explain extends ArboristWorkspaceCmd { } if (this.npm.flatOptions.json) { - this.npm.output(JSON.stringify(expls, null, 2)) + output.standard(JSON.stringify(expls, null, 2)) } else { - this.npm.output(expls.map(expl => { + output.standard(expls.map(expl => { return explainNode(expl, Infinity, this.npm.chalk) }).join('\n\n')) } diff --git a/lib/commands/explore.js b/lib/commands/explore.js index 23debc2743111..ef4743e62197d 100644 --- a/lib/commands/explore.js +++ b/lib/commands/explore.js @@ -4,7 +4,7 @@ const pkgJson = require('@npmcli/package-json') const runScript = require('@npmcli/run-script') const { join, relative } = require('path') -const log = require('proc-log') +const { log, output } = require('proc-log') const completion = require('../utils/completion/installed-shallow.js') const BaseCommand = require('../base-command.js') @@ -50,13 +50,12 @@ class Explore extends BaseCommand { } if (!args.length) { - this.npm.output(`\nExploring ${path}\nType 'exit' or ^D when finished\n`) + output.standard(`\nExploring ${path}\nType 'exit' or ^D when finished\n`) } return runScript({ ...this.npm.flatOptions, pkg, - banner: false, path, event: '_explore', stdio: 'inherit', diff --git a/lib/commands/fund.js b/lib/commands/fund.js index 2804d36cd5603..aa8c7b17b48b6 100644 --- a/lib/commands/fund.js +++ b/lib/commands/fund.js @@ -1,6 +1,7 @@ const archy = require('archy') const pacote = require('pacote') const semver = require('semver') +const { output } = require('proc-log') const npa = require('npm-package-arg') const { depth } = require('treeverse') const { readTree: getFundingInfo, normalizeFunding, isValidFunding } = require('libnpmfund') @@ -85,9 +86,9 @@ class Fund extends ArboristWorkspaceCmd { }) if (this.npm.config.get('json')) { - this.npm.output(this.printJSON(fundingInfo)) + output.standard(this.printJSON(fundingInfo)) } else { - this.npm.output(this.printHuman(fundingInfo)) + output.standard(this.printHuman(fundingInfo)) } } @@ -212,7 +213,7 @@ class Fund extends ArboristWorkspaceCmd { if (fundingSourceNumber) { ambiguousUrlMsg.unshift(`--which=${fundingSourceNumber} is not a valid index`) } - this.npm.output(ambiguousUrlMsg.join('\n')) + output.standard(ambiguousUrlMsg.join('\n')) } urlMessage (source) { diff --git a/lib/commands/help-search.js b/lib/commands/help-search.js index 273807c7469af..c3719d48f2f5a 100644 --- a/lib/commands/help-search.js +++ b/lib/commands/help-search.js @@ -1,6 +1,7 @@ const { readFile } = require('fs/promises') const path = require('path') const { glob } = require('glob') +const { output } = require('proc-log') const BaseCommand = require('../base-command.js') const globify = pattern => pattern.split('\\').join('/') @@ -24,9 +25,9 @@ class HelpSearch extends BaseCommand { const results = await this.searchFiles(args, data, files) const formatted = this.formatResults(args, results) if (!formatted.trim()) { - this.npm.output(`No matches in help for: ${args.join(' ')}\n`) + output.standard(`No matches in help for: ${args.join(' ')}\n`) } else { - this.npm.output(formatted) + output.standard(formatted) } } @@ -140,7 +141,7 @@ class HelpSearch extends BaseCommand { formatResults (args, results) { const cols = Math.min(process.stdout.columns || Infinity, 80) + 1 - const output = results.map(res => { + const formattedOutput = results.map(res => { const out = [res.cmd] const r = Object.keys(res.hits) .map(k => `${k}:${res.hits[k]}`) @@ -183,10 +184,10 @@ class HelpSearch extends BaseCommand { const finalOut = results.length && !this.npm.config.get('long') ? 'Top hits for ' + (args.map(JSON.stringify).join(' ')) + '\n' + '—'.repeat(cols - 1) + '\n' + - output + '\n' + + formattedOutput + '\n' + '—'.repeat(cols - 1) + '\n' + '(run with -l or --long to see more context)' - : output + : formattedOutput return finalOut.trim() } diff --git a/lib/commands/help.js b/lib/commands/help.js index 39c580f9a6871..1f51713a8d051 100644 --- a/lib/commands/help.js +++ b/lib/commands/help.js @@ -2,6 +2,7 @@ const spawn = require('@npmcli/promise-spawn') const path = require('path') const openUrl = require('../utils/open-url.js') const { glob } = require('glob') +const { output } = require('proc-log') const localeCompare = require('@isaacs/string-locale-compare')('en') const { deref } = require('../utils/cmd-list.js') @@ -50,7 +51,7 @@ class Help extends BaseCommand { const manSearch = /^\d+$/.test(args[0]) ? `man${args.shift()}` : 'man*' if (!args.length) { - return this.npm.output(this.npm.usage) + return output.standard(this.npm.usage) } // npm help foo bar baz: search topics diff --git a/lib/commands/hook.js b/lib/commands/hook.js index b0f52a801f571..5e6b593cccfd6 100644 --- a/lib/commands/hook.js +++ b/lib/commands/hook.js @@ -2,6 +2,7 @@ const hookApi = require('libnpmhook') const otplease = require('../utils/otplease.js') const relativeDate = require('tiny-relative-date') const Table = require('cli-table3') +const { output } = require('proc-log') const BaseCommand = require('../base-command.js') class Hook extends BaseCommand { @@ -40,31 +41,31 @@ class Hook extends BaseCommand { async add (pkg, uri, secret, opts) { const hook = await hookApi.add(pkg, uri, secret, opts) if (opts.json) { - this.npm.output(JSON.stringify(hook, null, 2)) + output.standard(JSON.stringify(hook, null, 2)) } else if (opts.parseable) { - this.npm.output(Object.keys(hook).join('\t')) - this.npm.output(Object.keys(hook).map(k => hook[k]).join('\t')) + output.standard(Object.keys(hook).join('\t')) + output.standard(Object.keys(hook).map(k => hook[k]).join('\t')) } else if (!this.npm.silent) { - this.npm.output(`+ ${this.hookName(hook)} ${opts.unicode ? ' ➜ ' : ' -> '} ${hook.endpoint}`) + output.standard(`+ ${this.hookName(hook)} ${opts.unicode ? ' ➜ ' : ' -> '} ${hook.endpoint}`) } } async ls (pkg, opts) { const hooks = await hookApi.ls({ ...opts, package: pkg }) if (opts.json) { - this.npm.output(JSON.stringify(hooks, null, 2)) + output.standard(JSON.stringify(hooks, null, 2)) } else if (opts.parseable) { - this.npm.output(Object.keys(hooks[0]).join('\t')) + output.standard(Object.keys(hooks[0]).join('\t')) hooks.forEach(hook => { - this.npm.output(Object.keys(hook).map(k => hook[k]).join('\t')) + output.standard(Object.keys(hook).map(k => hook[k]).join('\t')) }) } else if (!hooks.length) { - this.npm.output("You don't have any hooks configured yet.") + output.standard("You don't have any hooks configured yet.") } else if (!this.npm.silent) { if (hooks.length === 1) { - this.npm.output('You have one hook configured.') + output.standard('You have one hook configured.') } else { - this.npm.output(`You have ${hooks.length} hooks configured.`) + output.standard(`You have ${hooks.length} hooks configured.`) } const table = new Table({ head: ['id', 'target', 'endpoint'] }) @@ -86,31 +87,31 @@ class Hook extends BaseCommand { table.push([{ colSpan: 2, content: 'never triggered' }]) } }) - this.npm.output(table.toString()) + output.standard(table.toString()) } } async rm (id, opts) { const hook = await hookApi.rm(id, opts) if (opts.json) { - this.npm.output(JSON.stringify(hook, null, 2)) + output.standard(JSON.stringify(hook, null, 2)) } else if (opts.parseable) { - this.npm.output(Object.keys(hook).join('\t')) - this.npm.output(Object.keys(hook).map(k => hook[k]).join('\t')) + output.standard(Object.keys(hook).join('\t')) + output.standard(Object.keys(hook).map(k => hook[k]).join('\t')) } else if (!this.npm.silent) { - this.npm.output(`- ${this.hookName(hook)} ${opts.unicode ? ' ✘ ' : ' X '} ${hook.endpoint}`) + output.standard(`- ${this.hookName(hook)} ${opts.unicode ? ' ✘ ' : ' X '} ${hook.endpoint}`) } } async update (id, uri, secret, opts) { const hook = await hookApi.update(id, uri, secret, opts) if (opts.json) { - this.npm.output(JSON.stringify(hook, null, 2)) + output.standard(JSON.stringify(hook, null, 2)) } else if (opts.parseable) { - this.npm.output(Object.keys(hook).join('\t')) - this.npm.output(Object.keys(hook).map(k => hook[k]).join('\t')) + output.standard(Object.keys(hook).join('\t')) + output.standard(Object.keys(hook).map(k => hook[k]).join('\t')) } else if (!this.npm.silent) { - this.npm.output(`+ ${this.hookName(hook)} ${opts.unicode ? ' ➜ ' : ' -> '} ${hook.endpoint}`) + output.standard(`+ ${this.hookName(hook)} ${opts.unicode ? ' ➜ ' : ' -> '} ${hook.endpoint}`) } } diff --git a/lib/commands/init.js b/lib/commands/init.js index ad3aba4d0c68c..d45dbaa1fa0d7 100644 --- a/lib/commands/init.js +++ b/lib/commands/init.js @@ -6,7 +6,7 @@ const npa = require('npm-package-arg') const libexec = require('libnpmexec') const mapWorkspaces = require('@npmcli/map-workspaces') const PackageJson = require('@npmcli/package-json') -const log = require('proc-log') +const { log, output } = require('proc-log') const updateWorkspaces = require('../workspaces/update-workspaces.js') const posixPath = p => p.split('\\').join('/') @@ -130,7 +130,6 @@ class Init extends BaseCommand { globalBin, chalk, } = this.npm - const output = this.npm.output.bind(this.npm) const runPath = path const scriptShell = this.npm.config.get('script-shell') || undefined const yes = this.npm.config.get('yes') @@ -154,7 +153,7 @@ class Init extends BaseCommand { const initFile = this.npm.config.get('init-module') if (!this.npm.config.get('yes') && !this.npm.config.get('force')) { - this.npm.output([ + output.standard([ 'This utility will walk you through creating a package.json file.', 'It only covers the most common items, and tries to guess sensible defaults.', '', diff --git a/lib/commands/install.js b/lib/commands/install.js index eb19c9cc76eb4..13883499c13f0 100644 --- a/lib/commands/install.js +++ b/lib/commands/install.js @@ -3,7 +3,7 @@ const fs = require('fs') const util = require('util') const readdir = util.promisify(fs.readdir) const reifyFinish = require('../utils/reify-finish.js') -const log = require('proc-log') +const { log } = require('proc-log') const { resolve, join } = require('path') const runScript = require('@npmcli/run-script') const pacote = require('pacote') @@ -168,7 +168,6 @@ class Install extends ArboristWorkspaceCmd { args: [], scriptShell, stdio: 'inherit', - banner: !this.npm.silent, event, }) } diff --git a/lib/commands/login.js b/lib/commands/login.js index 97a90d09ec331..d38aec51289cc 100644 --- a/lib/commands/login.js +++ b/lib/commands/login.js @@ -1,4 +1,4 @@ -const log = require('proc-log') +const { log, output } = require('proc-log') const { redactLog: replaceInfo } = require('@npmcli/redact') const auth = require('../utils/auth.js') @@ -44,7 +44,7 @@ class Login extends BaseCommand { await this.npm.config.save('user') - this.npm.output(message) + output.standard(message) } } module.exports = Login diff --git a/lib/commands/logout.js b/lib/commands/logout.js index 60921ee3ee9f4..338081cccd457 100644 --- a/lib/commands/logout.js +++ b/lib/commands/logout.js @@ -1,6 +1,6 @@ const npmFetch = require('npm-registry-fetch') const { getAuth } = npmFetch -const log = require('proc-log') +const { log } = require('proc-log') const BaseCommand = require('../base-command.js') class Logout extends BaseCommand { diff --git a/lib/commands/ls.js b/lib/commands/ls.js index aef3be2828a5a..ff954dec49cc7 100644 --- a/lib/commands/ls.js +++ b/lib/commands/ls.js @@ -4,6 +4,7 @@ const relativePrefix = `.${sep}` const archy = require('archy') const { breadth } = require('treeverse') const npa = require('npm-package-arg') +const { output } = require('proc-log') const _depth = Symbol('depth') const _dedupe = Symbol('dedupe') @@ -176,7 +177,7 @@ class LS extends ArboristWorkspaceCmd { const [rootError] = tree.errors.filter(e => e.code === 'EJSONPARSE' && e.path === resolve(path, 'package.json')) - this.npm.outputBuffer( + output.buffer( json ? jsonOutput({ path, problems, result, rootError, seenItems }) : parseable ? parseableOutput({ seenNodes, global, long }) : humanOutput({ chalk, result, seenItems, unicode }) diff --git a/lib/commands/org.js b/lib/commands/org.js index 1f32d41ff7306..8881ded70f638 100644 --- a/lib/commands/org.js +++ b/lib/commands/org.js @@ -2,6 +2,7 @@ const liborg = require('libnpmorg') const otplease = require('../utils/otplease.js') const Table = require('cli-table3') const BaseCommand = require('../base-command.js') +const { output } = require('proc-log') class Org extends BaseCommand { static description = 'Manage orgs' @@ -68,14 +69,14 @@ class Org extends BaseCommand { const memDeets = await liborg.set(org, user, role, opts) if (opts.json) { - this.npm.output(JSON.stringify(memDeets, null, 2)) + output.standard(JSON.stringify(memDeets, null, 2)) } else if (opts.parseable) { - this.npm.output(['org', 'orgsize', 'user', 'role'].join('\t')) - this.npm.output( + output.standard(['org', 'orgsize', 'user', 'role'].join('\t')) + output.standard( [memDeets.org.name, memDeets.org.size, memDeets.user, memDeets.role].join('\t') ) } else if (!this.npm.silent) { - this.npm.output( + output.standard( `Added ${memDeets.user} as ${memDeets.role} to ${memDeets.org.name}. You now have ${ memDeets.org.size } member${memDeets.org.size === 1 ? '' : 's'} in this org.` @@ -100,7 +101,7 @@ class Org extends BaseCommand { org = org.replace(/^[~@]?/, '') const userCount = Object.keys(roster).length if (opts.json) { - this.npm.output( + output.standard( JSON.stringify({ user, org, @@ -109,10 +110,10 @@ class Org extends BaseCommand { }) ) } else if (opts.parseable) { - this.npm.output(['user', 'org', 'userCount', 'deleted'].join('\t')) - this.npm.output([user, org, userCount, true].join('\t')) + output.standard(['user', 'org', 'userCount', 'deleted'].join('\t')) + output.standard([user, org, userCount, true].join('\t')) } else if (!this.npm.silent) { - this.npm.output( + output.standard( `Successfully removed ${user} from ${org}. You now have ${userCount} member${ userCount === 1 ? '' : 's' } in this org.` @@ -135,11 +136,11 @@ class Org extends BaseCommand { roster = newRoster } if (opts.json) { - this.npm.output(JSON.stringify(roster, null, 2)) + output.standard(JSON.stringify(roster, null, 2)) } else if (opts.parseable) { - this.npm.output(['user', 'role'].join('\t')) + output.standard(['user', 'role'].join('\t')) Object.keys(roster).forEach(u => { - this.npm.output([u, roster[u]].join('\t')) + output.standard([u, roster[u]].join('\t')) }) } else if (!this.npm.silent) { const table = new Table({ head: ['user', 'role'] }) @@ -148,7 +149,7 @@ class Org extends BaseCommand { .forEach(u => { table.push([u, roster[u]]) }) - this.npm.output(table.toString()) + output.standard(table.toString()) } } } diff --git a/lib/commands/outdated.js b/lib/commands/outdated.js index 27b29b314b745..a75afe18e6d93 100644 --- a/lib/commands/outdated.js +++ b/lib/commands/outdated.js @@ -4,6 +4,7 @@ const pacote = require('pacote') const table = require('text-table') const npa = require('npm-package-arg') const pickManifest = require('npm-pick-manifest') +const { output } = require('proc-log') const localeCompare = require('@isaacs/string-locale-compare')('en') const ArboristWorkspaceCmd = require('../arborist-cmd.js') @@ -83,9 +84,9 @@ class Outdated extends ArboristWorkspaceCmd { // display results if (this.npm.config.get('json')) { - this.npm.output(this.makeJSON(outdated)) + output.standard(this.makeJSON(outdated)) } else if (this.npm.config.get('parseable')) { - this.npm.output(this.makeParseable(outdated)) + output.standard(this.makeParseable(outdated)) } else { const outList = outdated.map(x => this.makePretty(x)) const outHead = ['Package', @@ -107,7 +108,7 @@ class Outdated extends ArboristWorkspaceCmd { align: ['l', 'r', 'r', 'r', 'l'], stringLength: s => stripVTControlCharacters(s).length, } - this.npm.output(table(outTable, tableOpts)) + output.standard(table(outTable, tableOpts)) } } diff --git a/lib/commands/owner.js b/lib/commands/owner.js index e20d05dc15fab..cfd40df2151e6 100644 --- a/lib/commands/owner.js +++ b/lib/commands/owner.js @@ -1,7 +1,7 @@ const npa = require('npm-package-arg') const npmFetch = require('npm-registry-fetch') const pacote = require('pacote') -const log = require('proc-log') +const { log, output } = require('proc-log') const otplease = require('../utils/otplease.js') const pkgJson = require('@npmcli/package-json') const BaseCommand = require('../base-command.js') @@ -115,9 +115,9 @@ class Owner extends BaseCommand { const packumentOpts = { ...this.npm.flatOptions, fullMetadata: true, preferOnline: true } const { maintainers } = await pacote.packument(spec, packumentOpts) if (!maintainers || !maintainers.length) { - this.npm.output('no admin found') + output.standard('no admin found') } else { - this.npm.output(maintainers.map(m => `${m.name} <${m.email}>`).join('\n')) + output.standard(maintainers.map(m => `${m.name} <${m.email}>`).join('\n')) } } catch (err) { log.error('owner ls', "Couldn't get owner data", redact(pkg)) @@ -216,9 +216,9 @@ class Owner extends BaseCommand { }) }) if (addOrRm === 'add') { - this.npm.output(`+ ${user} (${spec.name})`) + output.standard(`+ ${user} (${spec.name})`) } else { - this.npm.output(`- ${user} (${spec.name})`) + output.standard(`- ${user} (${spec.name})`) } return res } catch (err) { diff --git a/lib/commands/pack.js b/lib/commands/pack.js index e1eb3f2d57aa4..463329235d417 100644 --- a/lib/commands/pack.js +++ b/lib/commands/pack.js @@ -1,7 +1,7 @@ const pacote = require('pacote') const libpack = require('libnpmpack') const npa = require('npm-package-arg') -const log = require('proc-log') +const { log, output } = require('proc-log') const { getContents, logTar } = require('../utils/tar.js') const BaseCommand = require('../base-command.js') @@ -58,13 +58,13 @@ class Pack extends BaseCommand { } if (json) { - this.npm.output(JSON.stringify(tarballs, null, 2)) + output.standard(JSON.stringify(tarballs, null, 2)) return } for (const tar of tarballs) { logTar(tar, { unicode }) - this.npm.output(tar.filename.replace(/^@/, '').replace(/\//, '-')) + output.standard(tar.filename.replace(/^@/, '').replace(/\//, '-')) } } diff --git a/lib/commands/ping.js b/lib/commands/ping.js index 21225bc4b5a6a..3ae4ed80a22cb 100644 --- a/lib/commands/ping.js +++ b/lib/commands/ping.js @@ -1,5 +1,5 @@ const { redact } = require('@npmcli/redact') -const log = require('proc-log') +const { log, output } = require('proc-log') const pingUtil = require('../utils/ping.js') const BaseCommand = require('../base-command.js') @@ -16,7 +16,7 @@ class Ping extends BaseCommand { const time = Date.now() - start log.notice('PONG', `${time}ms`) if (this.npm.config.get('json')) { - this.npm.output(JSON.stringify({ + output.standard(JSON.stringify({ registry: cleanRegistry, time, details, diff --git a/lib/commands/pkg.js b/lib/commands/pkg.js index 49a66823cca99..26e60fec48786 100644 --- a/lib/commands/pkg.js +++ b/lib/commands/pkg.js @@ -1,3 +1,4 @@ +const { output } = require('proc-log') const PackageJson = require('@npmcli/package-json') const BaseCommand = require('../base-command.js') const Queryable = require('../utils/queryable.js') @@ -62,7 +63,7 @@ class Pkg extends BaseCommand { } // when running in workspaces names, make sure to key by workspace // name the results of each value retrieved in each ws - this.npm.output(JSON.stringify(result, null, 2)) + output.standard(JSON.stringify(result, null, 2)) } async get (args) { @@ -85,7 +86,7 @@ class Pkg extends BaseCommand { // only outputs if not running with workspaces config // execWorkspaces will handle the output otherwise if (!this.workspaces) { - this.npm.output(JSON.stringify(result, null, 2)) + output.standard(JSON.stringify(result, null, 2)) } return result diff --git a/lib/commands/prefix.js b/lib/commands/prefix.js index 264b819fc7692..6c3d6f886f12c 100644 --- a/lib/commands/prefix.js +++ b/lib/commands/prefix.js @@ -1,3 +1,4 @@ +const { output } = require('proc-log') const BaseCommand = require('../base-command.js') class Prefix extends BaseCommand { @@ -7,7 +8,7 @@ class Prefix extends BaseCommand { static usage = ['[-g]'] async exec (args) { - return this.npm.output(this.npm.prefix) + return output.standard(this.npm.prefix) } } module.exports = Prefix diff --git a/lib/commands/profile.js b/lib/commands/profile.js index d43292f2dce09..98a8dcd050ee9 100644 --- a/lib/commands/profile.js +++ b/lib/commands/profile.js @@ -1,6 +1,6 @@ const inspect = require('util').inspect const { URL } = require('url') -const log = require('proc-log') +const { log, output } = require('proc-log') const npmProfile = require('npm-profile') const qrcodeTerminal = require('qrcode-terminal') const Table = require('cli-table3') @@ -110,7 +110,7 @@ class Profile extends BaseCommand { } if (this.npm.config.get('json')) { - this.npm.output(JSON.stringify(info, null, 2)) + output.standard(JSON.stringify(info, null, 2)) return } @@ -142,14 +142,14 @@ class Profile extends BaseCommand { .filter((arg) => arg.trim() !== '') .map((arg) => cleaned[arg]) .join('\t') - this.npm.output(values) + output.standard(values) } else { if (this.npm.config.get('parseable')) { for (const key of Object.keys(info)) { if (key === 'tfa') { - this.npm.output(`${key}\t${cleaned[tfa]}`) + output.standard(`${key}\t${cleaned[tfa]}`) } else { - this.npm.output(`${key}\t${info[key]}`) + output.standard(`${key}\t${info[key]}`) } } } else { @@ -158,7 +158,7 @@ class Profile extends BaseCommand { table.push({ [this.npm.chalk.bold(key)]: cleaned[key] }) } - this.npm.output(table.toString()) + output.standard(table.toString()) } } } @@ -216,13 +216,13 @@ class Profile extends BaseCommand { const result = await otplease(this.npm, conf, c => npmProfile.set(newUser, c)) if (this.npm.config.get('json')) { - this.npm.output(JSON.stringify({ [prop]: result[prop] }, null, 2)) + output.standard(JSON.stringify({ [prop]: result[prop] }, null, 2)) } else if (this.npm.config.get('parseable')) { - this.npm.output(prop + '\t' + result[prop]) + output.standard(prop + '\t' + result[prop]) } else if (result[prop] != null) { - this.npm.output('Set', prop, 'to', result[prop]) + output.standard('Set', prop, 'to', result[prop]) } else { - this.npm.output('Set', prop) + output.standard('Set', prop) } } @@ -320,7 +320,7 @@ class Profile extends BaseCommand { const challenge = await npmProfile.set(info, conf) if (challenge.tfa === null) { - this.npm.output('Two factor authentication mode changed to: ' + mode) + output.standard('Two factor authentication mode changed to: ' + mode) return } @@ -337,7 +337,7 @@ class Profile extends BaseCommand { const secret = otpauth.searchParams.get('secret') const code = await qrcode(challenge.tfa) - this.npm.output( + output.standard( 'Scan into your authenticator app:\n' + code + '\n Or enter code:', secret ) @@ -348,17 +348,17 @@ class Profile extends BaseCommand { const result = await npmProfile.set({ tfa: [interactiveOTP] }, conf) - this.npm.output( + output.standard( '2FA successfully enabled. Below are your recovery codes, ' + 'please print these out.' ) - this.npm.output( + output.standard( 'You will need these to recover access to your account ' + 'if you lose your authentication device.' ) for (const tfaCode of result.tfa) { - this.npm.output('\t' + tfaCode) + output.standard('\t' + tfaCode) } } @@ -367,7 +367,7 @@ class Profile extends BaseCommand { const info = await npmProfile.get(conf) if (!info.tfa || info.tfa.pending) { - this.npm.output('Two factor authentication not enabled.') + output.standard('Two factor authentication not enabled.') return } @@ -383,11 +383,11 @@ class Profile extends BaseCommand { await npmProfile.set({ tfa: { password: password, mode: 'disable' } }, conf) if (this.npm.config.get('json')) { - this.npm.output(JSON.stringify({ tfa: false }, null, 2)) + output.standard(JSON.stringify({ tfa: false }, null, 2)) } else if (this.npm.config.get('parseable')) { - this.npm.output('tfa\tfalse') + output.standard('tfa\tfalse') } else { - this.npm.output('Two factor authentication disabled.') + output.standard('Two factor authentication disabled.') } } } diff --git a/lib/commands/publish.js b/lib/commands/publish.js index 6ff6f4d85c014..8758422f5e9a7 100644 --- a/lib/commands/publish.js +++ b/lib/commands/publish.js @@ -1,4 +1,4 @@ -const log = require('proc-log') +const { log, output } = require('proc-log') const semver = require('semver') const pack = require('libnpmpack') const libpub = require('libnpmpublish').publish @@ -72,7 +72,6 @@ class Publish extends BaseCommand { path: spec.fetchSpec, stdio: 'inherit', pkg: manifest, - banner: !silent, }) } @@ -131,7 +130,6 @@ class Publish extends BaseCommand { path: spec.fetchSpec, stdio: 'inherit', pkg: manifest, - banner: !silent, }) await runScript({ @@ -139,15 +137,14 @@ class Publish extends BaseCommand { path: spec.fetchSpec, stdio: 'inherit', pkg: manifest, - banner: !silent, }) } if (!this.suppressOutput) { if (!silent && json) { - this.npm.output(JSON.stringify(pkgContents, null, 2)) + output.standard(JSON.stringify(pkgContents, null, 2)) } else if (!silent) { - this.npm.output(`+ ${pkgContents.id}`) + output.standard(`+ ${pkgContents.id}`) } } @@ -184,14 +181,14 @@ class Publish extends BaseCommand { // This needs to be in-line w/ the rest of the output that non-JSON // publish generates if (!silent && !json) { - this.npm.output(`+ ${pkgContents.id}`) + output.standard(`+ ${pkgContents.id}`) } else { results[name] = pkgContents } } if (!silent && json) { - this.npm.output(JSON.stringify(results, null, 2)) + output.standard(JSON.stringify(results, null, 2)) } } diff --git a/lib/commands/query.js b/lib/commands/query.js index acf2fe3d9e9d1..319d3ee0cc293 100644 --- a/lib/commands/query.js +++ b/lib/commands/query.js @@ -2,7 +2,7 @@ const { resolve } = require('path') const BaseCommand = require('../base-command.js') -const log = require('proc-log') +const { log, output } = require('proc-log') class QuerySelectorItem { constructor (node) { @@ -83,7 +83,7 @@ class Query extends BaseCommand { this.buildResponse(items) this.checkExpected(this.#response.length) - this.npm.output(this.parsedResponse) + output.standard(this.parsedResponse) } async execWorkspaces (args) { @@ -107,7 +107,7 @@ class Query extends BaseCommand { this.buildResponse(items) } this.checkExpected(this.#response.length) - this.npm.output(this.parsedResponse) + output.standard(this.parsedResponse) } // builds a normalized inventory diff --git a/lib/commands/rebuild.js b/lib/commands/rebuild.js index 8af96f725555c..8858edd1da349 100644 --- a/lib/commands/rebuild.js +++ b/lib/commands/rebuild.js @@ -1,4 +1,5 @@ const { resolve } = require('path') +const { output } = require('proc-log') const npa = require('npm-package-arg') const semver = require('semver') @@ -56,7 +57,7 @@ class Rebuild extends ArboristWorkspaceCmd { await arb.rebuild() } - this.npm.output('rebuilt dependencies successfully') + output.standard('rebuilt dependencies successfully') } isNode (specs, node) { diff --git a/lib/commands/root.js b/lib/commands/root.js index 7749c602456b7..f1f9579d103fd 100644 --- a/lib/commands/root.js +++ b/lib/commands/root.js @@ -1,3 +1,4 @@ +const { output } = require('proc-log') const BaseCommand = require('../base-command.js') class Root extends BaseCommand { static description = 'Display npm root' @@ -5,7 +6,7 @@ class Root extends BaseCommand { static params = ['global'] async exec () { - this.npm.output(this.npm.dir) + output.standard(this.npm.dir) } } module.exports = Root diff --git a/lib/commands/run-script.js b/lib/commands/run-script.js index 58bd51e00c2ad..d86f9b7326e3b 100644 --- a/lib/commands/run-script.js +++ b/lib/commands/run-script.js @@ -1,7 +1,7 @@ const runScript = require('@npmcli/run-script') const { isServerPackage } = runScript const pkgJson = require('@npmcli/package-json') -const log = require('proc-log') +const { log, output } = require('proc-log') const didYouMean = require('../utils/did-you-mean.js') const { isWindowsShell } = require('../utils/is-windows.js') @@ -114,7 +114,6 @@ class RunScript extends BaseCommand { scriptShell, stdio: 'inherit', pkg, - banner: !this.npm.silent, event: ev, args: evArgs, }) @@ -136,13 +135,13 @@ class RunScript extends BaseCommand { } if (this.npm.config.get('json')) { - this.npm.output(JSON.stringify(scripts, null, 2)) + output.standard(JSON.stringify(scripts, null, 2)) return allScripts } if (this.npm.config.get('parseable')) { for (const [script, cmd] of Object.entries(scripts)) { - this.npm.output(`${script}:${cmd}`) + output.standard(`${script}:${cmd}`) } return allScripts @@ -159,7 +158,7 @@ class RunScript extends BaseCommand { const colorize = this.npm.chalk if (cmds.length) { - this.npm.output( + output.standard( `${colorize.reset(colorize.bold('Lifecycle scripts'))} included in ${colorize.green( pkgid )}:` @@ -167,24 +166,24 @@ class RunScript extends BaseCommand { } for (const script of cmds) { - this.npm.output(prefix + script + indent + colorize.dim(scripts[script])) + output.standard(prefix + script + indent + colorize.dim(scripts[script])) } if (!cmds.length && runScripts.length) { - this.npm.output( + output.standard( `${colorize.bold('Scripts')} available in ${colorize.green(pkgid)} via \`${colorize.blue( 'npm run-script' )}\`:` ) } else if (runScripts.length) { - this.npm.output(`\navailable via \`${colorize.blue('npm run-script')}\`:`) + output.standard(`\navailable via \`${colorize.blue('npm run-script')}\`:`) } for (const script of runScripts) { - this.npm.output(prefix + script + indent + colorize.dim(scripts[script])) + output.standard(prefix + script + indent + colorize.dim(scripts[script])) } - this.npm.output('') + output.standard('') return allScripts } @@ -221,7 +220,7 @@ class RunScript extends BaseCommand { const { content: { scripts, name } } = await pkgJson.normalize(workspacePath) res[name] = { ...scripts } } - this.npm.output(JSON.stringify(res, null, 2)) + output.standard(JSON.stringify(res, null, 2)) return } @@ -229,7 +228,7 @@ class RunScript extends BaseCommand { for (const workspacePath of this.workspacePaths) { const { content: { scripts, name } } = await pkgJson.normalize(workspacePath) for (const [script, cmd] of Object.entries(scripts || {})) { - this.npm.output(`${name}:${script}:${cmd}`) + output.standard(`${name}:${script}:${cmd}`) } } return diff --git a/lib/commands/sbom.js b/lib/commands/sbom.js index d43c94826dc9b..4b20bf5ea1f76 100644 --- a/lib/commands/sbom.js +++ b/lib/commands/sbom.js @@ -2,7 +2,7 @@ const localeCompare = require('@isaacs/string-locale-compare')('en') const BaseCommand = require('../base-command.js') -const log = require('proc-log') +const { log, output } = require('proc-log') const { cyclonedxOutput } = require('../utils/sbom-cyclonedx.js') const { spdxOutput } = require('../utils/sbom-spdx.js') @@ -86,7 +86,7 @@ class SBOM extends BaseCommand { items .sort((a, b) => localeCompare(a.location, b.location)) ) - this.npm.output(this.#parsedResponse) + output.standard(this.#parsedResponse) } async execWorkspaces (args) { diff --git a/lib/commands/search.js b/lib/commands/search.js index 7f92e995cf2fd..4a69c77a256e7 100644 --- a/lib/commands/search.js +++ b/lib/commands/search.js @@ -1,7 +1,7 @@ const { Minipass } = require('minipass') const Pipeline = require('minipass-pipeline') const libSearch = require('libnpmsearch') -const log = require('proc-log') +const { log, output } = require('proc-log') const formatSearchStream = require('../utils/format-search-stream.js') @@ -99,12 +99,12 @@ class Search extends BaseCommand { if (!anyOutput) { anyOutput = true } - this.npm.output(chunk.toString('utf8')) + output.standard(chunk.toString('utf8')) }) await p.promise() if (!anyOutput && !this.npm.config.get('json') && !this.npm.config.get('parseable')) { - this.npm.output('No matches found for ' + (args.map(JSON.stringify).join(' '))) + output.standard('No matches found for ' + (args.map(JSON.stringify).join(' '))) } log.silly('search', 'search completed') diff --git a/lib/commands/shrinkwrap.js b/lib/commands/shrinkwrap.js index 7febc2f9b0460..01e1d5fdc1189 100644 --- a/lib/commands/shrinkwrap.js +++ b/lib/commands/shrinkwrap.js @@ -1,6 +1,6 @@ const { resolve, basename } = require('path') const { unlink } = require('fs').promises -const log = require('proc-log') +const { log } = require('proc-log') const BaseCommand = require('../base-command.js') class Shrinkwrap extends BaseCommand { static description = 'Lock down dependency versions for publication' diff --git a/lib/commands/star.js b/lib/commands/star.js index 4a84adf641b8d..39165d8c3d8dc 100644 --- a/lib/commands/star.js +++ b/lib/commands/star.js @@ -1,6 +1,6 @@ const fetch = require('npm-registry-fetch') const npa = require('npm-package-arg') -const log = require('proc-log') +const { log, output } = require('proc-log') const getIdentity = require('../utils/get-identity') const BaseCommand = require('../base-command.js') @@ -62,7 +62,7 @@ class Star extends BaseCommand { body, }) - this.npm.output(show + ' ' + pkg.name) + output.standard(show + ' ' + pkg.name) log.verbose('star', data) return data } diff --git a/lib/commands/stars.js b/lib/commands/stars.js index 73b5dbb2d7f7f..1d92d97d7760a 100644 --- a/lib/commands/stars.js +++ b/lib/commands/stars.js @@ -1,5 +1,5 @@ const fetch = require('npm-registry-fetch') -const log = require('proc-log') +const { log, output } = require('proc-log') const getIdentity = require('../utils/get-identity.js') const BaseCommand = require('../base-command.js') @@ -25,7 +25,7 @@ class Stars extends BaseCommand { } for (const row of rows) { - this.npm.output(row.value) + output.standard(row.value) } } catch (err) { if (err.code === 'ENEEDAUTH') { diff --git a/lib/commands/team.js b/lib/commands/team.js index 3c6cf305a6e5f..4ffaa5ff86ab9 100644 --- a/lib/commands/team.js +++ b/lib/commands/team.js @@ -1,5 +1,6 @@ const columns = require('cli-columns') const libteam = require('libnpmteam') +const { output } = require('proc-log') const otplease = require('../utils/otplease.js') @@ -68,86 +69,86 @@ class Team extends BaseCommand { async create (entity, opts) { await libteam.create(entity, opts) if (opts.json) { - this.npm.output(JSON.stringify({ + output.standard(JSON.stringify({ created: true, team: entity, })) } else if (opts.parseable) { - this.npm.output(`${entity}\tcreated`) + output.standard(`${entity}\tcreated`) } else if (!this.npm.silent) { - this.npm.output(`+@${entity}`) + output.standard(`+@${entity}`) } } async destroy (entity, opts) { await libteam.destroy(entity, opts) if (opts.json) { - this.npm.output(JSON.stringify({ + output.standard(JSON.stringify({ deleted: true, team: entity, })) } else if (opts.parseable) { - this.npm.output(`${entity}\tdeleted`) + output.standard(`${entity}\tdeleted`) } else if (!this.npm.silent) { - this.npm.output(`-@${entity}`) + output.standard(`-@${entity}`) } } async add (entity, user, opts) { await libteam.add(user, entity, opts) if (opts.json) { - this.npm.output(JSON.stringify({ + output.standard(JSON.stringify({ added: true, team: entity, user, })) } else if (opts.parseable) { - this.npm.output(`${user}\t${entity}\tadded`) + output.standard(`${user}\t${entity}\tadded`) } else if (!this.npm.silent) { - this.npm.output(`${user} added to @${entity}`) + output.standard(`${user} added to @${entity}`) } } async rm (entity, user, opts) { await libteam.rm(user, entity, opts) if (opts.json) { - this.npm.output(JSON.stringify({ + output.standard(JSON.stringify({ removed: true, team: entity, user, })) } else if (opts.parseable) { - this.npm.output(`${user}\t${entity}\tremoved`) + output.standard(`${user}\t${entity}\tremoved`) } else if (!this.npm.silent) { - this.npm.output(`${user} removed from @${entity}`) + output.standard(`${user} removed from @${entity}`) } } async listUsers (entity, opts) { const users = (await libteam.lsUsers(entity, opts)).sort() if (opts.json) { - this.npm.output(JSON.stringify(users, null, 2)) + output.standard(JSON.stringify(users, null, 2)) } else if (opts.parseable) { - this.npm.output(users.join('\n')) + output.standard(users.join('\n')) } else if (!this.npm.silent) { const plural = users.length === 1 ? '' : 's' const more = users.length === 0 ? '' : ':\n' - this.npm.output(`\n@${entity} has ${users.length} user${plural}${more}`) - this.npm.output(columns(users, { padding: 1 })) + output.standard(`\n@${entity} has ${users.length} user${plural}${more}`) + output.standard(columns(users, { padding: 1 })) } } async listTeams (entity, opts) { const teams = (await libteam.lsTeams(entity, opts)).sort() if (opts.json) { - this.npm.output(JSON.stringify(teams, null, 2)) + output.standard(JSON.stringify(teams, null, 2)) } else if (opts.parseable) { - this.npm.output(teams.join('\n')) + output.standard(teams.join('\n')) } else if (!this.npm.silent) { const plural = teams.length === 1 ? '' : 's' const more = teams.length === 0 ? '' : ':\n' - this.npm.output(`\n@${entity} has ${teams.length} team${plural}${more}`) - this.npm.output(columns(teams.map(t => `@${t}`), { padding: 1 })) + output.standard(`\n@${entity} has ${teams.length} team${plural}${more}`) + output.standard(columns(teams.map(t => `@${t}`), { padding: 1 })) } } } diff --git a/lib/commands/token.js b/lib/commands/token.js index 361dfe52e8006..ba842f9747948 100644 --- a/lib/commands/token.js +++ b/lib/commands/token.js @@ -1,5 +1,5 @@ const Table = require('cli-table3') -const log = require('proc-log') +const { log, output } = require('proc-log') const profile = require('npm-profile') const otplease = require('../utils/otplease.js') @@ -51,12 +51,12 @@ class Token extends BaseCommand { log.info('token', 'getting list') const tokens = profile.listTokens(conf) if (conf.json) { - this.npm.output(JSON.stringify(tokens, null, 2)) + output.standard(JSON.stringify(tokens, null, 2)) return } else if (conf.parseable) { - this.npm.output(['key', 'token', 'created', 'readonly', 'CIDR whitelist'].join('\t')) + output.standard(['key', 'token', 'created', 'readonly', 'CIDR whitelist'].join('\t')) tokens.forEach(token => { - this.npm.output( + output.standard( [ token.key, token.token, @@ -83,7 +83,7 @@ class Token extends BaseCommand { token.cidr_whitelist ? token.cidr_whitelist.join(', ') : '', ]) }) - this.npm.output(table.toString()) + output.standard(table.toString()) } async rm (args) { @@ -119,11 +119,11 @@ class Token extends BaseCommand { }) ) if (conf.json) { - this.npm.output(JSON.stringify(toRemove)) + output.standard(JSON.stringify(toRemove)) } else if (conf.parseable) { - this.npm.output(toRemove.join('\t')) + output.standard(toRemove.join('\t')) } else { - this.npm.output('Removed ' + toRemove.length + ' token' + (toRemove.length !== 1 ? 's' : '')) + output.standard('Removed ' + toRemove.length + ' token' + (toRemove.length !== 1 ? 's' : '')) } } @@ -143,15 +143,15 @@ class Token extends BaseCommand { delete result.key delete result.updated if (conf.json) { - this.npm.output(JSON.stringify(result)) + output.standard(JSON.stringify(result)) } else if (conf.parseable) { - Object.keys(result).forEach(k => this.npm.output(k + '\t' + result[k])) + Object.keys(result).forEach(k => output.standard(k + '\t' + result[k])) } else { const table = new Table() for (const k of Object.keys(result)) { table.push({ [this.npm.chalk.bold(k)]: String(result[k]) }) } - this.npm.output(table.toString()) + output.standard(table.toString()) } } diff --git a/lib/commands/unpublish.js b/lib/commands/unpublish.js index 0b351ef3e37f0..3e7e8c8b624a2 100644 --- a/lib/commands/unpublish.js +++ b/lib/commands/unpublish.js @@ -2,11 +2,10 @@ const libaccess = require('libnpmaccess') const libunpub = require('libnpmpublish').unpublish const npa = require('npm-package-arg') const pacote = require('pacote') +const { output, log } = require('proc-log') const pkgJson = require('@npmcli/package-json') - const { flatten } = require('@npmcli/config/lib/definitions') const getIdentity = require('../utils/get-identity.js') -const log = require('proc-log') const otplease = require('../utils/otplease.js') const LAST_REMAINING_VERSION_ERROR = 'Refusing to delete the last version of the package. ' + @@ -161,7 +160,7 @@ class Unpublish extends BaseCommand { await otplease(this.npm, opts, o => libunpub(spec, o)) } if (!silent) { - this.npm.output(`- ${spec.name}${pkgVersion}`) + output.standard(`- ${spec.name}${pkgVersion}`) } } diff --git a/lib/commands/update.js b/lib/commands/update.js index 4799c635cae44..12b6ac153a588 100644 --- a/lib/commands/update.js +++ b/lib/commands/update.js @@ -1,6 +1,6 @@ const path = require('path') -const log = require('proc-log') +const { log } = require('proc-log') const reifyFinish = require('../utils/reify-finish.js') diff --git a/lib/commands/version.js b/lib/commands/version.js index 029a6fdd3101e..9776b70240519 100644 --- a/lib/commands/version.js +++ b/lib/commands/version.js @@ -1,6 +1,7 @@ const libnpmversion = require('libnpmversion') const { resolve } = require('path') const { promisify } = require('util') +const { output } = require('proc-log') const readFile = promisify(require('fs').readFile) const updateWorkspaces = require('../workspaces/update-workspaces.js') @@ -78,7 +79,7 @@ class Version extends BaseCommand { ...this.npm.flatOptions, path: this.npm.prefix, }) - return this.npm.output(`${prefix}${version}`) + return output.standard(`${prefix}${version}`) } async changeWorkspaces (args) { @@ -86,14 +87,14 @@ class Version extends BaseCommand { await this.setWorkspaces() const updatedWorkspaces = [] for (const [name, path] of this.workspaces) { - this.npm.output(name) + output.standard(name) const version = await libnpmversion(args[0], { ...this.npm.flatOptions, 'git-tag-version': false, path, }) updatedWorkspaces.push(name) - this.npm.output(`${prefix}${version}`) + output.standard(`${prefix}${version}`) } return this.update(updatedWorkspaces) } @@ -115,9 +116,9 @@ class Version extends BaseCommand { } if (this.npm.config.get('json')) { - this.npm.output(JSON.stringify(results, null, 2)) + output.standard(JSON.stringify(results, null, 2)) } else { - this.npm.output(results) + output.standard(results) } } diff --git a/lib/commands/view.js b/lib/commands/view.js index 255766267caaa..9fb0f8add1ca7 100644 --- a/lib/commands/view.js +++ b/lib/commands/view.js @@ -1,7 +1,7 @@ const columns = require('cli-columns') const fs = require('fs') const jsonParse = require('json-parse-even-better-errors') -const log = require('proc-log') +const { log, output } = require('proc-log') const npa = require('npm-package-arg') const { resolve } = require('path') const formatBytes = require('../utils/format-bytes.js') @@ -118,7 +118,7 @@ class View extends BaseCommand { const msg = await this.jsonData(reducedData, pckmnt._id) if (msg !== '') { - this.npm.output(msg) + output.standard(msg) } } } @@ -157,10 +157,10 @@ class View extends BaseCommand { if (wholePackument) { data.map((v) => this.prettyView(pckmnt, v[Object.keys(v)[0]][''])) } else { - this.npm.output(`${name}:`) + output.standard(`${name}:`) const msg = await this.jsonData(reducedData, pckmnt._id) if (msg !== '') { - this.npm.output(msg) + output.standard(msg) } } } else { @@ -171,7 +171,7 @@ class View extends BaseCommand { } } if (Object.keys(results).length > 0) { - this.npm.output(JSON.stringify(results, null, 2)) + output.standard(JSON.stringify(results, null, 2)) } } @@ -374,61 +374,61 @@ class View extends BaseCommand { info.license = chalk.green(info.license) } - this.npm.output('') - this.npm.output( + output.standard('') + output.standard( chalk.underline.bold(`${info.name}@${info.version}`) + ' | ' + info.license + ' | deps: ' + (info.deps.length ? chalk.cyan(info.deps.length) : chalk.green('none')) + ' | versions: ' + info.versions ) - info.description && this.npm.output(info.description) + info.description && output.standard(info.description) if (info.repo || info.site) { - info.site && this.npm.output(chalk.cyan(info.site)) + info.site && output.standard(chalk.cyan(info.site)) } const warningSign = unicode ? ' ⚠️ ' : '!!' - info.deprecated && this.npm.output( + info.deprecated && output.standard( `\n${chalk.bold.red('DEPRECATED')}${ warningSign } - ${info.deprecated}` ) if (info.keywords.length) { - this.npm.output('') - this.npm.output(`keywords: ${chalk.yellow(info.keywords.join(', '))}`) + output.standard('') + output.standard(`keywords: ${chalk.yellow(info.keywords.join(', '))}`) } if (info.bins.length) { - this.npm.output('') - this.npm.output(`bin: ${chalk.yellow(info.bins.join(', '))}`) + output.standard('') + output.standard(`bin: ${chalk.yellow(info.bins.join(', '))}`) } - this.npm.output('') - this.npm.output('dist') - this.npm.output(`.tarball: ${info.tarball}`) - this.npm.output(`.shasum: ${info.shasum}`) - info.integrity && this.npm.output(`.integrity: ${info.integrity}`) - info.unpackedSize && this.npm.output(`.unpackedSize: ${info.unpackedSize}`) + output.standard('') + output.standard('dist') + output.standard(`.tarball: ${info.tarball}`) + output.standard(`.shasum: ${info.shasum}`) + info.integrity && output.standard(`.integrity: ${info.integrity}`) + info.unpackedSize && output.standard(`.unpackedSize: ${info.unpackedSize}`) const maxDeps = 24 if (info.deps.length) { - this.npm.output('') - this.npm.output('dependencies:') - this.npm.output(columns(info.deps.slice(0, maxDeps), { padding: 1 })) + output.standard('') + output.standard('dependencies:') + output.standard(columns(info.deps.slice(0, maxDeps), { padding: 1 })) if (info.deps.length > maxDeps) { - this.npm.output(`(...and ${info.deps.length - maxDeps} more.)`) + output.standard(`(...and ${info.deps.length - maxDeps} more.)`) } } if (info.maintainers && info.maintainers.length) { - this.npm.output('') - this.npm.output('maintainers:') - info.maintainers.forEach((u) => this.npm.output(`- ${u}`)) + output.standard('') + output.standard('maintainers:') + info.maintainers.forEach((u) => output.standard(`- ${u}`)) } - this.npm.output('') - this.npm.output('dist-tags:') - this.npm.output(columns(info.tags)) + output.standard('') + output.standard('dist-tags:') + output.standard(columns(info.tags)) if (info.publisher || info.modified) { let publishInfo = 'published' @@ -438,8 +438,8 @@ class View extends BaseCommand { if (info.publisher) { publishInfo += ` by ${info.publisher}` } - this.npm.output('') - this.npm.output(publishInfo) + output.standard('') + output.standard(publishInfo) } } } diff --git a/lib/commands/whoami.js b/lib/commands/whoami.js index 154cc870391ba..e05993abdd5bf 100644 --- a/lib/commands/whoami.js +++ b/lib/commands/whoami.js @@ -1,3 +1,4 @@ +const { output } = require('proc-log') const getIdentity = require('../utils/get-identity.js') const BaseCommand = require('../base-command.js') @@ -8,7 +9,7 @@ class Whoami extends BaseCommand { async exec (args) { const username = await getIdentity(this.npm, { ...this.npm.flatOptions }) - this.npm.output( + output.standard( this.npm.config.get('json') ? JSON.stringify(username) : username ) } diff --git a/lib/npm.js b/lib/npm.js index 912371a1afaf8..8449e2e2775a8 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -11,7 +11,7 @@ const usage = require('./utils/npm-usage.js') const LogFile = require('./utils/log-file.js') const Timers = require('./utils/timers.js') const Display = require('./utils/display.js') -const log = require('proc-log') +const { log } = require('proc-log') const { redactLog: replaceInfo } = require('@npmcli/redact') const updateNotifier = require('./utils/update-notifier.js') const pkg = require('../package.json') @@ -50,14 +50,7 @@ class Npm { #display = null #logFile = new LogFile() - #timers = new Timers({ - start: 'npm', - listener: (name, ms) => { - const args = [name, `Completed in ${ms}ms`] - this.#logFile.log('timing', ...args) - this.#display.logTiming(...args) - }, - }) + #timers = new Timers({ start: 'npm' }) // all these options are only used by tests in order to make testing more // closely resemble real world usage. for now, npm has no programmatic API so @@ -251,7 +244,13 @@ class Npm { this.time('npm:load:display', () => { this.#display.load({ loglevel: this.config.get('loglevel'), - chalk: this.logChalk, // Use logChalk since that is based on stderr + // TODO: only pass in logColor and color and create chalk instances + // in display load method. Then remove chalk getters from npm and + // producers should emit chalk-templates (or something else). + stdoutChalk: this.#chalk, + stdoutColor: this.color, + stderrChalk: this.#logChalk, + stderrColor: this.logColor, timing: this.config.get('timing'), unicode: this.config.get('unicode'), progress: this.flatOptions.progress, @@ -440,22 +439,12 @@ class Npm { return usage(this) } + // TODO: move to proc-log and remove forceLog (...args) { this.#display.forceLog(...args) } - output (...args) { - this.#display.output(...args) - } - - outputError (...args) { - this.#display.outputError(...args) - } - - outputBuffer (arg) { - this.#display.outputBuffer(arg) - } - + // TODO: move to proc-log and remove flushOutput (jsonError) { this.#display.flushOutput(jsonError) } diff --git a/lib/package-url-cmd.js b/lib/package-url-cmd.js index 6e43b8989c191..dc6b6f7c0b512 100644 --- a/lib/package-url-cmd.js +++ b/lib/package-url-cmd.js @@ -4,7 +4,7 @@ const pacote = require('pacote') const hostedGitInfo = require('hosted-git-info') const openUrl = require('./utils/open-url.js') -const log = require('proc-log') +const { log } = require('proc-log') const BaseCommand = require('./base-command.js') class PackageUrlCommand extends BaseCommand { diff --git a/lib/utils/audit-error.js b/lib/utils/audit-error.js index 69025506d674b..10aec7592b03c 100644 --- a/lib/utils/audit-error.js +++ b/lib/utils/audit-error.js @@ -1,4 +1,4 @@ -const log = require('proc-log') +const { log, output } = require('proc-log') const { redactLog: replaceInfo } = require('@npmcli/redact') // print an error or just nothing if the audit report has an error @@ -22,7 +22,7 @@ const auditError = (npm, report) => { const { body: errBody } = error const body = Buffer.isBuffer(errBody) ? errBody.toString() : errBody if (npm.flatOptions.json) { - npm.output(JSON.stringify({ + output.standard(JSON.stringify({ message: error.message, method: error.method, uri: replaceInfo(error.uri), @@ -31,7 +31,7 @@ const auditError = (npm, report) => { body, }, null, 2)) } else { - npm.output(body) + output.standard(body) } throw 'audit endpoint returned an error' diff --git a/lib/utils/auth.js b/lib/utils/auth.js index 931c74c04f606..c38d7cc78e2ce 100644 --- a/lib/utils/auth.js +++ b/lib/utils/auth.js @@ -1,5 +1,5 @@ const profile = require('npm-profile') -const log = require('proc-log') +const { log } = require('proc-log') const openUrlPrompt = require('../utils/open-url-prompt.js') const read = require('../utils/read-user-info.js') const otplease = require('../utils/otplease.js') diff --git a/lib/utils/display.js b/lib/utils/display.js index c2e4918258afe..05cdee6f9dbe4 100644 --- a/lib/utils/display.js +++ b/lib/utils/display.js @@ -1,7 +1,7 @@ const proggy = require('proggy') -const log = require('proc-log') +const { log, output } = require('proc-log') const { explain } = require('./explain-eresolve.js') -const { formatWithOptions, format } = require('./format') +const { formatWithOptions } = require('./format') const COLOR_PALETTE = ({ chalk: c }) => ({ heading: c.white.bgBlack, @@ -17,7 +17,13 @@ const COLOR_PALETTE = ({ chalk: c }) => ({ silly: c.inverse, }) -const LEVELS = ['timing', ...log.LEVELS].reduce((acc, key) => { +const LOG_LEVELS = log.LEVELS.reduce((acc, key) => { + acc[key] = key + return acc +}, {}) + +// TODO: move flush to proc-log +const OUTPUT_LEVELS = ['flush', ...output.LEVELS].reduce((acc, key) => { acc[key] = key return acc }, {}) @@ -55,20 +61,20 @@ const LEVEL_OPTIONS = { const LEVEL_METHODS = { ...LEVEL_OPTIONS, - [LEVELS.timing]: { + [LOG_LEVELS.timing]: { show: ({ timing, index }) => !!timing && index !== 0, }, } -const safeJsonParse = (maybeJsonStr) => { - if (typeof maybeJsonStr !== 'string') { - return maybeJsonStr - } - try { - return JSON.parse(maybeJsonStr) - } catch { - return {} +const tryJsonParse = (value) => { + if (typeof value === 'string') { + try { + return JSON.parse(value) + } catch { + return {} + } } + return value } const setBlocking = (stream) => { @@ -81,17 +87,30 @@ const setBlocking = (stream) => { return stream } +const getLevel = (stringOrLevelObject) => { + if (typeof stringOrLevelObject === 'string') { + return { level: stringOrLevelObject } + } + return stringOrLevelObject +} + class Display { - // pause by default until config is loaded - #paused = true + #logState = { + buffering: true, + buffer: [], + } - // buffers to store logs when paused - #logBuffer = [] - #outputBuffer = [] + #outputState = { + buffering: true, + buffer: [], + } // colors - #chalk - #colors + #stdoutChalk + #stdoutColor + #stderrChalk + #stderrColor + #logColors // progress #progress @@ -109,142 +128,215 @@ class Display { constructor ({ stdout, stderr }) { this.#stdout = setBlocking(stdout) this.#stderr = setBlocking(stderr) + + // Handlers are set immediately so they can buffer all events process.on('log', this.#logHandler) + process.on('output', this.#outputHandler) } off () { process.off('log', this.#logHandler) - this.#logBuffer.length = 0 + this.#logState.buffer.length = 0 + + process.off('output', this.#outputHandler) + this.#outputState.buffer.length = 0 + if (this.#progress) { this.#progress.stop() } } - load ({ loglevel, chalk, timing, unicode, progress, json, heading }) { - this.#chalk = chalk - this.#colors = COLOR_PALETTE({ chalk }) + load ({ + heading, + json, + loglevel, + progress, + stderrChalk, + stderrColor, + stdoutChalk, + stdoutColor, + timing, + unicode, + }) { + this.#stdoutColor = stdoutColor + this.#stdoutChalk = stdoutChalk + + this.#stderrColor = stderrColor + this.#stderrChalk = stderrChalk + + this.#logColors = COLOR_PALETTE({ chalk: stderrChalk }) this.#levelIndex = LEVEL_OPTIONS[loglevel].index this.#timing = timing this.#json = json this.#heading = heading + // In silent mode we remove all the handlers if (this.#levelIndex <= 0) { this.off() - } else { - log.resume() - if (progress) { - this.#startProgress({ unicode }) - } + return } - } - logTiming (...args) { - this.#logHandler(LEVELS.timing, ...args) - } + // Emit resume event on the logs which will flush output + log.resume() - forceLog (level, ...args) { - // This will show the log regardless of the current loglevel, except when silent - this.#logHandler({ level, force: true }, ...args) - } + // TODO: this should be a proc-log method `proc-log.output.flush`? + this.#outputHandler(OUTPUT_LEVELS.flush) - output (...args) { - // TODO: make this respect silent option - this.#stdout.write(format(...args)) + this.#startProgress({ progress, unicode }) } - outputError (...args) { - this.#stderr.write(format(...args)) + // STREAM WRITES + + // Write formatted and (non-)colorized output to streams + #stdoutWrite (options, ...args) { + this.#stdout.write(formatWithOptions({ colors: this.#stdoutColor, ...options }, ...args)) } - outputBuffer (item) { - this.#outputBuffer.push(item) + #stderrWrite (options, ...args) { + this.#stderr.write(formatWithOptions({ colors: this.#stderrColor, ...options }, ...args)) } - flushOutput (jsonError) { - if (!jsonError && !this.#outputBuffer.length) { + // HANDLERS + + // Arrow function assigned to a private class field so it can be passed + // directly as a listener and still reference "this" + #logHandler = (...args) => { + if (args[0] === LOG_LEVELS.resume) { + this.#logState.buffering = false + this.#logState.buffer.forEach((item) => this.#tryWriteLog(...item)) + this.#logState.buffer.length = 0 return } - if (this.#json) { - const output = this.#outputBuffer.reduce((a, i) => ({ ...a, ...safeJsonParse(i) }), {}) - this.output(JSON.stringify({ ...output, ...jsonError }, null, 2)) - } else { - this.#outputBuffer.forEach((item) => this.output(item)) + if (args[0] === LOG_LEVELS.pause) { + this.#logState.buffering = true + return } - this.#outputBuffer.length = 0 + if (this.#logState.buffering) { + this.#logState.buffer.push(args) + return + } + + this.#tryWriteLog(...args) } - #write (...args) { - const { level: levelName, force = false } = typeof args[0] === 'string' - ? { level: args[0] } : args[0] + // Arrow function assigned to a private class field so it can be passed + // directly as a listener and still reference "this" + #outputHandler = (...args) => { + if (args[0] === OUTPUT_LEVELS.flush) { + this.#outputState.buffering = false + if (args[1] && this.#json) { + const json = {} + for (const [, item] of this.#outputState.buffer) { + Object.assign(json, tryJsonParse(item)) + } + this.#writeOutput('standard', JSON.stringify({ ...json, ...args[1] }, null, 2)) + } else { + this.#outputState.buffer.forEach((item) => this.#writeOutput(...item)) + } + this.#outputState.buffer.length = 0 + return + } - if (levelName === LEVELS.pause) { - this.#paused = true + if (args[0] === OUTPUT_LEVELS.buffer) { + this.#outputState.buffer.push(['standard', ...args.slice(1)]) return } - if (levelName === LEVELS.resume) { - this.#paused = false - this.#logBuffer.forEach((item) => this.#write(...item)) - this.#logBuffer.length = 0 + if (this.#outputState.buffering) { + this.#outputState.buffer.push(args) return } - if (this.#paused) { - this.#logBuffer.push(args) + this.#writeOutput(...args) + } + + // OUTPUT + + #writeOutput (...args) { + const { level } = getLevel(args.shift()) + + if (level === OUTPUT_LEVELS.standard) { + this.#stdoutWrite({}, ...args) return } - const level = LEVEL_METHODS[levelName] - const show = level.show ?? (({ index }) => level.index <= index) + if (level === OUTPUT_LEVELS.error) { + this.#stderrWrite({}, ...args) + } + } - if ((force && level.index !== 0) || show({ index: this.#levelIndex, timing: this.#timing })) { - // this mutates the array so we can pass args directly to format later - const [, title] = args.splice(0, 2) - const prefix = [ - this.#colors.heading(this.#heading), - this.#colors[levelName](level.label ?? levelName), - title ? this.#colors.title(title) : null, - ] - this.#stderr.write(formatWithOptions({ prefix }, ...args)) - } else if (this.#progress) { - // TODO: make this display a single log line of filtered messages + // TODO: move this to proc-log and remove this public method + flushOutput (jsonError) { + this.#outputHandler(OUTPUT_LEVELS.flush, jsonError) + } + + // LOGS + + // TODO: make proc-log able to send signal data like `force` + // when that happens, remove this public method + forceLog (level, ...args) { + // This will show the log regardless of the current loglevel except when silent + if (this.#levelIndex !== 0) { + this.#logHandler({ level, force: true }, ...args) } } - #logHandler = (level, ...args) => { + #tryWriteLog (...args) { try { - this.#log(level, ...args) + // Also (and this is a really inexcusable kludge), we patch the + // log.warn() method so that when we see a peerDep override + // explanation from Arborist, we can replace the object with a + // highly abbreviated explanation of what's being overridden. + // TODO: this could probably be moved to arborist now that display is refactored + const [level, heading, message, expl] = args + if (level === LOG_LEVELS.warn && heading === 'ERESOLVE' && expl && typeof expl === 'object') { + this.#writeLog(level, heading, message) + this.#writeLog(level, '', explain(expl, this.#stderrChalk, 2)) + return + } + this.#writeLog(...args) } catch (ex) { try { // if it crashed once, it might again! - this.#write(LEVELS.verbose, null, `attempt to log crashed`, ...args, ex) + this.#writeLog(LOG_LEVELS.verbose, null, `attempt to log crashed`, ...args, ex) } catch (ex2) { - /* istanbul ignore next - this happens if the object has an inspect method that crashes */ + // This happens if the object has an inspect method that crashes so just console.error + // with the errors but don't do anything else that might error again. // eslint-disable-next-line no-console console.error(`attempt to log crashed`, ex, ex2) } } } - #log (...args) { - const [level, heading, message, expl] = args - if (level === LEVELS.warn && heading === 'ERESOLVE' && expl && typeof expl === 'object') { - // Also (and this is a really inexcusable kludge), we patch the - // log.warn() method so that when we see a peerDep override - // explanation from Arborist, we can replace the object with a - // highly abbreviated explanation of what's being overridden. - // TODO: this could probably be moved to arborist now that display is refactored - this.#write(level, heading, message) - this.#write(level, '', explain(expl, this.#chalk, 2)) - return + #writeLog (...args) { + const { level, force = false } = getLevel(args.shift()) + + const levelOpts = LEVEL_METHODS[level] + const show = levelOpts.show ?? (({ index }) => levelOpts.index <= index) + + if (force || show({ index: this.#levelIndex, timing: this.#timing })) { + // this mutates the array so we can pass args directly to format later + const title = args.shift() + const prefix = [ + this.#logColors.heading(this.#heading), + this.#logColors[level](levelOpts.label ?? level), + title ? this.#logColors.title(title) : null, + ] + this.#stderrWrite({ prefix }, ...args) + } else if (this.#progress) { + // TODO: make this display a single log line of filtered messages } - this.#write(...args) } - #startProgress ({ unicode }) { + // PROGRESS + + #startProgress ({ progress, unicode }) { + if (!progress) { + return + } this.#progress = proggy.createClient({ normalize: true }) // TODO: implement proggy trackers in arborist/doctor // TODO: listen to progress events here and build progress UI diff --git a/lib/utils/error-message.js b/lib/utils/error-message.js index e68181bc0ea0b..c27b8a3447957 100644 --- a/lib/utils/error-message.js +++ b/lib/utils/error-message.js @@ -2,7 +2,7 @@ const { format } = require('util') const { resolve } = require('path') const { redactLog: replaceInfo } = require('@npmcli/redact') const { report } = require('./explain-eresolve.js') -const log = require('proc-log') +const { log } = require('proc-log') const messageText = msg => msg.map(line => line.slice(1).join(' ')).join('\n') diff --git a/lib/utils/exit-handler.js b/lib/utils/exit-handler.js index ab436a8f38951..ce1bfaa54a56a 100644 --- a/lib/utils/exit-handler.js +++ b/lib/utils/exit-handler.js @@ -1,7 +1,6 @@ const os = require('os') const fs = require('fs') - -const log = require('proc-log') +const { log, output } = require('proc-log') const errorMessage = require('./error-message.js') const { redactLog: replaceInfo } = require('@npmcli/redact') @@ -32,10 +31,13 @@ process.on('exit', code => { if (!exitHandlerCalled) { process.exitCode = code || 1 log.error('', 'Exit handler never called!') - // eslint-disable-next-line no-console - console.error('') log.error('', 'This is an error with npm itself. Please report this error at:') log.error('', ' ') + + // This gets logged regardless of silent mode + // eslint-disable-next-line no-console + console.error('') + showLogFileError = true } @@ -60,11 +62,8 @@ process.on('exit', code => { const logMethod = showLogFileError ? 'error' : timing ? 'info' : null if (logMethod) { - if (!npm.silent) { - // just a line break if not in silent mode - // eslint-disable-next-line no-console - console.error('') - } + // just a line break, will be ignored in silent mode + output.error('') const message = [] @@ -108,6 +107,7 @@ const exitHandler = err => { if (!npm) { err = err || new Error('Exit prior to setting npm in exit handler') + // Don't use proc-log here since npm was never set // eslint-disable-next-line no-console console.error(err.stack || err.message) return process.exit(1) @@ -115,12 +115,14 @@ const exitHandler = err => { if (!hasLoadedNpm) { err = err || new Error('Exit prior to config file resolving.') + // Don't use proc-log here since npm was never loaded // eslint-disable-next-line no-console console.error(err.stack || err.message) } // only show the notification if it finished. if (typeof npm.updateNotification === 'string') { + // TODO: use proc-log to send `force: true` along with event npm.forceLog('notice', '', npm.updateNotification) } @@ -198,6 +200,7 @@ const exitHandler = err => { } if (hasLoadedNpm) { + // TODO: use proc-log.output.flush() once it exists npm.flushOutput(jsonError) } diff --git a/lib/utils/format.js b/lib/utils/format.js index 97f01996a2025..abfbf9e331704 100644 --- a/lib/utils/format.js +++ b/lib/utils/format.js @@ -47,6 +47,4 @@ const formatWithOptions = ({ prefix: prefixes = [], eol = '\n', ...options }, .. return lines.reduce((acc, l) => `${acc}${prefix}${prefix && l ? ' ' : ''}${l}${eol}`, '') } -const format = (...args) => formatWithOptions({}, ...args) - -module.exports = { format, formatWithOptions } +module.exports = { formatWithOptions } diff --git a/lib/utils/log-file.js b/lib/utils/log-file.js index 4a5eaf9be0280..a3792abf91951 100644 --- a/lib/utils/log-file.js +++ b/lib/utils/log-file.js @@ -3,7 +3,7 @@ const { join, dirname, basename } = require('path') const { Minipass } = require('minipass') const fsMiniPass = require('fs-minipass') const fs = require('fs/promises') -const log = require('proc-log') +const { log } = require('proc-log') const { formatWithOptions } = require('./format') const padZero = (n, length) => n.toString().padStart(length.toString().length, '0') diff --git a/lib/utils/open-url-prompt.js b/lib/utils/open-url-prompt.js index 71a68c253c050..261cf370da6bd 100644 --- a/lib/utils/open-url-prompt.js +++ b/lib/utils/open-url-prompt.js @@ -1,4 +1,5 @@ const readline = require('readline') +const { output } = require('proc-log') const open = require('./open-url.js') function print (npm, title, url) { @@ -6,7 +7,7 @@ function print (npm, title, url) { const message = json ? JSON.stringify({ title, url }) : `${title}:\n${url}` - npm.output(message) + output.standard(message) } // Prompt to open URL in browser if possible @@ -48,7 +49,7 @@ const promptOpen = async (npm, url, title, prompt, emitter) => { rl.close() // clear the prompt line - npm.output('') + output.standard('') resolve(false) }) diff --git a/lib/utils/open-url.js b/lib/utils/open-url.js index 77bb1d03d8e16..46b7abc731fa1 100644 --- a/lib/utils/open-url.js +++ b/lib/utils/open-url.js @@ -1,4 +1,5 @@ const promiseSpawn = require('@npmcli/promise-spawn') +const { output } = require('proc-log') const { URL } = require('url') @@ -16,7 +17,7 @@ const open = async (npm, url, errMsg, isFile) => { }, null, 2) : `${errMsg}:\n ${url}\n` - npm.output(alternateMsg) + output.standard(alternateMsg) } if (browser === false) { diff --git a/lib/utils/read-user-info.js b/lib/utils/read-user-info.js index 3c7817e3e491a..b2cd7374c17c3 100644 --- a/lib/utils/read-user-info.js +++ b/lib/utils/read-user-info.js @@ -1,6 +1,6 @@ const { read } = require('read') const userValidate = require('npm-user-validate') -const log = require('proc-log') +const { log } = require('proc-log') exports.otp = readOTP exports.password = readPassword diff --git a/lib/utils/reify-output.js b/lib/utils/reify-output.js index 3b2b69279e190..40f1722f246e9 100644 --- a/lib/utils/reify-output.js +++ b/lib/utils/reify-output.js @@ -9,7 +9,7 @@ // found 37 vulnerabilities (5 low, 7 moderate, 25 high) // run `npm audit fix` to fix them, or `npm audit` for details -const log = require('proc-log') +const { log, output } = require('proc-log') const { depth } = require('treeverse') const ms = require('ms') const npmAuditReport = require('npm-audit-report') @@ -99,7 +99,7 @@ const reifyOutput = (npm, arb) => { }) if (diffTable) { - npm.output('\n' + diffTable.toString()) + output.standard('\n' + diffTable.toString()) } } @@ -115,7 +115,7 @@ const reifyOutput = (npm, arb) => { summary.audit = npm.command === 'audit' ? auditReport : auditReport.toJSON().metadata } - npm.output(JSON.stringify(summary, null, 2)) + output.standard(JSON.stringify(summary, null, 2)) } else { packagesChangedMessage(npm, summary) packagesFundingMessage(npm, summary) @@ -134,7 +134,7 @@ const printAuditReport = (npm, report) => { if (!res || !res.report) { return } - npm.output(`\n${res.report}`) + output.standard(`\n${res.report}`) } const getAuditReport = (npm, report) => { @@ -206,7 +206,7 @@ const packagesChangedMessage = (npm, { added, removed, changed, audited }) => { } msg.push(` in ${ms(Date.now() - npm.started)}`) - npm.output(msg.join('')) + output.standard(msg.join('')) } const packagesFundingMessage = (npm, { funding }) => { @@ -214,11 +214,11 @@ const packagesFundingMessage = (npm, { funding }) => { return } - npm.output('') + output.standard('') const pkg = funding === 1 ? 'package' : 'packages' const is = funding === 1 ? 'is' : 'are' - npm.output(`${funding} ${pkg} ${is} looking for funding`) - npm.output(' run `npm fund` for details') + output.standard(`${funding} ${pkg} ${is} looking for funding`) + output.standard(' run `npm fund` for details') } module.exports = reifyOutput diff --git a/lib/utils/tar.js b/lib/utils/tar.js index e03b4b65466e4..8883f231a8981 100644 --- a/lib/utils/tar.js +++ b/lib/utils/tar.js @@ -1,6 +1,6 @@ const tar = require('tar') const ssri = require('ssri') -const log = require('proc-log') +const { log } = require('proc-log') const formatBytes = require('./format-bytes.js') const columnify = require('columnify') const localeCompare = require('@isaacs/string-locale-compare')('en', { diff --git a/lib/utils/timers.js b/lib/utils/timers.js index c897757b697fd..58ff39b6a1d66 100644 --- a/lib/utils/timers.js +++ b/lib/utils/timers.js @@ -1,24 +1,20 @@ const EE = require('events') const fs = require('fs') -const log = require('proc-log') +const { log } = require('proc-log') + +const INITIAL_TIMER = 'npm' -// This is an event emiiter but on/off -// only listen on a single internal event that gets -// emitted whenever a timer ends class Timers extends EE { file = null #unfinished = new Map() #finished = {} - #onTimeEnd = Symbol('onTimeEnd') - #initialListener = null - #initialTimer = null - constructor ({ listener = null, start = 'npm' } = {}) { + constructor () { super() - this.#initialListener = listener - this.#initialTimer = start - this.#init() + this.on() + process.emit('time', INITIAL_TIMER) + this.started = this.#unfinished.get(INITIAL_TIMER) } get unfinished () { @@ -29,32 +25,14 @@ class Timers extends EE { return this.#finished } - #init () { - this.on() - if (this.#initialListener) { - this.on(this.#initialListener) - } - process.emit('time', this.#initialTimer) - this.started = this.#unfinished.get(this.#initialTimer) - } - - on (listener) { - if (listener) { - super.on(this.#onTimeEnd, listener) - } else { - process.on('time', this.#timeListener) - process.on('timeEnd', this.#timeEndListener) - } + on () { + process.on('time', this.#timeListener) + process.on('timeEnd', this.#timeEndListener) } - off (listener) { - if (listener) { - super.off(this.#onTimeEnd, listener) - } else { - this.removeAllListeners(this.#onTimeEnd) - process.off('time', this.#timeListener) - process.off('timeEnd', this.#timeEndListener) - } + off () { + process.off('time', this.#timeListener) + process.off('timeEnd', this.#timeEndListener) } time (name, fn) { @@ -80,7 +58,7 @@ class Timers extends EE { try { const globalStart = this.started - const globalEnd = this.#finished.npm || Date.now() + const globalEnd = this.#finished[INITIAL_TIMER] || Date.now() const content = { metadata, timers: this.#finished, @@ -106,7 +84,7 @@ class Timers extends EE { const ms = Date.now() - this.#unfinished.get(name) this.#finished[name] = ms this.#unfinished.delete(name) - this.emit(this.#onTimeEnd, name, ms) + log.timing(name, `Completed in ${ms}ms`) } else { log.silly('timing', "Tried to end timer that doesn't exist:", name) } diff --git a/mock-registry/package.json b/mock-registry/package.json index 2bc1035c0a14b..8be3efdb1ff8f 100644 --- a/mock-registry/package.json +++ b/mock-registry/package.json @@ -50,8 +50,8 @@ "@npmcli/template-oss": "4.21.3", "json-stringify-safe": "^5.0.1", "nock": "^13.3.3", - "npm-package-arg": "^11.0.1", - "pacote": "^17.0.4", + "npm-package-arg": "^11.0.2", + "pacote": "^18.0.0", "tap": "^16.3.8" } } diff --git a/node_modules/.gitignore b/node_modules/.gitignore index 10c7e82b9c489..beddaa3541d3e 100644 --- a/node_modules/.gitignore +++ b/node_modules/.gitignore @@ -158,6 +158,9 @@ !/mute-stream !/negotiator !/node-gyp +!/node-gyp/node_modules/ +/node-gyp/node_modules/* +!/node-gyp/node_modules/proc-log !/nopt !/normalize-package-data !/npm-audit-report diff --git a/node_modules/@npmcli/git/lib/spawn.js b/node_modules/@npmcli/git/lib/spawn.js index 5e96eb5542b5a..03c1cbde21547 100644 --- a/node_modules/@npmcli/git/lib/spawn.js +++ b/node_modules/@npmcli/git/lib/spawn.js @@ -1,6 +1,6 @@ const spawn = require('@npmcli/promise-spawn') const promiseRetry = require('promise-retry') -const log = require('proc-log') +const { log } = require('proc-log') const makeError = require('./make-error.js') const makeOpts = require('./opts.js') diff --git a/node_modules/@npmcli/git/package.json b/node_modules/@npmcli/git/package.json index 7493ec7fb0eff..f7117f13a9399 100644 --- a/node_modules/@npmcli/git/package.json +++ b/node_modules/@npmcli/git/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/git", - "version": "5.0.5", + "version": "5.0.6", "main": "lib/index.js", "files": [ "bin/", @@ -40,7 +40,7 @@ "@npmcli/promise-spawn": "^7.0.0", "lru-cache": "^10.0.1", "npm-pick-manifest": "^9.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.0.0", "promise-inflight": "^1.0.1", "promise-retry": "^2.0.1", "semver": "^7.3.5", diff --git a/node_modules/@npmcli/metavuln-calculator/package.json b/node_modules/@npmcli/metavuln-calculator/package.json index 4d0af031d5414..c3fbada55aaf7 100644 --- a/node_modules/@npmcli/metavuln-calculator/package.json +++ b/node_modules/@npmcli/metavuln-calculator/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/metavuln-calculator", - "version": "7.0.0", + "version": "7.0.1", "main": "lib/index.js", "files": [ "bin/", @@ -19,7 +19,7 @@ "snap": "tap", "postsnap": "npm run lint", "eslint": "eslint", - "lint": "eslint \"**/*.js\"", + "lint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"", "lintfix": "npm run lint -- --fix", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force" @@ -34,14 +34,14 @@ }, "devDependencies": { "@npmcli/eslint-config": "^4.0.0", - "@npmcli/template-oss": "4.18.0", + "@npmcli/template-oss": "4.21.4", "require-inject": "^1.4.4", "tap": "^16.0.1" }, "dependencies": { "cacache": "^18.0.0", "json-parse-even-better-errors": "^3.0.0", - "pacote": "^17.0.0", + "pacote": "^18.0.0", "semver": "^7.3.5" }, "engines": { @@ -49,7 +49,7 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.18.0", + "version": "4.21.4", "publish": "true", "ciVersions": [ "16.14.0", diff --git a/node_modules/@npmcli/package-json/lib/normalize.js b/node_modules/@npmcli/package-json/lib/normalize.js index 350b3f3d7cb8f..e3b3798488427 100644 --- a/node_modules/@npmcli/package-json/lib/normalize.js +++ b/node_modules/@npmcli/package-json/lib/normalize.js @@ -2,7 +2,7 @@ const valid = require('semver/functions/valid') const clean = require('semver/functions/clean') const fs = require('fs/promises') const path = require('path') -const log = require('proc-log') +const { log } = require('proc-log') /** * @type {import('hosted-git-info')} diff --git a/node_modules/@npmcli/package-json/package.json b/node_modules/@npmcli/package-json/package.json index 4f7a29d2e4c59..faf9a952fe915 100644 --- a/node_modules/@npmcli/package-json/package.json +++ b/node_modules/@npmcli/package-json/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/package-json", - "version": "5.0.2", + "version": "5.0.3", "description": "Programmatic API to update package.json", "main": "lib/index.js", "files": [ @@ -36,7 +36,7 @@ "hosted-git-info": "^7.0.0", "json-parse-even-better-errors": "^3.0.0", "normalize-package-data": "^6.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.0.0", "semver": "^7.5.3" }, "repository": { diff --git a/node_modules/@npmcli/run-script/lib/run-script-pkg.js b/node_modules/@npmcli/run-script/lib/run-script-pkg.js index ea33db5629858..a4f27b500718c 100644 --- a/node_modules/@npmcli/run-script/lib/run-script-pkg.js +++ b/node_modules/@npmcli/run-script/lib/run-script-pkg.js @@ -5,19 +5,6 @@ const { isNodeGypPackage, defaultGypInstallScript } = require('@npmcli/node-gyp' const signalManager = require('./signal-manager.js') const isServerPackage = require('./is-server-package.js') -// you wouldn't like me when I'm angry... -const bruce = (id, event, cmd, args) => { - let banner = id - ? `\n> ${id} ${event}\n` - : `\n> ${event}\n` - banner += `> ${cmd.trim().replace(/\n/g, '\n> ')}` - if (args.length) { - banner += ` ${args.join(' ')}` - } - banner += '\n' - return banner -} - const runScriptPkg = async options => { const { event, @@ -29,8 +16,6 @@ const runScriptPkg = async options => { pkg, args = [], stdioString, - // note: only used when stdio:inherit - banner = true, // how long to wait for a process.kill signal // only exposed here so that we can make the test go a bit faster. signalTimeout = 500, @@ -59,9 +44,20 @@ const runScriptPkg = async options => { return { code: 0, signal: null } } - if (stdio === 'inherit' && banner !== false) { - // we're dumping to the parent's stdout, so print the banner - console.log(bruce(pkg._id, event, cmd, args)) + if (stdio === 'inherit') { + let banner + if (pkg._id) { + banner = `\n> ${pkg._id} ${event}\n` + } else { + banner = `\n> ${event}\n` + } + banner += `> ${cmd.trim().replace(/\n/g, '\n> ')}` + if (args.length) { + banner += ` ${args.join(' ')}` + } + banner += '\n' + const { output } = require('proc-log') + output.standard(banner) } const [spawnShell, spawnArgs, spawnOpts] = makeSpawnArgs({ diff --git a/node_modules/@npmcli/run-script/package.json b/node_modules/@npmcli/run-script/package.json index 1c98b1b170e26..dc780ad3ecbec 100644 --- a/node_modules/@npmcli/run-script/package.json +++ b/node_modules/@npmcli/run-script/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/run-script", - "version": "7.0.4", + "version": "8.0.0", "description": "Run a lifecycle script for a package (descendant of npm-lifecycle)", "author": "GitHub Inc.", "license": "ISC", @@ -25,6 +25,7 @@ "@npmcli/package-json": "^5.0.0", "@npmcli/promise-spawn": "^7.0.0", "node-gyp": "^10.0.0", + "proc-log": "^4.0.0", "which": "^4.0.0" }, "files": [ diff --git a/node_modules/color-name/test.js b/node_modules/color-name/test.js deleted file mode 100644 index 6e6bf30bcd622..0000000000000 --- a/node_modules/color-name/test.js +++ /dev/null @@ -1,7 +0,0 @@ -'use strict' - -var names = require('./'); -var assert = require('assert'); - -assert.deepEqual(names.red, [255,0,0]); -assert.deepEqual(names.aliceblue, [240,248,255]); diff --git a/node_modules/node-gyp/node_modules/proc-log/LICENSE b/node_modules/node-gyp/node_modules/proc-log/LICENSE new file mode 100644 index 0000000000000..83837797202b7 --- /dev/null +++ b/node_modules/node-gyp/node_modules/proc-log/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) GitHub, Inc. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/node-gyp/node_modules/proc-log/lib/index.js b/node_modules/node-gyp/node_modules/proc-log/lib/index.js new file mode 100644 index 0000000000000..7c5dfad3b7ba3 --- /dev/null +++ b/node_modules/node-gyp/node_modules/proc-log/lib/index.js @@ -0,0 +1,23 @@ +// emits 'log' events on the process +const LEVELS = [ + 'notice', + 'error', + 'warn', + 'info', + 'verbose', + 'http', + 'silly', + 'pause', + 'resume', +] + +const log = level => (...args) => process.emit('log', level, ...args) + +const logger = {} +for (const level of LEVELS) { + logger[level] = log(level) +} + +logger.LEVELS = LEVELS + +module.exports = logger diff --git a/node_modules/node-gyp/node_modules/proc-log/package.json b/node_modules/node-gyp/node_modules/proc-log/package.json new file mode 100644 index 0000000000000..d335fa965ace5 --- /dev/null +++ b/node_modules/node-gyp/node_modules/proc-log/package.json @@ -0,0 +1,44 @@ +{ + "name": "proc-log", + "version": "3.0.0", + "files": [ + "bin/", + "lib/" + ], + "main": "lib/index.js", + "description": "just emit 'log' events on the process object", + "repository": { + "type": "git", + "url": "https://github.com/npm/proc-log.git" + }, + "author": "GitHub Inc.", + "license": "ISC", + "scripts": { + "test": "tap", + "snap": "tap", + "posttest": "npm run lint", + "postsnap": "eslint index.js test/*.js --fix", + "lint": "eslint \"**/*.js\"", + "postlint": "template-oss-check", + "lintfix": "npm run lint -- --fix", + "template-oss-apply": "template-oss-apply --force" + }, + "devDependencies": { + "@npmcli/eslint-config": "^3.0.1", + "@npmcli/template-oss": "4.5.1", + "tap": "^16.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "4.5.1" + }, + "tap": { + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] + } +} diff --git a/node_modules/npm-package-arg/lib/npa.js b/node_modules/npm-package-arg/lib/npa.js index 23bf68d2e04a3..6a3f07da929d8 100644 --- a/node_modules/npm-package-arg/lib/npa.js +++ b/node_modules/npm-package-arg/lib/npa.js @@ -10,7 +10,7 @@ const semver = require('semver') const path = global.FAKE_WINDOWS ? require('path').win32 : require('path') const validatePackageName = require('validate-npm-package-name') const { homedir } = require('os') -const log = require('proc-log') +const { log } = require('proc-log') const isWindows = process.platform === 'win32' || global.FAKE_WINDOWS const hasSlashes = isWindows ? /\\|[/]/ : /[/]/ diff --git a/node_modules/npm-package-arg/package.json b/node_modules/npm-package-arg/package.json index f7965d5a007c9..c4cee1f928e89 100644 --- a/node_modules/npm-package-arg/package.json +++ b/node_modules/npm-package-arg/package.json @@ -1,6 +1,6 @@ { "name": "npm-package-arg", - "version": "11.0.1", + "version": "11.0.2", "description": "Parse the things that can be arguments to `npm install`", "main": "./lib/npa.js", "directories": { @@ -12,20 +12,20 @@ ], "dependencies": { "hosted-git-info": "^7.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.0.0", "semver": "^7.3.5", "validate-npm-package-name": "^5.0.0" }, "devDependencies": { "@npmcli/eslint-config": "^4.0.0", - "@npmcli/template-oss": "4.18.0", + "@npmcli/template-oss": "4.21.3", "tap": "^16.0.1" }, "scripts": { "test": "tap", "snap": "tap", "npmclilint": "npmcli-lint", - "lint": "eslint \"**/*.js\"", + "lint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"", "lintfix": "npm run lint -- --fix", "posttest": "npm run lint", "postsnap": "npm run lintfix --", @@ -54,14 +54,7 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.18.0", - "publish": true, - "ciVersions": [ - "16.14.0", - "16.x", - "18.0.0", - "18.x" - ], - "npmSpec": "next-9" + "version": "4.21.3", + "publish": true } } diff --git a/node_modules/npm-profile/lib/index.js b/node_modules/npm-profile/lib/index.js index ce78882a55438..a56a3794ba891 100644 --- a/node_modules/npm-profile/lib/index.js +++ b/node_modules/npm-profile/lib/index.js @@ -5,7 +5,7 @@ const { HttpErrorBase } = require('npm-registry-fetch/lib/errors') const EventEmitter = require('events') const os = require('os') const { URL } = require('url') -const log = require('proc-log') +const { log } = require('proc-log') // try loginWeb, catch the "not supported" message and fall back to couch const login = (opener, prompter, opts = {}) => { diff --git a/node_modules/npm-profile/package.json b/node_modules/npm-profile/package.json index af57e9e73509c..3b4b582f8c15f 100644 --- a/node_modules/npm-profile/package.json +++ b/node_modules/npm-profile/package.json @@ -1,13 +1,13 @@ { "name": "npm-profile", - "version": "9.0.0", + "version": "9.0.1", "description": "Library for updating an npmjs.com profile", "keywords": [], "author": "GitHub Inc.", "license": "ISC", "dependencies": { "npm-registry-fetch": "^16.0.0", - "proc-log": "^3.0.0" + "proc-log": "^4.0.0" }, "main": "./lib/index.js", "repository": { @@ -20,7 +20,7 @@ ], "devDependencies": { "@npmcli/eslint-config": "^4.0.0", - "@npmcli/template-oss": "4.18.0", + "@npmcli/template-oss": "4.21.3", "nock": "^13.2.4", "tap": "^16.0.1" }, @@ -28,7 +28,7 @@ "posttest": "npm run lint", "test": "tap", "snap": "tap", - "lint": "eslint \"**/*.js\"", + "lint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"", "postlint": "template-oss-check", "lintfix": "npm run lint -- --fix", "template-oss-apply": "template-oss-apply --force" @@ -45,13 +45,7 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.18.0", - "ciVersions": [ - "16.14.0", - "16.x", - "18.0.0", - "18.x" - ], + "version": "4.21.3", "publish": true } } diff --git a/node_modules/npm-registry-fetch/lib/check-response.js b/node_modules/npm-registry-fetch/lib/check-response.js index 183311d840397..65eea2963b0b4 100644 --- a/node_modules/npm-registry-fetch/lib/check-response.js +++ b/node_modules/npm-registry-fetch/lib/check-response.js @@ -3,7 +3,7 @@ const errors = require('./errors.js') const { Response } = require('minipass-fetch') const defaultOpts = require('./default-opts.js') -const log = require('proc-log') +const { log } = require('proc-log') const { redact: cleanUrl } = require('@npmcli/redact') /* eslint-disable-next-line max-len */ diff --git a/node_modules/npm-registry-fetch/package.json b/node_modules/npm-registry-fetch/package.json index 88455a4971af0..4e450868a77f7 100644 --- a/node_modules/npm-registry-fetch/package.json +++ b/node_modules/npm-registry-fetch/package.json @@ -1,6 +1,6 @@ { "name": "npm-registry-fetch", - "version": "16.2.0", + "version": "16.2.1", "description": "Fetch-based http client for use with npm registry APIs", "main": "lib", "files": [ @@ -38,7 +38,7 @@ "minipass-json-stream": "^1.0.1", "minizlib": "^2.1.2", "npm-package-arg": "^11.0.0", - "proc-log": "^3.0.0" + "proc-log": "^4.0.0" }, "devDependencies": { "@npmcli/eslint-config": "^4.0.0", diff --git a/node_modules/pacote/lib/dir.js b/node_modules/pacote/lib/dir.js index 420afc5802cb2..6979462ea073e 100644 --- a/node_modules/pacote/lib/dir.js +++ b/node_modules/pacote/lib/dir.js @@ -41,16 +41,11 @@ class DirFetcher extends Fetcher { // but this function is *also* run when installing git deps const stdio = this.opts.foregroundScripts ? 'inherit' : 'pipe' - // hide the banner if silent opt is passed in, or if prepare running - // in the background. - const banner = this.opts.silent ? false : stdio === 'inherit' - return runScript({ pkg: mani, event: 'prepare', path: this.resolved, stdio, - banner, env: { npm_package_resolved: this.resolved, npm_package_integrity: this.integrity, diff --git a/node_modules/pacote/lib/fetcher.js b/node_modules/pacote/lib/fetcher.js index f961a45c7d346..287ec7956fc97 100644 --- a/node_modules/pacote/lib/fetcher.js +++ b/node_modules/pacote/lib/fetcher.js @@ -8,7 +8,7 @@ const ssri = require('ssri') const { promisify } = require('util') const { basename, dirname } = require('path') const tar = require('tar') -const log = require('proc-log') +const { log } = require('proc-log') const retry = require('promise-retry') const fs = require('fs/promises') const fsm = require('fs-minipass') diff --git a/node_modules/pacote/lib/git.js b/node_modules/pacote/lib/git.js index 5d24f72497ec9..533d83d3d8dd3 100644 --- a/node_modules/pacote/lib/git.js +++ b/node_modules/pacote/lib/git.js @@ -8,7 +8,7 @@ const pickManifest = require('npm-pick-manifest') const npa = require('npm-package-arg') const { Minipass } = require('minipass') const cacache = require('cacache') -const log = require('proc-log') +const { log } = require('proc-log') const npm = require('./util/npm.js') const _resolvedFromRepo = Symbol('_resolvedFromRepo') diff --git a/node_modules/pacote/package.json b/node_modules/pacote/package.json index 8fc0bb707f1e5..9fc3f2cfee960 100644 --- a/node_modules/pacote/package.json +++ b/node_modules/pacote/package.json @@ -1,6 +1,6 @@ { "name": "pacote", - "version": "17.0.6", + "version": "18.0.0", "description": "JavaScript package downloader", "author": "GitHub Inc.", "bin": { @@ -27,7 +27,7 @@ "devDependencies": { "@npmcli/arborist": "^7.1.0", "@npmcli/eslint-config": "^4.0.0", - "@npmcli/template-oss": "4.21.3", + "@npmcli/template-oss": "4.21.4", "hosted-git-info": "^7.0.0", "mutate-fs": "^2.1.1", "nock": "^13.2.4", @@ -47,7 +47,7 @@ "@npmcli/git": "^5.0.0", "@npmcli/installed-package-contents": "^2.0.1", "@npmcli/promise-spawn": "^7.0.0", - "@npmcli/run-script": "^7.0.0", + "@npmcli/run-script": "^8.0.0", "cacache": "^18.0.0", "fs-minipass": "^3.0.0", "minipass": "^7.0.2", @@ -55,7 +55,7 @@ "npm-packlist": "^8.0.0", "npm-pick-manifest": "^9.0.0", "npm-registry-fetch": "^16.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.0.0", "promise-retry": "^2.0.1", "read-package-json": "^7.0.0", "read-package-json-fast": "^3.0.0", @@ -72,7 +72,7 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.21.3", + "version": "4.21.4", "windowsCI": false, "publish": "true" } diff --git a/node_modules/proc-log/lib/index.js b/node_modules/proc-log/lib/index.js index 7c5dfad3b7ba3..2a049e6bd16b2 100644 --- a/node_modules/proc-log/lib/index.js +++ b/node_modules/proc-log/lib/index.js @@ -1,23 +1,62 @@ -// emits 'log' events on the process -const LEVELS = [ - 'notice', - 'error', - 'warn', - 'info', - 'verbose', - 'http', - 'silly', - 'pause', - 'resume', -] - -const log = level => (...args) => process.emit('log', level, ...args) - -const logger = {} -for (const level of LEVELS) { - logger[level] = log(level) +module.exports = { + output: { + LEVELS: [ + 'standard', + 'error', + 'buffer', + ], + standard: function (...args) { + return process.emit('output', 'standard', ...args) + }, + error: function (...args) { + return process.emit('output', 'error', ...args) + }, + buffer: function (...args) { + return process.emit('output', 'buffer', ...args) + }, + }, + log: { + LEVELS: [ + 'notice', + 'error', + 'warn', + 'info', + 'verbose', + 'http', + 'silly', + 'timing', + 'pause', + 'resume', + ], + error: function (...args) { + return process.emit('log', 'error', ...args) + }, + notice: function (...args) { + return process.emit('log', 'notice', ...args) + }, + warn: function (...args) { + return process.emit('log', 'warn', ...args) + }, + info: function (...args) { + return process.emit('log', 'info', ...args) + }, + verbose: function (...args) { + return process.emit('log', 'verbose', ...args) + }, + http: function (...args) { + return process.emit('log', 'http', ...args) + }, + silly: function (...args) { + return process.emit('log', 'silly', ...args) + }, + timing: function (...args) { + return process.emit('log', 'timing', ...args) + }, + pause: function (...args) { + return process.emit('log', 'pause', ...args) + }, + resume: function (...args) { + return process.emit('log', 'resume', ...args) + }, + }, } - -logger.LEVELS = LEVELS - -module.exports = logger diff --git a/node_modules/proc-log/package.json b/node_modules/proc-log/package.json index d335fa965ace5..405e3c433acbb 100644 --- a/node_modules/proc-log/package.json +++ b/node_modules/proc-log/package.json @@ -1,6 +1,6 @@ { "name": "proc-log", - "version": "3.0.0", + "version": "4.0.0", "files": [ "bin/", "lib/" @@ -18,14 +18,14 @@ "snap": "tap", "posttest": "npm run lint", "postsnap": "eslint index.js test/*.js --fix", - "lint": "eslint \"**/*.js\"", + "lint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"", "postlint": "template-oss-check", "lintfix": "npm run lint -- --fix", "template-oss-apply": "template-oss-apply --force" }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "4.5.1", + "@npmcli/eslint-config": "^4.0.0", + "@npmcli/template-oss": "4.21.3", "tap": "^16.0.1" }, "engines": { @@ -33,7 +33,8 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.5.1" + "version": "4.21.3", + "publish": true }, "tap": { "nyc-arg": [ diff --git a/node_modules/signal-exit/index.js b/node_modules/signal-exit/index.js deleted file mode 100644 index 93703f369265c..0000000000000 --- a/node_modules/signal-exit/index.js +++ /dev/null @@ -1,202 +0,0 @@ -// Note: since nyc uses this module to output coverage, any lines -// that are in the direct sync flow of nyc's outputCoverage are -// ignored, since we can never get coverage for them. -// grab a reference to node's real process object right away -var process = global.process - -const processOk = function (process) { - return process && - typeof process === 'object' && - typeof process.removeListener === 'function' && - typeof process.emit === 'function' && - typeof process.reallyExit === 'function' && - typeof process.listeners === 'function' && - typeof process.kill === 'function' && - typeof process.pid === 'number' && - typeof process.on === 'function' -} - -// some kind of non-node environment, just no-op -/* istanbul ignore if */ -if (!processOk(process)) { - module.exports = function () { - return function () {} - } -} else { - var assert = require('assert') - var signals = require('./signals.js') - var isWin = /^win/i.test(process.platform) - - var EE = require('events') - /* istanbul ignore if */ - if (typeof EE !== 'function') { - EE = EE.EventEmitter - } - - var emitter - if (process.__signal_exit_emitter__) { - emitter = process.__signal_exit_emitter__ - } else { - emitter = process.__signal_exit_emitter__ = new EE() - emitter.count = 0 - emitter.emitted = {} - } - - // Because this emitter is a global, we have to check to see if a - // previous version of this library failed to enable infinite listeners. - // I know what you're about to say. But literally everything about - // signal-exit is a compromise with evil. Get used to it. - if (!emitter.infinite) { - emitter.setMaxListeners(Infinity) - emitter.infinite = true - } - - module.exports = function (cb, opts) { - /* istanbul ignore if */ - if (!processOk(global.process)) { - return function () {} - } - assert.equal(typeof cb, 'function', 'a callback must be provided for exit handler') - - if (loaded === false) { - load() - } - - var ev = 'exit' - if (opts && opts.alwaysLast) { - ev = 'afterexit' - } - - var remove = function () { - emitter.removeListener(ev, cb) - if (emitter.listeners('exit').length === 0 && - emitter.listeners('afterexit').length === 0) { - unload() - } - } - emitter.on(ev, cb) - - return remove - } - - var unload = function unload () { - if (!loaded || !processOk(global.process)) { - return - } - loaded = false - - signals.forEach(function (sig) { - try { - process.removeListener(sig, sigListeners[sig]) - } catch (er) {} - }) - process.emit = originalProcessEmit - process.reallyExit = originalProcessReallyExit - emitter.count -= 1 - } - module.exports.unload = unload - - var emit = function emit (event, code, signal) { - /* istanbul ignore if */ - if (emitter.emitted[event]) { - return - } - emitter.emitted[event] = true - emitter.emit(event, code, signal) - } - - // { : , ... } - var sigListeners = {} - signals.forEach(function (sig) { - sigListeners[sig] = function listener () { - /* istanbul ignore if */ - if (!processOk(global.process)) { - return - } - // If there are no other listeners, an exit is coming! - // Simplest way: remove us and then re-send the signal. - // We know that this will kill the process, so we can - // safely emit now. - var listeners = process.listeners(sig) - if (listeners.length === emitter.count) { - unload() - emit('exit', null, sig) - /* istanbul ignore next */ - emit('afterexit', null, sig) - /* istanbul ignore next */ - if (isWin && sig === 'SIGHUP') { - // "SIGHUP" throws an `ENOSYS` error on Windows, - // so use a supported signal instead - sig = 'SIGINT' - } - /* istanbul ignore next */ - process.kill(process.pid, sig) - } - } - }) - - module.exports.signals = function () { - return signals - } - - var loaded = false - - var load = function load () { - if (loaded || !processOk(global.process)) { - return - } - loaded = true - - // This is the number of onSignalExit's that are in play. - // It's important so that we can count the correct number of - // listeners on signals, and don't wait for the other one to - // handle it instead of us. - emitter.count += 1 - - signals = signals.filter(function (sig) { - try { - process.on(sig, sigListeners[sig]) - return true - } catch (er) { - return false - } - }) - - process.emit = processEmit - process.reallyExit = processReallyExit - } - module.exports.load = load - - var originalProcessReallyExit = process.reallyExit - var processReallyExit = function processReallyExit (code) { - /* istanbul ignore if */ - if (!processOk(global.process)) { - return - } - process.exitCode = code || /* istanbul ignore next */ 0 - emit('exit', process.exitCode, null) - /* istanbul ignore next */ - emit('afterexit', process.exitCode, null) - /* istanbul ignore next */ - originalProcessReallyExit.call(process, process.exitCode) - } - - var originalProcessEmit = process.emit - var processEmit = function processEmit (ev, arg) { - if (ev === 'exit' && processOk(global.process)) { - /* istanbul ignore else */ - if (arg !== undefined) { - process.exitCode = arg - } - var ret = originalProcessEmit.apply(this, arguments) - /* istanbul ignore next */ - emit('exit', process.exitCode, null) - /* istanbul ignore next */ - emit('afterexit', process.exitCode, null) - /* istanbul ignore next */ - return ret - } else { - return originalProcessEmit.apply(this, arguments) - } - } -} diff --git a/node_modules/signal-exit/signals.js b/node_modules/signal-exit/signals.js deleted file mode 100644 index 3bd67a8a554e3..0000000000000 --- a/node_modules/signal-exit/signals.js +++ /dev/null @@ -1,53 +0,0 @@ -// This is not the set of all possible signals. -// -// It IS, however, the set of all signals that trigger -// an exit on either Linux or BSD systems. Linux is a -// superset of the signal names supported on BSD, and -// the unknown signals just fail to register, so we can -// catch that easily enough. -// -// Don't bother with SIGKILL. It's uncatchable, which -// means that we can't fire any callbacks anyway. -// -// If a user does happen to register a handler on a non- -// fatal signal like SIGWINCH or something, and then -// exit, it'll end up firing `process.emit('exit')`, so -// the handler will be fired anyway. -// -// SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised -// artificially, inherently leave the process in a -// state from which it is not safe to try and enter JS -// listeners. -module.exports = [ - 'SIGABRT', - 'SIGALRM', - 'SIGHUP', - 'SIGINT', - 'SIGTERM' -] - -if (process.platform !== 'win32') { - module.exports.push( - 'SIGVTALRM', - 'SIGXCPU', - 'SIGXFSZ', - 'SIGUSR2', - 'SIGTRAP', - 'SIGSYS', - 'SIGQUIT', - 'SIGIOT' - // should detect profiler and enable/disable accordingly. - // see #21 - // 'SIGPROF' - ) -} - -if (process.platform === 'linux') { - module.exports.push( - 'SIGIO', - 'SIGPOLL', - 'SIGPWR', - 'SIGSTKFLT', - 'SIGUNUSED' - ) -} diff --git a/package-lock.json b/package-lock.json index b3d627b42b0fb..a0dee643680fd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -94,10 +94,10 @@ "@npmcli/config": "^8.0.2", "@npmcli/fs": "^3.1.0", "@npmcli/map-workspaces": "^3.0.6", - "@npmcli/package-json": "^5.0.2", + "@npmcli/package-json": "^5.0.3", "@npmcli/promise-spawn": "^7.0.1", "@npmcli/redact": "^1.1.0", - "@npmcli/run-script": "^7.0.4", + "@npmcli/run-script": "^8.0.0", "@sigstore/tuf": "^2.3.2", "abbrev": "^2.0.0", "archy": "~1.0.0", @@ -137,15 +137,15 @@ "normalize-package-data": "^6.0.0", "npm-audit-report": "^5.0.0", "npm-install-checks": "^6.3.0", - "npm-package-arg": "^11.0.1", + "npm-package-arg": "^11.0.2", "npm-pick-manifest": "^9.0.0", - "npm-profile": "^9.0.0", - "npm-registry-fetch": "^16.2.0", + "npm-profile": "^9.0.1", + "npm-registry-fetch": "^16.2.1", "npm-user-validate": "^2.0.0", "p-map": "^4.0.0", - "pacote": "^17.0.6", + "pacote": "^18.0.0", "parse-conflict-json": "^3.0.1", - "proc-log": "^3.0.0", + "proc-log": "^4.0.0", "proggy": "^2.0.0", "qrcode-terminal": "^0.12.0", "read": "^3.0.1", @@ -168,7 +168,7 @@ "devDependencies": { "@npmcli/docs": "^1.0.0", "@npmcli/eslint-config": "^4.0.2", - "@npmcli/git": "^5.0.5", + "@npmcli/git": "^5.0.6", "@npmcli/mock-globals": "^1.0.0", "@npmcli/mock-registry": "^1.0.0", "@npmcli/template-oss": "4.21.3", @@ -238,8 +238,8 @@ "@npmcli/template-oss": "4.21.3", "json-stringify-safe": "^5.0.1", "nock": "^13.3.3", - "npm-package-arg": "^11.0.1", - "pacote": "^17.0.4", + "npm-package-arg": "^11.0.2", + "pacote": "^18.0.0", "tap": "^16.3.8" }, "engines": { @@ -1701,15 +1701,15 @@ } }, "node_modules/@npmcli/git": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-5.0.5.tgz", - "integrity": "sha512-x8hXItC8OFOwdgERzRIxg0ic1lQqW6kSZFFQtZTCNYOeGb9UqzVcod02TYljI9UBl4RtfcyQ0A7ygmcGFvEqWw==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-5.0.6.tgz", + "integrity": "sha512-4x/182sKXmQkf0EtXxT26GEsaOATpD7WVtza5hrYivWZeo6QefC6xq9KAXrnjtFKBZ4rZwR7aX/zClYYXgtwLw==", "inBundle": true, "dependencies": { "@npmcli/promise-spawn": "^7.0.0", "lru-cache": "^10.0.1", "npm-pick-manifest": "^9.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.0.0", "promise-inflight": "^1.0.1", "promise-retry": "^2.0.1", "semver": "^7.3.5", @@ -1751,13 +1751,13 @@ } }, "node_modules/@npmcli/metavuln-calculator": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/metavuln-calculator/-/metavuln-calculator-7.0.0.tgz", - "integrity": "sha512-Pw0tyX02VkpqlIQlG2TeiJNsdrecYeUU0ubZZa9pi3N37GCsxI+en43u4hYFdq+eSx1A9a9vwFAUyqEtKFsbHQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/metavuln-calculator/-/metavuln-calculator-7.0.1.tgz", + "integrity": "sha512-665lHkHWufnWA3i6H1dJ/EDvK0s0JHrECuBLv/SdLsB53e4v70twsK1baDxatn1pZp7g11HhH80upkfgsBAFFg==", "dependencies": { "cacache": "^18.0.0", "json-parse-even-better-errors": "^3.0.0", - "pacote": "^17.0.0", + "pacote": "^18.0.0", "semver": "^7.3.5" }, "engines": { @@ -1805,9 +1805,9 @@ } }, "node_modules/@npmcli/package-json": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-5.0.2.tgz", - "integrity": "sha512-LmW+tueGSK+FCM3OpcKtwKKo3igpefh6HHiw23sGd8OdJ8l0GrfGfVdGOFVtJRMaXVnvI1RUdEPlB9VUln5Wbw==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-5.0.3.tgz", + "integrity": "sha512-cgsjCvld2wMqkUqvY+SZI+1ZJ7umGBYc9IAKfqJRKJCcs7hCQYxScUgdsyrRINk3VmdCYf9TXiLBHQ6ECTxhtg==", "inBundle": true, "dependencies": { "@npmcli/git": "^5.0.0", @@ -1815,7 +1815,7 @@ "hosted-git-info": "^7.0.0", "json-parse-even-better-errors": "^3.0.0", "normalize-package-data": "^6.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.0.0", "semver": "^7.5.3" }, "engines": { @@ -1855,15 +1855,16 @@ } }, "node_modules/@npmcli/run-script": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-7.0.4.tgz", - "integrity": "sha512-9ApYM/3+rBt9V80aYg6tZfzj3UWdiYyCt7gJUD1VJKvWF5nwKDSICXbYIQbspFTq6TOpbsEtIC0LArB8d9PFmg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-8.0.0.tgz", + "integrity": "sha512-5noc+eCQmX1W9nlFUe65n5MIteikd3vOA2sEPdXtlUv68KWyHNFZnT/LDRXu/E4nZ5yxjciP30pADr/GQ97W1w==", "inBundle": true, "dependencies": { "@npmcli/node-gyp": "^3.0.0", "@npmcli/package-json": "^5.0.0", "@npmcli/promise-spawn": "^7.0.0", "node-gyp": "^10.0.0", + "proc-log": "^4.0.0", "which": "^4.0.0" }, "engines": { @@ -1919,6 +1920,15 @@ "node": "^18.17.0 || >=20.5.0" } }, + "node_modules/@npmcli/template-oss/node_modules/proc-log": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz", + "integrity": "sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/@octokit/auth-token": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.4.tgz", @@ -8249,6 +8259,15 @@ "node": ">=8" } }, + "node_modules/licensee/node_modules/proc-log": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz", + "integrity": "sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/licensee/node_modules/promise-call-limit": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/promise-call-limit/-/promise-call-limit-1.0.2.tgz", @@ -9943,6 +9962,15 @@ "node": "^16.14.0 || >=18.0.0" } }, + "node_modules/node-gyp/node_modules/proc-log": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz", + "integrity": "sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==", + "inBundle": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/node-html-parser": { "version": "6.1.13", "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-6.1.13.tgz", @@ -10059,13 +10087,13 @@ } }, "node_modules/npm-package-arg": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.1.tgz", - "integrity": "sha512-M7s1BD4NxdAvBKUPqqRW957Xwcl/4Zvo8Aj+ANrzvIPzGJZElrH7Z//rSaec2ORcND6FHHLnZeY8qgTpXDMFQQ==", + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.2.tgz", + "integrity": "sha512-IGN0IAwmhDJwy13Wc8k+4PEbTPhpJnMtfR53ZbOyjkvmEcLS4nCwp6mvMWjS5sUjeiW3mpx6cHmuhKEu9XmcQw==", "inBundle": true, "dependencies": { "hosted-git-info": "^7.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.0.0", "semver": "^7.3.5", "validate-npm-package-name": "^5.0.0" }, @@ -10101,22 +10129,22 @@ } }, "node_modules/npm-profile": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/npm-profile/-/npm-profile-9.0.0.tgz", - "integrity": "sha512-qv43ixsJ7vndzfxD3XsPNu1Njck6dhO7q1efksTo+0DiOQysKSOsIhK/qDD1/xO2o+2jDOA4Rv/zOJ9KQFs9nw==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/npm-profile/-/npm-profile-9.0.1.tgz", + "integrity": "sha512-9o6dw5eu3tiqX1XFOXjznO73Jzin48Oyo9qAhfaEHXzeZHXpdzgDmzWruWk7uJsu5GMIsigx5hva5rB5NhfSWw==", "inBundle": true, "dependencies": { "npm-registry-fetch": "^16.0.0", - "proc-log": "^3.0.0" + "proc-log": "^4.0.0" }, "engines": { "node": "^16.14.0 || >=18.0.0" } }, "node_modules/npm-registry-fetch": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-16.2.0.tgz", - "integrity": "sha512-zVH+G0q1O2hqgQBUvQ2LWp6ujr6VJAeDnmWxqiMlCguvLexEzBnuQIwC70r04vcvCMAcYEIpA/rO9YyVi+fmJQ==", + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-16.2.1.tgz", + "integrity": "sha512-8l+7jxhim55S85fjiDGJ1rZXBWGtRLi1OSb4Z3BPLObPuIaeKRlPRiYMSHU4/81ck3t71Z+UwDDl47gcpmfQQA==", "inBundle": true, "dependencies": { "@npmcli/redact": "^1.1.0", @@ -10126,7 +10154,7 @@ "minipass-json-stream": "^1.0.1", "minizlib": "^2.1.2", "npm-package-arg": "^11.0.0", - "proc-log": "^3.0.0" + "proc-log": "^4.0.0" }, "engines": { "node": "^16.14.0 || >=18.0.0" @@ -10660,15 +10688,15 @@ } }, "node_modules/pacote": { - "version": "17.0.6", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-17.0.6.tgz", - "integrity": "sha512-cJKrW21VRE8vVTRskJo78c/RCvwJCn1f4qgfxL4w77SOWrTCRcmfkYHlHtS0gqpgjv3zhXflRtgsrUCX5xwNnQ==", + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-18.0.0.tgz", + "integrity": "sha512-ma7uVt/q3Sb3XbLwUjOeClz+7feHjMOFegHn5whw++x+GzikZkAq/2auklSbRuy6EI2iJh1/ZqCpVaUcxRaeqQ==", "inBundle": true, "dependencies": { "@npmcli/git": "^5.0.0", "@npmcli/installed-package-contents": "^2.0.1", "@npmcli/promise-spawn": "^7.0.0", - "@npmcli/run-script": "^7.0.0", + "@npmcli/run-script": "^8.0.0", "cacache": "^18.0.0", "fs-minipass": "^3.0.0", "minipass": "^7.0.2", @@ -10676,7 +10704,7 @@ "npm-packlist": "^8.0.0", "npm-pick-manifest": "^9.0.0", "npm-registry-fetch": "^16.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.0.0", "promise-retry": "^2.0.1", "read-package-json": "^7.0.0", "read-package-json-fast": "^3.0.0", @@ -10944,9 +10972,9 @@ } }, "node_modules/proc-log": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz", - "integrity": "sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.0.0.tgz", + "integrity": "sha512-v1lzmYxGDs2+OZnmYtYZK3DG8zogt+CbQ+o/iqqtTfpyCmGWulCTEQu5GIbivf7OjgIkH2Nr8SH8UxAGugZNbg==", "inBundle": true, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" @@ -16133,13 +16161,13 @@ "@npmcli/fs": "^3.1.0", "@npmcli/installed-package-contents": "^2.0.2", "@npmcli/map-workspaces": "^3.0.2", - "@npmcli/metavuln-calculator": "^7.0.0", + "@npmcli/metavuln-calculator": "^7.0.1", "@npmcli/name-from-folder": "^2.0.0", "@npmcli/node-gyp": "^3.0.0", - "@npmcli/package-json": "^5.0.0", + "@npmcli/package-json": "^5.0.3", "@npmcli/query": "^3.1.0", "@npmcli/redact": "^1.1.0", - "@npmcli/run-script": "^7.0.2", + "@npmcli/run-script": "^8.0.0", "bin-links": "^4.0.1", "cacache": "^18.0.0", "common-ancestor-path": "^1.0.1", @@ -16149,12 +16177,12 @@ "minimatch": "^9.0.4", "nopt": "^7.0.0", "npm-install-checks": "^6.2.0", - "npm-package-arg": "^11.0.1", + "npm-package-arg": "^11.0.2", "npm-pick-manifest": "^9.0.0", - "npm-registry-fetch": "^16.2.0", - "pacote": "^17.0.4", + "npm-registry-fetch": "^16.2.1", + "pacote": "^18.0.0", "parse-conflict-json": "^3.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.0.0", "proggy": "^2.0.0", "promise-all-reject-late": "^1.0.0", "promise-call-limit": "^3.0.1", @@ -16190,7 +16218,7 @@ "ci-info": "^4.0.0", "ini": "^4.1.2", "nopt": "^7.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.0.0", "read-package-json-fast": "^3.0.2", "semver": "^7.3.5", "walk-up-path": "^3.0.1" @@ -16209,8 +16237,8 @@ "version": "8.0.3", "license": "ISC", "dependencies": { - "npm-package-arg": "^11.0.1", - "npm-registry-fetch": "^16.2.0" + "npm-package-arg": "^11.0.2", + "npm-registry-fetch": "^16.2.1" }, "devDependencies": { "@npmcli/eslint-config": "^4.0.0", @@ -16233,8 +16261,8 @@ "binary-extensions": "^2.3.0", "diff": "^5.1.0", "minimatch": "^9.0.4", - "npm-package-arg": "^11.0.1", - "pacote": "^17.0.4", + "npm-package-arg": "^11.0.2", + "pacote": "^18.0.0", "tar": "^6.2.1" }, "devDependencies": { @@ -16251,11 +16279,11 @@ "license": "ISC", "dependencies": { "@npmcli/arborist": "^7.2.1", - "@npmcli/run-script": "^7.0.2", + "@npmcli/run-script": "^8.0.0", "ci-info": "^4.0.0", - "npm-package-arg": "^11.0.1", - "pacote": "^17.0.4", - "proc-log": "^3.0.0", + "npm-package-arg": "^11.0.2", + "pacote": "^18.0.0", + "proc-log": "^4.0.0", "read": "^3.0.1", "read-package-json-fast": "^3.0.2", "semver": "^7.3.7", @@ -16295,7 +16323,7 @@ "license": "ISC", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^16.2.0" + "npm-registry-fetch": "^16.2.1" }, "devDependencies": { "@npmcli/eslint-config": "^4.0.0", @@ -16312,7 +16340,7 @@ "license": "ISC", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^16.2.0" + "npm-registry-fetch": "^16.2.1" }, "devDependencies": { "@npmcli/eslint-config": "^4.0.0", @@ -16330,9 +16358,9 @@ "license": "ISC", "dependencies": { "@npmcli/arborist": "^7.2.1", - "@npmcli/run-script": "^7.0.2", - "npm-package-arg": "^11.0.1", - "pacote": "^17.0.4" + "@npmcli/run-script": "^8.0.0", + "npm-package-arg": "^11.0.2", + "pacote": "^18.0.0" }, "devDependencies": { "@npmcli/eslint-config": "^4.0.0", @@ -16351,9 +16379,9 @@ "dependencies": { "ci-info": "^4.0.0", "normalize-package-data": "^6.0.0", - "npm-package-arg": "^11.0.1", - "npm-registry-fetch": "^16.2.0", - "proc-log": "^3.0.0", + "npm-package-arg": "^11.0.2", + "npm-registry-fetch": "^16.2.1", + "proc-log": "^4.0.0", "semver": "^7.3.7", "sigstore": "^2.2.0", "ssri": "^10.0.5" @@ -16374,7 +16402,7 @@ "version": "7.0.2", "license": "ISC", "dependencies": { - "npm-registry-fetch": "^16.2.0" + "npm-registry-fetch": "^16.2.1" }, "devDependencies": { "@npmcli/eslint-config": "^4.0.0", @@ -16391,7 +16419,7 @@ "license": "ISC", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^16.2.0" + "npm-registry-fetch": "^16.2.1" }, "devDependencies": { "@npmcli/eslint-config": "^4.0.0", @@ -16407,10 +16435,10 @@ "version": "5.0.2", "license": "ISC", "dependencies": { - "@npmcli/git": "^5.0.3", - "@npmcli/run-script": "^7.0.2", + "@npmcli/git": "^5.0.6", + "@npmcli/run-script": "^8.0.0", "json-parse-even-better-errors": "^3.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.0.0", "semver": "^7.3.7" }, "devDependencies": { diff --git a/package.json b/package.json index 90b6695c8973f..19198f3e3449d 100644 --- a/package.json +++ b/package.json @@ -56,10 +56,10 @@ "@npmcli/config": "^8.0.2", "@npmcli/fs": "^3.1.0", "@npmcli/map-workspaces": "^3.0.6", - "@npmcli/package-json": "^5.0.2", + "@npmcli/package-json": "^5.0.3", "@npmcli/promise-spawn": "^7.0.1", "@npmcli/redact": "^1.1.0", - "@npmcli/run-script": "^7.0.4", + "@npmcli/run-script": "^8.0.0", "@sigstore/tuf": "^2.3.2", "abbrev": "^2.0.0", "archy": "~1.0.0", @@ -99,15 +99,15 @@ "normalize-package-data": "^6.0.0", "npm-audit-report": "^5.0.0", "npm-install-checks": "^6.3.0", - "npm-package-arg": "^11.0.1", + "npm-package-arg": "^11.0.2", "npm-pick-manifest": "^9.0.0", - "npm-profile": "^9.0.0", - "npm-registry-fetch": "^16.2.0", + "npm-profile": "^9.0.1", + "npm-registry-fetch": "^16.2.1", "npm-user-validate": "^2.0.0", "p-map": "^4.0.0", - "pacote": "^17.0.6", + "pacote": "^18.0.0", "parse-conflict-json": "^3.0.1", - "proc-log": "^3.0.0", + "proc-log": "^4.0.0", "proggy": "^2.0.0", "qrcode-terminal": "^0.12.0", "read": "^3.0.1", @@ -199,7 +199,7 @@ "devDependencies": { "@npmcli/docs": "^1.0.0", "@npmcli/eslint-config": "^4.0.2", - "@npmcli/git": "^5.0.5", + "@npmcli/git": "^5.0.6", "@npmcli/mock-globals": "^1.0.0", "@npmcli/mock-registry": "^1.0.0", "@npmcli/template-oss": "4.21.3", diff --git a/scripts/create-node-pr.js b/scripts/create-node-pr.js index 3509512a305ad..b0b4856c0192f 100644 --- a/scripts/create-node-pr.js +++ b/scripts/create-node-pr.js @@ -3,7 +3,7 @@ const fsp = require('fs/promises') const hgi = require('hosted-git-info') const semver = require('semver') const pacote = require('pacote') -const log = require('proc-log') +const { log } = require('proc-log') const tar = require('tar') const { cp, withTempDir } = require('@npmcli/fs') const { CWD, run, spawn, git, fs, gh } = require('./util.js') diff --git a/scripts/dependency-graph.js b/scripts/dependency-graph.js index 8c5f9af50c6a2..6b92c65296f0a 100644 --- a/scripts/dependency-graph.js +++ b/scripts/dependency-graph.js @@ -2,7 +2,7 @@ const Arborist = require('@npmcli/arborist') const os = require('os') const { readFileSync } = require('fs') const { join } = require('path') -const log = require('proc-log') +const { log } = require('proc-log') const { run, CWD, pkg, fs, EOL } = require('./util.js') // Generates our dependency graph documents in DEPENDENCIES.md. diff --git a/scripts/publish.js b/scripts/publish.js index 12f77625fc69e..f27b07fb8e658 100644 --- a/scripts/publish.js +++ b/scripts/publish.js @@ -1,5 +1,5 @@ const semver = require('semver') -const log = require('proc-log') +const { log } = require('proc-log') const pacote = require('pacote') const { read } = require('read') const Table = require('cli-table3') diff --git a/scripts/util.js b/scripts/util.js index b2e9add674714..c842bd26004f3 100644 --- a/scripts/util.js +++ b/scripts/util.js @@ -1,7 +1,7 @@ const fsp = require('fs/promises') const { resolve, join, relative } = require('path') const { formatWithOptions } = require('util') -const log = require('proc-log') +const { log } = require('proc-log') const nopt = require('nopt') const npmGit = require('@npmcli/git') const promiseSpawn = require('@npmcli/promise-spawn') diff --git a/test/fixtures/mock-logs.js b/test/fixtures/mock-logs.js index 3f25737ef4501..c29928130088c 100644 --- a/test/fixtures/mock-logs.js +++ b/test/fixtures/mock-logs.js @@ -1,14 +1,13 @@ -const { LEVELS: PROC_LOC_LEVELS } = require('proc-log') +const { log: { LEVELS } } = require('proc-log') const { stripVTControlCharacters: stripAnsi } = require('util') -const levels = ['timing', ...PROC_LOC_LEVELS] const labels = new Map([ ['error', 'ERR!'], ['warn', 'WARN'], ['verbose', 'verb'], ['silly', 'sill'], ].reduce((acc, v) => acc.concat([v, v.slice(0).reverse()]), [])) -const logPrefix = new RegExp(`^npm (${levels.map(l => labels.get(l) ?? l).join('|')})\\s`) +const logPrefix = new RegExp(`^npm (${LEVELS.map(l => labels.get(l) ?? l).join('|')})\\s`) const isLog = (str) => logPrefix.test(stripAnsi(str)) // We only strip trailing newlines since some output will @@ -35,7 +34,7 @@ module.exports = () => { const levelLogs = [] const logs = Object.defineProperties([], { ...logsByTitle(levelLogs), - ...levels.reduce((acc, level) => { + ...LEVELS.reduce((acc, level) => { acc[level] = { get () { const byLevel = levelLogs.filter((l) => l.level === level) diff --git a/test/lib/commands/ci.js b/test/lib/commands/ci.js index 681ccad7d87a7..6ab9662fc8be5 100644 --- a/test/lib/commands/ci.js +++ b/test/lib/commands/ci.js @@ -164,7 +164,6 @@ t.test('lifecycle scripts', async t => { }, mocks: { '@npmcli/run-script': (opts) => { - t.ok(opts.banner) scripts.push(opts.event) }, }, diff --git a/test/lib/commands/pack.js b/test/lib/commands/pack.js index 93d4da22d31c2..067e84a0980e0 100644 --- a/test/lib/commands/pack.js +++ b/test/lib/commands/pack.js @@ -121,28 +121,17 @@ t.test('foreground-scripts defaults to true', async t => { config: { 'dry-run': true }, }) - /* eslint no-console: 0 */ - // TODO: replace this with `const results = t.intercept(console, 'log')` - const log = console.log - t.teardown(() => { - console.log = log - }) - const caughtLogs = [] - console.log = (...args) => { - caughtLogs.push(args) - } - // end TODO - await npm.exec('pack', []) const filename = 'test-fg-scripts-0.0.0.tgz' - t.same( - caughtLogs, + t.strictSame( + outputs, [ - ['\n> test-fg-scripts@0.0.0 prepack\n> echo prepack!\n'], - ['\n> test-fg-scripts@0.0.0 postpack\n> echo postpack!\n'], + '\n> test-fg-scripts@0.0.0 prepack\n> echo prepack!\n', + '\n> test-fg-scripts@0.0.0 postpack\n> echo postpack!\n', + filename, ], - 'prepack and postpack log to stdout') - t.strictSame(outputs, [filename]) + 'prepack and postpack log to stdout' + ) t.matchSnapshot(logs.notice, 'logs pack contents') t.throws(() => fs.statSync(path.resolve(npm.prefix, filename))) }) @@ -163,25 +152,10 @@ t.test('foreground-scripts can still be set to false', async t => { config: { 'dry-run': true, 'foreground-scripts': false }, }) - /* eslint no-console: 0 */ - // TODO: replace this with `const results = t.intercept(console, 'log')` - const log = console.log - t.teardown(() => { - console.log = log - }) - const caughtLogs = [] - console.log = (...args) => { - caughtLogs.push(args) - } - // end TODO - await npm.exec('pack', []) const filename = 'test-fg-scripts-0.0.0.tgz' - t.same( - caughtLogs, - [], - 'prepack and postpack do not log to stdout') - t.strictSame(outputs, [filename]) + + t.strictSame(outputs, [filename], 'prepack and postpack do not log to stdout') t.matchSnapshot(logs.notice, 'logs pack contents') t.throws(() => fs.statSync(path.resolve(npm.prefix, filename))) }) diff --git a/test/lib/commands/publish.js b/test/lib/commands/publish.js index 751cd97d8acf6..85a66d88b8b34 100644 --- a/test/lib/commands/publish.js +++ b/test/lib/commands/publish.js @@ -83,6 +83,8 @@ t.test('re-loads publishConfig.registry if added during script process', async t const { joinedOutput, npm } = await loadMockNpm(t, { config: { [`${alternateRegistry.slice(6)}/:_authToken`]: 'test-other-token', + // Keep output from leaking into tap logs for readability + 'foreground-scripts': false, }, prefixDir: { 'package.json': JSON.stringify({ @@ -136,6 +138,8 @@ t.test('prioritize CLI flags over publishConfig', async t => { const { joinedOutput, npm } = await loadMockNpm(t, { config: { [`${alternateRegistry.slice(6)}/:_authToken`]: 'test-other-token', + // Keep output from leaking into tap logs for readability + 'foreground-scripts': false, }, prefixDir: { 'package.json': JSON.stringify({ @@ -220,7 +224,7 @@ t.test('dry-run', async t => { }) t.test('foreground-scripts defaults to true', async t => { - const { joinedOutput, npm, logs } = await loadMockNpm(t, { + const { outputs, npm, logs } = await loadMockNpm(t, { config: { 'dry-run': true, ...auth, @@ -238,33 +242,22 @@ t.test('foreground-scripts defaults to true', async t => { }, }) - /* eslint no-console: 0 */ - // TODO: replace this with `const results = t.intercept(console, 'log')` - const log = console.log - t.teardown(() => { - console.log = log - }) - const caughtLogs = [] - console.log = (...args) => { - caughtLogs.push(args) - } - // end TODO - await npm.exec('publish', []) - t.equal(joinedOutput(), `+ test-fg-scripts@0.0.0`) + t.matchSnapshot(logs.notice) - t.same( - caughtLogs, + t.strictSame( + outputs, [ - ['\n> test-fg-scripts@0.0.0 prepack\n> echo prepack!\n'], - ['\n> test-fg-scripts@0.0.0 postpack\n> echo postpack!\n'], + '\n> test-fg-scripts@0.0.0 prepack\n> echo prepack!\n', + '\n> test-fg-scripts@0.0.0 postpack\n> echo postpack!\n', + `+ test-fg-scripts@0.0.0`, ], 'prepack and postpack log to stdout') }) t.test('foreground-scripts can still be set to false', async t => { - const { joinedOutput, npm, logs } = await loadMockNpm(t, { + const { outputs, npm, logs } = await loadMockNpm(t, { config: { 'dry-run': true, 'foreground-scripts': false, @@ -283,25 +276,13 @@ t.test('foreground-scripts can still be set to false', async t => { }, }) - /* eslint no-console: 0 */ - // TODO: replace this with `const results = t.intercept(console, 'log')` - const log = console.log - t.teardown(() => { - console.log = log - }) - const caughtLogs = [] - console.log = (...args) => { - caughtLogs.push(args) - } - // end TODO - await npm.exec('publish', []) - t.equal(joinedOutput(), `+ test-fg-scripts@0.0.0`) + t.matchSnapshot(logs.notice) - t.same( - caughtLogs, - [], + t.strictSame( + outputs, + [`+ test-fg-scripts@0.0.0`], 'prepack and postpack do not log to stdout') }) @@ -871,6 +852,7 @@ t.test('manifest', async t => { const { npm } = await loadMockNpm(t, { config: { ...auth, + 'foreground-scripts': false, }, chdir: () => root, mocks: { diff --git a/test/lib/commands/run-script.js b/test/lib/commands/run-script.js index a110037c8031c..c5bb2b488c053 100644 --- a/test/lib/commands/run-script.js +++ b/test/lib/commands/run-script.js @@ -347,7 +347,6 @@ t.test('skip pre/post hooks when using ignoreScripts', async t => { env: 'env', }, }, - banner: true, event: 'env', }, ]) @@ -388,7 +387,6 @@ t.test('run silent', async t => { }, }, event: 'env', - banner: false, }, { event: 'postenv', diff --git a/test/lib/npm.js b/test/lib/npm.js index ad776fc65b573..59400ce8da9f1 100644 --- a/test/lib/npm.js +++ b/test/lib/npm.js @@ -476,15 +476,6 @@ t.test('timings', async t => { } }) -t.test('outputs cleaned messages', async t => { - const { outputs, outputErrors, npm } = await loadMockNpm(t) - npm.output('hello\x00world') - npm.outputError('error\x00world') - - t.match(outputs, ['hello^@world']) - t.match(outputErrors, ['error^@world']) -}) - t.test('aliases and typos', async t => { const { Npm } = await loadMockNpm(t, { init: false }) t.throws(() => Npm.cmd('thisisnotacommand'), { code: 'EUNKNOWNCOMMAND' }) diff --git a/test/lib/utils/display.js b/test/lib/utils/display.js index 9f6b77259feba..31ea7bbed8add 100644 --- a/test/lib/utils/display.js +++ b/test/lib/utils/display.js @@ -1,49 +1,77 @@ const t = require('tap') const tmock = require('../../fixtures/tmock') const mockLogs = require('../../fixtures/mock-logs') +const mockGlobals = require('@npmcli/mock-globals') const { inspect } = require('util') const mockDisplay = async (t, { mocks, load } = {}) => { const { Chalk } = await import('chalk') - const log = require('proc-log') + const { log, output } = require('proc-log') + const logs = mockLogs() + const Display = tmock(t, '{LIB}/utils/display', mocks) const display = new Display(logs.streams) - display.load({ + const displayLoad = (opts) => display.load({ loglevel: 'silly', - chalk: new Chalk({ level: 0 }), + stderrChalk: new Chalk({ level: 0 }), + stderrColor: false, heading: 'npm', - ...load, + ...opts, }) + + if (load !== false) { + displayLoad(load) + } + t.teardown(() => display.off()) return { display, + output, log, + displayLoad, ...logs.logs, } } t.test('can log cleanly', async (t) => { + const { log, logs } = await mockDisplay(t) + + log.error('', 'test\x00message') + t.match(logs.error, ['test^@message']) +}) + +t.test('can handle special eresolves', async (t) => { const explains = [] const { log, logs } = await mockDisplay(t, { mocks: { '{LIB}/utils/explain-eresolve.js': { explain: (...args) => { explains.push(args) - return 'explanation' + return 'EXPLAIN' }, }, }, }) - log.error('', 'test\x00message') - t.match(logs.error, ['test^@message']) - log.warn('ERESOLVE', 'hello', { some: 'object' }) - t.match(logs.warn, ['ERESOLVE hello']) + t.strictSame(logs.warn, ['ERESOLVE hello', 'EXPLAIN']) t.match(explains, [[{ some: 'object' }, Function, 2]]) }) +t.test('can buffer output when paused', async t => { + const { displayLoad, outputs, output } = await mockDisplay(t, { + load: false, + }) + + output.buffer('Message 1') + output.standard('Message 2') + + t.strictSame(outputs, []) + displayLoad() + t.strictSame(outputs, ['Message 1', 'Message 2']) +}) + t.test('can do progress', async (t) => { const { log, logs } = await mockDisplay(t, { load: { @@ -58,24 +86,38 @@ t.test('can do progress', async (t) => { }) t.test('handles log throwing', async (t) => { - const { log, logs } = await mockDisplay(t, { - mocks: { - '{LIB}/utils/explain-eresolve.js': { - explain: () => { - throw new Error('explain') - }, - }, - }, - }) + class ThrowInspect { + #crashes = 0; - log.warn('ERESOLVE', 'hello', { some: 'object' }) + [inspect.custom] () { + throw new Error(`Crashed ${++this.#crashes}`) + } + } + + const errors = [] + mockGlobals(t, { 'console.error': (...msg) => errors.push(msg) }) + + const { log, logs } = await mockDisplay(t) + + log.error('woah', new ThrowInspect()) + + t.strictSame(logs.error, []) + t.equal(errors.length, 1) + t.match(errors[0], [ + 'attempt to log crashed', + new Error('Crashed 1'), + new Error('Crashed 2'), + ]) +}) - t.match(logs.verbose[0], - `attempt to log crashed ERESOLVE hello { some: 'object' } Error: explain`) +t.test('incorrect levels', async t => { + const { outputs } = await mockDisplay(t) + process.emit('output', 'not a real level') + t.strictSame(outputs, [], 'output is ignored') }) t.test('Display.clean', async (t) => { - const { display, outputs, clearOutput } = await mockDisplay(t) + const { output, outputs, clearOutput } = await mockDisplay(t) class CustomObj { #inspected @@ -136,7 +178,7 @@ t.test('Display.clean', async (t) => { ] for (const [dirty, clean] of tests) { - display.output(dirty) + output.standard(dirty) t.equal(outputs[0], clean) clearOutput() } diff --git a/test/lib/utils/exit-handler.js b/test/lib/utils/exit-handler.js index 597792da73e63..8af47d9abc26c 100644 --- a/test/lib/utils/exit-handler.js +++ b/test/lib/utils/exit-handler.js @@ -3,6 +3,7 @@ const fs = require('fs') const fsMiniPass = require('fs-minipass') const { join, resolve } = require('path') const EventEmitter = require('events') +const { output } = require('proc-log') const { load: loadMockNpm } = require('../../fixtures/mock-npm') const mockGlobals = require('@npmcli/mock-globals') const { cleanCwd, cleanDate } = require('../../fixtures/clean-snapshot') @@ -102,7 +103,10 @@ const mockExitHandler = async (t, { config, mocks, files, ...opts } = {}) => { return { ...rest, - errors, + errors: () => [ + ...rest.outputErrors, + ...errors, + ], npm, // Make it async to make testing ergonomics a little easier so we dont need // to t.plan() every test to make sure we get process.exit called. @@ -174,7 +178,7 @@ t.test('exit handler never called - loglevel silent', async (t) => { }) process.emit('exit', 1) t.strictSame(logs.error, []) - t.strictSame(errors, [''], 'logs one empty string to console.error') + t.strictSame(errors(), [''], 'one empty string') }) t.test('exit handler never called - loglevel notice', async (t) => { @@ -185,7 +189,7 @@ t.test('exit handler never called - loglevel notice', async (t) => { 'Exit handler never called!', /error with npm itself/, ]) - t.strictSame(errors, ['', ''], 'logs two empty strings to console.error') + t.strictSame(errors(), ['', ''], 'two empty string on output') }) t.test('exit handler never called - no npm', async (t) => { @@ -193,31 +197,34 @@ t.test('exit handler never called - no npm', async (t) => { process.emit('exit', 1) t.equal(process.exitCode, 1) t.strictSame(logs.error, []) - t.strictSame(errors, [''], 'logs one empty string to console.error') + t.strictSame(errors(), [''], 'one empty string') }) t.test('exit handler called - no npm', async (t) => { const { exitHandler, errors } = await mockExitHandler(t, { init: false }) await exitHandler() t.equal(process.exitCode, 1) - t.match(errors, [/Error: Exit prior to setting npm in exit handler/]) + t.equal(errors().length, 1) + t.match(errors(), [/Error: Exit prior to setting npm in exit handler/]) }) t.test('exit handler called - no npm with error', async (t) => { const { exitHandler, errors } = await mockExitHandler(t, { init: false }) await exitHandler(err('something happened')) t.equal(process.exitCode, 1) - t.match(errors, [/Error: something happened/]) + t.equal(errors().length, 1) + t.match(errors(), [/Error: something happened/]) }) t.test('exit handler called - no npm with error without stack', async (t) => { const { exitHandler, errors } = await mockExitHandler(t, { init: false }) await exitHandler(err('something happened', {}, true)) t.equal(process.exitCode, 1) - t.match(errors, [/something happened/]) + t.equal(errors().length, 1) + t.match(errors(), [/something happened/]) }) -t.test('console.log output using --json', async (t) => { +t.test('standard output using --json', async (t) => { const { exitHandler, outputs } = await mockExitHandler(t, { config: { json: true }, }) @@ -239,13 +246,13 @@ t.test('console.log output using --json', async (t) => { }) t.test('merges output buffers errors with --json', async (t) => { - const { exitHandler, outputs, npm } = await mockExitHandler(t, { + const { exitHandler, outputs } = await mockExitHandler(t, { config: { json: true }, }) - npm.outputBuffer({ output_data: 1 }) - npm.outputBuffer(JSON.stringify({ more_data: 2 })) - npm.outputBuffer('not json, will be ignored') + output.buffer({ output_data: 1 }) + output.buffer(JSON.stringify({ more_data: 2 })) + output.buffer('not json, will be ignored') await exitHandler(err('Error: EBADTHING Something happened')) @@ -266,10 +273,10 @@ t.test('merges output buffers errors with --json', async (t) => { }) t.test('output buffer without json', async (t) => { - const { exitHandler, outputs, npm, logs } = await mockExitHandler(t) + const { exitHandler, outputs, logs } = await mockExitHandler(t) - npm.outputBuffer('output_data') - npm.outputBuffer('more_data') + output.buffer('output_data') + output.buffer('more_data') await exitHandler(err('Error: EBADTHING Something happened')) @@ -307,8 +314,10 @@ t.test('throw a string error', async (t) => { ]) }) -t.test('update notification', async (t) => { - const { exitHandler, logs, npm } = await mockExitHandler(t) +t.test('update notification - shows even with loglevel error', async (t) => { + const { exitHandler, logs, npm } = await mockExitHandler(t, { + config: { loglevel: 'error' }, + }) npm.updateNotification = 'you should update npm!' await exitHandler() @@ -318,6 +327,17 @@ t.test('update notification', async (t) => { ]) }) +t.test('update notification - hidden with silent', async (t) => { + const { exitHandler, logs, npm } = await mockExitHandler(t, { + config: { loglevel: 'silent' }, + }) + npm.updateNotification = 'you should update npm!' + + await exitHandler() + + t.strictSame(logs.notice, []) +}) + t.test('npm.config not ready', async (t) => { const { exitHandler, logs, errors } = await mockExitHandler(t, { load: false, @@ -326,7 +346,8 @@ t.test('npm.config not ready', async (t) => { await exitHandler() t.equal(process.exitCode, 1) - t.match(errors, [ + t.equal(errors().length, 1) + t.match(errors(), [ /Error: Exit prior to config file resolving./, ], 'should exit with config error msg') t.strictSame(logs, [], 'no logs if it doesnt load') @@ -584,7 +605,7 @@ t.test('defaults to log error msg if stack is missing when unloaded', async (t) await exitHandler(err('Error with no stack', { code: 'ENOSTACK', errno: 127 }, true)) t.equal(process.exitCode, 127) - t.same(errors, ['Error with no stack'], 'should use error msg') + t.strictSame(errors(), ['Error with no stack'], 'should use error msg') t.strictSame(logs.error, []) }) @@ -608,25 +629,28 @@ t.test('do no fancy handling for shellouts', async t => { }) t.test('shellout with a numeric error code', async t => { - const { exitHandler, logs } = await mockShelloutExit(t) + const { exitHandler, logs, errors } = await mockShelloutExit(t) await exitHandler(err('', 5)) t.equal(process.exitCode, 5, 'got expected exit code') t.strictSame(logs.error, [], 'no noisy warnings') t.strictSame(logs.warn, [], 'no noisy warnings') + t.strictSame(errors(), []) }) t.test('shellout without a numeric error code (something in npm)', async t => { - const { exitHandler, logs } = await mockShelloutExit(t) + const { exitHandler, logs, errors } = await mockShelloutExit(t) await exitHandler(err('', 'banana stand')) t.equal(process.exitCode, 1, 'got expected exit code') // should log some warnings and errors, because something weird happened t.strictNotSame(logs.error, [], 'bring the noise') + t.strictSame(errors(), ['']) }) t.test('shellout with code=0 (extra weird?)', async t => { - const { exitHandler, logs } = await mockShelloutExit(t) + const { exitHandler, logs, errors } = await mockShelloutExit(t) await exitHandler(Object.assign(new Error(), { code: 0 })) t.equal(process.exitCode, 1, 'got expected exit code') t.strictNotSame(logs.error, [], 'bring the noise') + t.strictSame(errors(), ['']) }) }) diff --git a/test/lib/utils/read-user-info.js b/test/lib/utils/read-user-info.js index da771ccdf4a98..854277783bb6b 100644 --- a/test/lib/utils/read-user-info.js +++ b/test/lib/utils/read-user-info.js @@ -29,7 +29,9 @@ let logMsg = null const readUserInfo = tmock(t, '{LIB}/utils/read-user-info.js', { read, 'proc-log': { - warn: (msg) => logMsg = msg, + log: { + warn: (msg) => logMsg = msg, + }, }, 'npm-user-validate': npmUserValidate, }) diff --git a/test/lib/utils/tar.js b/test/lib/utils/tar.js index 9653e6058492f..45ba720ac54ed 100644 --- a/test/lib/utils/tar.js +++ b/test/lib/utils/tar.js @@ -9,7 +9,9 @@ t.cleanSnapshot = data => cleanZlib(data) const mockTar = ({ notice }) => tmock(t, '{LIB}/utils/tar.js', { 'proc-log': { - notice, + log: { + notice, + }, }, }) diff --git a/test/lib/utils/timers.js b/test/lib/utils/timers.js index 31f73b5aca408..c395a92a0a3e7 100644 --- a/test/lib/utils/timers.js +++ b/test/lib/utils/timers.js @@ -1,22 +1,24 @@ const t = require('tap') const { resolve, join } = require('path') const fs = require('graceful-fs') -const { format } = require('util') +const { log } = require('proc-log') const tmock = require('../../fixtures/tmock') const mockTimers = (t, options) => { - const logs = { - warn: [], - silly: [], + const logs = log.LEVELS.reduce((acc, l) => { + acc[l] = [] + return acc + }, {}) + const logHandler = (level, ...args) => { + logs[level].push(args.join(' ')) } - const Timers = tmock(t, '{LIB}/utils/timers', { - 'proc-log': { - warn: (...args) => logs.warn.push(args.map((a) => format(a)).join(' ')), - silly: (...args) => logs.silly.push(args.map((a) => format(a)).join(' ')), - }, - }) + process.on('log', logHandler) + const Timers = tmock(t, '{LIB}/utils/timers') const timers = new Timers(options) - t.teardown(() => timers.off()) + t.teardown(() => { + timers.off() + process.off('log', logHandler) + }) return { timers, logs } } @@ -43,23 +45,23 @@ t.test('convenience time method', async (t) => { t.match(timers.finished, { later: Number, sync: Number, async: Number }) }) -t.test('initial timer', async (t) => { - const { timers } = mockTimers(t, { start: 'foo' }) - process.emit('timeEnd', 'foo') - t.match(timers.finished, { foo: Number }) +t.test('initial timer is named npm', async (t) => { + const { timers } = mockTimers(t) + process.emit('timeEnd', 'npm') + t.match(timers.finished, { npm: Number }) }) -t.test('initial listener', async (t) => { +t.test('logs timing events', async (t) => { const events = [] const listener = (...args) => events.push(args) - const { timers } = mockTimers(t, { listener }) + const { timers, logs } = mockTimers(t, { listener }) process.emit('time', 'foo') process.emit('time', 'bar') process.emit('timeEnd', 'bar') timers.off(listener) process.emit('timeEnd', 'foo') - t.equal(events.length, 1) - t.match(events, [['bar', Number]]) + t.equal(logs.timing.length, 1) + t.match(logs.timing[0], /^bar Completed in [0-9]ms/) }) t.test('finish unstarted timer', async (t) => { diff --git a/workspaces/arborist/bin/lib/logging.js b/workspaces/arborist/bin/lib/logging.js index ffb5544b21463..f06716735de74 100644 --- a/workspaces/arborist/bin/lib/logging.js +++ b/workspaces/arborist/bin/lib/logging.js @@ -1,4 +1,4 @@ -const log = require('proc-log') +const { log } = require('proc-log') const fs = require('fs') const { dirname } = require('path') const os = require('os') diff --git a/workspaces/arborist/lib/add-rm-pkg-deps.js b/workspaces/arborist/lib/add-rm-pkg-deps.js index c5cdc097a9fab..2e30eb1de7626 100644 --- a/workspaces/arborist/lib/add-rm-pkg-deps.js +++ b/workspaces/arborist/lib/add-rm-pkg-deps.js @@ -1,6 +1,6 @@ // add and remove dependency specs to/from pkg manifest -const log = require('proc-log') +const { log } = require('proc-log') const localeCompare = require('@isaacs/string-locale-compare')('en') const add = ({ pkg, add, saveBundle, saveType }) => { diff --git a/workspaces/arborist/lib/arborist/build-ideal-tree.js b/workspaces/arborist/lib/arborist/build-ideal-tree.js index 75e4d373259a0..1daf03b0b466c 100644 --- a/workspaces/arborist/lib/arborist/build-ideal-tree.js +++ b/workspaces/arborist/lib/arborist/build-ideal-tree.js @@ -11,7 +11,7 @@ const treeCheck = require('../tree-check.js') const { readdirScoped } = require('@npmcli/fs') const { lstat, readlink } = require('fs/promises') const { depth } = require('treeverse') -const log = require('proc-log') +const { log } = require('proc-log') const { redact } = require('@npmcli/redact') const { diff --git a/workspaces/arborist/lib/arborist/index.js b/workspaces/arborist/lib/arborist/index.js index 358f3e1b1a759..0f02e1df1582f 100644 --- a/workspaces/arborist/lib/arborist/index.js +++ b/workspaces/arborist/lib/arborist/index.js @@ -30,7 +30,7 @@ const { resolve } = require('path') const { homedir } = require('os') const { depth } = require('treeverse') const mapWorkspaces = require('@npmcli/map-workspaces') -const log = require('proc-log') +const { log } = require('proc-log') const { saveTypeMap } = require('../add-rm-pkg-deps.js') const AuditReport = require('../audit-report.js') diff --git a/workspaces/arborist/lib/arborist/rebuild.js b/workspaces/arborist/lib/arborist/rebuild.js index 422819b2104b7..36dc6ae790fe6 100644 --- a/workspaces/arborist/lib/arborist/rebuild.js +++ b/workspaces/arborist/lib/arborist/rebuild.js @@ -13,7 +13,7 @@ const { isNodeGypPackage, defaultGypInstallScript, } = require('@npmcli/node-gyp') -const log = require('proc-log') +const { log } = require('proc-log') const boolEnv = b => b ? '1' : '' const sortNodes = (a, b) => diff --git a/workspaces/arborist/lib/arborist/reify.js b/workspaces/arborist/lib/arborist/reify.js index a70e21821ecb8..81b81cfd2d665 100644 --- a/workspaces/arborist/lib/arborist/reify.js +++ b/workspaces/arborist/lib/arborist/reify.js @@ -7,7 +7,7 @@ const npa = require('npm-package-arg') const semver = require('semver') const debug = require('../debug.js') const { walkUp } = require('walk-up-path') -const log = require('proc-log') +const { log } = require('proc-log') const hgi = require('hosted-git-info') const rpj = require('read-package-json-fast') diff --git a/workspaces/arborist/lib/audit-report.js b/workspaces/arborist/lib/audit-report.js index 387919f610829..7e5ac2071dcbe 100644 --- a/workspaces/arborist/lib/audit-report.js +++ b/workspaces/arborist/lib/audit-report.js @@ -13,7 +13,7 @@ const _fixAvailable = Symbol('fixAvailable') const _checkTopNode = Symbol('checkTopNode') const _init = Symbol('init') const _omit = Symbol('omit') -const log = require('proc-log') +const { log } = require('proc-log') const fetch = require('npm-registry-fetch') diff --git a/workspaces/arborist/lib/place-dep.js b/workspaces/arborist/lib/place-dep.js index bf0fef6525343..fca36eb685613 100644 --- a/workspaces/arborist/lib/place-dep.js +++ b/workspaces/arborist/lib/place-dep.js @@ -8,7 +8,7 @@ // a result. const localeCompare = require('@isaacs/string-locale-compare')('en') -const log = require('proc-log') +const { log } = require('proc-log') const { redact } = require('@npmcli/redact') const deepestNestingTarget = require('./deepest-nesting-target.js') const CanPlaceDep = require('./can-place-dep.js') diff --git a/workspaces/arborist/lib/query-selector-all.js b/workspaces/arborist/lib/query-selector-all.js index c8ec866f0f969..d001a5cced83d 100644 --- a/workspaces/arborist/lib/query-selector-all.js +++ b/workspaces/arborist/lib/query-selector-all.js @@ -3,7 +3,7 @@ const { resolve } = require('path') const { parser, arrayDelimiter } = require('@npmcli/query') const localeCompare = require('@isaacs/string-locale-compare')('en') -const log = require('proc-log') +const { log } = require('proc-log') const { minimatch } = require('minimatch') const npa = require('npm-package-arg') const pacote = require('pacote') diff --git a/workspaces/arborist/lib/shrinkwrap.js b/workspaces/arborist/lib/shrinkwrap.js index 275043d1208b7..026abc55ccba1 100644 --- a/workspaces/arborist/lib/shrinkwrap.js +++ b/workspaces/arborist/lib/shrinkwrap.js @@ -33,7 +33,7 @@ const mismatch = (a, b) => a && b && a !== b // After calling this.commit(), any nodes not present in the tree will have // been removed from the shrinkwrap data as well. -const log = require('proc-log') +const { log } = require('proc-log') const YarnLock = require('./yarn-lock.js') const { readFile, diff --git a/workspaces/arborist/package.json b/workspaces/arborist/package.json index d4350b1adaf11..04dcb3b63d747 100644 --- a/workspaces/arborist/package.json +++ b/workspaces/arborist/package.json @@ -7,13 +7,13 @@ "@npmcli/fs": "^3.1.0", "@npmcli/installed-package-contents": "^2.0.2", "@npmcli/map-workspaces": "^3.0.2", - "@npmcli/metavuln-calculator": "^7.0.0", + "@npmcli/metavuln-calculator": "^7.0.1", "@npmcli/name-from-folder": "^2.0.0", "@npmcli/node-gyp": "^3.0.0", - "@npmcli/package-json": "^5.0.0", + "@npmcli/package-json": "^5.0.3", "@npmcli/query": "^3.1.0", "@npmcli/redact": "^1.1.0", - "@npmcli/run-script": "^7.0.2", + "@npmcli/run-script": "^8.0.0", "bin-links": "^4.0.1", "cacache": "^18.0.0", "common-ancestor-path": "^1.0.1", @@ -23,12 +23,12 @@ "minimatch": "^9.0.4", "nopt": "^7.0.0", "npm-install-checks": "^6.2.0", - "npm-package-arg": "^11.0.1", + "npm-package-arg": "^11.0.2", "npm-pick-manifest": "^9.0.0", - "npm-registry-fetch": "^16.2.0", - "pacote": "^17.0.4", + "npm-registry-fetch": "^16.2.1", + "pacote": "^18.0.0", "parse-conflict-json": "^3.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.0.0", "proggy": "^2.0.0", "promise-all-reject-late": "^1.0.0", "promise-call-limit": "^3.0.1", diff --git a/workspaces/arborist/test/arborist/reify.js b/workspaces/arborist/test/arborist/reify.js index 46dc367cd3f08..db7df07e46bcd 100644 --- a/workspaces/arborist/test/arborist/reify.js +++ b/workspaces/arborist/test/arborist/reify.js @@ -101,6 +101,16 @@ const warningTracker = () => { } } +const outputTracker = () => { + const list = [] + const onlog = (...msg) => msg[0] === 'standard' && list.push(msg) + process.on('output', onlog) + return () => { + process.removeListener('output', onlog) + return list + } +} + const debugLogTracker = () => { const list = [] mockDebug.log = (...msg) => list.push(msg) @@ -2593,19 +2603,12 @@ t.test('runs dependencies script if tree changes', async (t) => { t.not(fs.existsSync(expectedPath), `did not run ${script}`) } - // take over console.log as run-script is going to print a banner for these because - // they're running in the foreground - const _log = console.log - t.teardown(() => { - console.log = _log - }) - const logs = [] - console.log = (msg) => logs.push(msg) + const outputs = outputTracker() + // reify again, this time adding a new dependency await reify(path, { foregroundScripts: true, add: ['once@^1.4.0'] }) - console.log = _log - t.match(logs, [/predependencies/, /dependencies/, /postdependencies/], 'logged banners') + t.match(outputs(), [/predependencies/, /dependencies/, /postdependencies/], 'logged banners') // files should exist again for (const script of ['predependencies', 'dependencies', 'postdependencies']) { diff --git a/workspaces/config/lib/index.js b/workspaces/config/lib/index.js index 1ff19c128696c..0d7ba3eb21f4e 100644 --- a/workspaces/config/lib/index.js +++ b/workspaces/config/lib/index.js @@ -2,7 +2,7 @@ const { walkUp } = require('walk-up-path') const ini = require('ini') const nopt = require('nopt') -const log = require('proc-log') +const { log } = require('proc-log') const { resolve, dirname, join } = require('node:path') const { homedir } = require('node:os') diff --git a/workspaces/config/package.json b/workspaces/config/package.json index 797c32f7ee4a6..bbfca367a1c24 100644 --- a/workspaces/config/package.json +++ b/workspaces/config/package.json @@ -40,7 +40,7 @@ "ci-info": "^4.0.0", "ini": "^4.1.2", "nopt": "^7.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.0.0", "read-package-json-fast": "^3.0.2", "semver": "^7.3.5", "walk-up-path": "^3.0.1" diff --git a/workspaces/libnpmaccess/package.json b/workspaces/libnpmaccess/package.json index 81a87d6395455..de40271c06c21 100644 --- a/workspaces/libnpmaccess/package.json +++ b/workspaces/libnpmaccess/package.json @@ -29,8 +29,8 @@ "bugs": "https://github.com/npm/libnpmaccess/issues", "homepage": "https://npmjs.com/package/libnpmaccess", "dependencies": { - "npm-package-arg": "^11.0.1", - "npm-registry-fetch": "^16.2.0" + "npm-package-arg": "^11.0.2", + "npm-registry-fetch": "^16.2.1" }, "engines": { "node": "^16.14.0 || >=18.0.0" diff --git a/workspaces/libnpmdiff/package.json b/workspaces/libnpmdiff/package.json index 98229e99bd561..fc4aac936b494 100644 --- a/workspaces/libnpmdiff/package.json +++ b/workspaces/libnpmdiff/package.json @@ -52,8 +52,8 @@ "binary-extensions": "^2.3.0", "diff": "^5.1.0", "minimatch": "^9.0.4", - "npm-package-arg": "^11.0.1", - "pacote": "^17.0.4", + "npm-package-arg": "^11.0.2", + "pacote": "^18.0.0", "tar": "^6.2.1" }, "templateOSS": { diff --git a/workspaces/libnpmexec/README.md b/workspaces/libnpmexec/README.md index fb4a1e32b18df..acd037c110b4b 100644 --- a/workspaces/libnpmexec/README.md +++ b/workspaces/libnpmexec/README.md @@ -35,7 +35,6 @@ await libexec({ - `localBin`: Location to the `node_modules/.bin` folder of the local project to start scanning for bin files **String**, defaults to `./node_modules/.bin`. **libexec** will walk up the directory structure looking for `node_modules/.bin` folders in parent folders that might satisfy the current `arg` and will use that bin if found. - `locationMsg`: Overrides "at location" message when entering interactive mode **String** - `globalBin`: Location to the global space bin folder, same as: `$(npm bin -g)` **String**, defaults to empty string. - - `output`: A function to print output to **Function** - `packages`: A list of packages to be used (possibly fetch from the registry) **Array**, defaults to `[]` - `path`: Location to where to read local project info (`package.json`) **String**, defaults to `.` - `runPath`: Location to where to execute the script **String**, defaults to `.` diff --git a/workspaces/libnpmexec/lib/index.js b/workspaces/libnpmexec/lib/index.js index af4d6e738779a..944f34b01c237 100644 --- a/workspaces/libnpmexec/lib/index.js +++ b/workspaces/libnpmexec/lib/index.js @@ -4,7 +4,7 @@ const { mkdir } = require('fs/promises') const Arborist = require('@npmcli/arborist') const ciInfo = require('ci-info') const crypto = require('crypto') -const log = require('proc-log') +const { log } = require('proc-log') const npa = require('npm-package-arg') const pacote = require('pacote') const { read } = require('read') @@ -83,7 +83,6 @@ const exec = async (opts) => { locationMsg = undefined, globalBin = '', globalPath, - output, // dereference values because we manipulate it later packages: [...packages] = [], path = '.', @@ -98,7 +97,6 @@ const exec = async (opts) => { call, flatOptions, locationMsg, - output, path, binPaths, runPath, diff --git a/workspaces/libnpmexec/lib/run-script.js b/workspaces/libnpmexec/lib/run-script.js index 65fabfc480b8c..1f621edcbc9aa 100644 --- a/workspaces/libnpmexec/lib/run-script.js +++ b/workspaces/libnpmexec/lib/run-script.js @@ -1,7 +1,7 @@ const ciInfo = require('ci-info') const runScript = require('@npmcli/run-script') const readPackageJson = require('read-package-json-fast') -const log = require('proc-log') +const { log, output } = require('proc-log') const noTTY = require('./no-tty.js') const run = async ({ @@ -9,7 +9,6 @@ const run = async ({ call, flatOptions, locationMsg, - output = () => {}, path, binPaths, runPath, @@ -37,7 +36,7 @@ const run = async ({ const { chalk } = flatOptions - output(`${ + output.standard(`${ chalk.reset('\nEntering npm script environment') }${ chalk.reset(locationMsg || ` at location:\n${chalk.dim(runPath)}`) @@ -49,7 +48,6 @@ const run = async ({ return runScript({ ...flatOptions, pkg, - banner: false, // we always run in cwd, not --prefix path: runPath, binPaths, diff --git a/workspaces/libnpmexec/package.json b/workspaces/libnpmexec/package.json index ac7d4afbccec1..67da94289092d 100644 --- a/workspaces/libnpmexec/package.json +++ b/workspaces/libnpmexec/package.json @@ -60,11 +60,11 @@ }, "dependencies": { "@npmcli/arborist": "^7.2.1", - "@npmcli/run-script": "^7.0.2", + "@npmcli/run-script": "^8.0.0", "ci-info": "^4.0.0", - "npm-package-arg": "^11.0.1", - "pacote": "^17.0.4", - "proc-log": "^3.0.0", + "npm-package-arg": "^11.0.2", + "pacote": "^18.0.0", + "proc-log": "^4.0.0", "read": "^3.0.1", "read-package-json-fast": "^3.0.2", "semver": "^7.3.7", diff --git a/workspaces/libnpmexec/test/local.js b/workspaces/libnpmexec/test/local.js index 19595187e265f..ddfb8f5429e1a 100644 --- a/workspaces/libnpmexec/test/local.js +++ b/workspaces/libnpmexec/test/local.js @@ -1,4 +1,4 @@ -const log = require('proc-log') +const { log } = require('proc-log') const { resolve } = require('path') const t = require('tap') const fs = require('fs/promises') @@ -283,9 +283,11 @@ t.test('local file system path', async t => { mocks: { 'ci-info': { isCI: true }, 'proc-log': { - ...log, - warn () { - t.fail('should not warn about local file package install') + log: { + ...log, + warn () { + t.fail('should not warn about local file package install') + }, }, }, }, diff --git a/workspaces/libnpmexec/test/prompt.js b/workspaces/libnpmexec/test/prompt.js index d1f4ec48e6b98..5edcff9a3d9cb 100644 --- a/workspaces/libnpmexec/test/prompt.js +++ b/workspaces/libnpmexec/test/prompt.js @@ -1,4 +1,4 @@ -const log = require('proc-log') +const { log } = require('proc-log') const { resolve } = require('path') const t = require('tap') const fs = require('fs/promises') @@ -146,18 +146,20 @@ t.test('no prompt if CI, multiple packages', async t => { mocks: { 'ci-info': { isCI: true }, 'proc-log': { - ...log, - warn (title, msg) { - t.equal(title, 'exec', 'should warn exec title') - // this message is nondeterministic as it queries manifests so we just - // test the constituent parts - t.match( - msg, - 'The following packages were not found and will be installed:', - 'should warn installing packages' - ) - t.match(msg, '@npmcli/create-index@1.0.0', 'includes package being installed') - t.match(msg, '@npmcli/create-test@1.0.0', 'includes package being installed') + log: { + ...log, + warn (title, msg) { + t.equal(title, 'exec', 'should warn exec title') + // this message is nondeterministic as it queries manifests so we just + // test the constituent parts + t.match( + msg, + 'The following packages were not found and will be installed:', + 'should warn installing packages' + ) + t.match(msg, '@npmcli/create-index@1.0.0', 'includes package being installed') + t.match(msg, '@npmcli/create-test@1.0.0', 'includes package being installed') + }, }, }, }, diff --git a/workspaces/libnpmexec/test/run-script.js b/workspaces/libnpmexec/test/run-script.js index e7c83466334fd..01e3f35594906 100644 --- a/workspaces/libnpmexec/test/run-script.js +++ b/workspaces/libnpmexec/test/run-script.js @@ -1,9 +1,26 @@ const t = require('tap') const mockRunScript = async (t, mocks, { level = 0 } = {}) => { - const runScript = t.mock('../lib/run-script.js', mocks) + const mockedRunScript = t.mock('../lib/run-script.js', mocks) const { Chalk } = await import('chalk') - return (opts) => runScript({ + + const outputs = [] + const handleOutput = (_level, msg) => { + if (_level === 'standard') { + outputs.push(msg) + } + } + process.on('output', handleOutput) + t.teardown(() => process.off('output', handleOutput)) + + const logs = [] + const handleLog = (_level, title, msg) => { + logs.push(`${_level} ${title} ${msg}`) + } + process.on('log', handleLog) + t.teardown(() => process.off('log', handleLog)) + + const runScript = (opts) => mockedRunScript({ args: [], call: '', path: '', @@ -14,6 +31,7 @@ const mockRunScript = async (t, mocks, { level = 0 } = {}) => { ...opts, flatOptions: { chalk: new Chalk({ level }) }, }) + return { runScript, outputs, logs } } t.test('no package.json', async t => { @@ -24,7 +42,7 @@ t.test('no package.json', async t => { name: 'pkg', }), }) - const runScript = await mockRunScript(t, { + const { runScript } = await mockRunScript(t, { 'ci-info': { isCI: false }, '@npmcli/run-script': async () => { t.ok('should call run-script') @@ -38,7 +56,7 @@ t.test('no package.json', async t => { t.test('colorized interactive mode msg', async t => { t.plan(2) - const runScript = await mockRunScript(t, { + const { runScript, outputs } = await mockRunScript(t, { 'ci-info': { isCI: false }, '@npmcli/run-script': async () => { t.ok('should call run-script') @@ -46,20 +64,16 @@ t.test('colorized interactive mode msg', async t => { '../lib/no-tty.js': () => false, }, { level: 3 }) - const OUTPUT = [] await runScript({ - output: msg => { - OUTPUT.push(msg) - }, runPath: '/foo/', }) - t.matchSnapshot(OUTPUT.join('\n'), 'should print colorized output') + t.matchSnapshot(outputs.join('\n'), 'should print colorized output') }) t.test('no color interactive mode msg', async t => { t.plan(2) - const runScript = await mockRunScript(t, { + const { runScript, outputs } = await mockRunScript(t, { 'ci-info': { isCI: false }, '@npmcli/run-script': async () => { t.ok('should call run-script') @@ -67,20 +81,16 @@ t.test('no color interactive mode msg', async t => { '../lib/no-tty.js': () => false, }) - const OUTPUT = [] await runScript({ - output: msg => { - OUTPUT.push(msg) - }, runPath: '/foo/', }) - t.matchSnapshot(OUTPUT.join('\n'), 'should print non-colorized output') + t.matchSnapshot(outputs.join('\n'), 'should print non-colorized output') }) t.test('no tty', async t => { t.plan(1) - const runScript = await mockRunScript(t, { + const { runScript } = await mockRunScript(t, { 'ci-info': { isCI: false }, '@npmcli/run-script': async () => { t.ok('should call run-script') @@ -92,25 +102,16 @@ t.test('no tty', async t => { }) t.test('ci env', async t => { - t.plan(2) - - const runScript = await mockRunScript(t, { + const { runScript, logs } = await mockRunScript(t, { 'ci-info': { isCI: true }, '@npmcli/run-script': async () => { throw new Error('should not call run-script') }, '../lib/no-tty.js': () => false, - 'proc-log': { - warn (title, msg) { - t.equal(title, 'exec', 'should have expected title') - t.equal( - msg, - 'Interactive mode disabled in CI environment', - 'should have expected ci environment message' - ) - }, - }, + }) await runScript() + + t.equal(logs[0], 'warn exec Interactive mode disabled in CI environment') }) diff --git a/workspaces/libnpmhook/package.json b/workspaces/libnpmhook/package.json index 7613c1c86fbc1..31745cd7583aa 100644 --- a/workspaces/libnpmhook/package.json +++ b/workspaces/libnpmhook/package.json @@ -31,7 +31,7 @@ "license": "ISC", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^16.2.0" + "npm-registry-fetch": "^16.2.1" }, "devDependencies": { "@npmcli/eslint-config": "^4.0.0", diff --git a/workspaces/libnpmorg/package.json b/workspaces/libnpmorg/package.json index 49671afd46371..626da4c72bb18 100644 --- a/workspaces/libnpmorg/package.json +++ b/workspaces/libnpmorg/package.json @@ -42,7 +42,7 @@ "homepage": "https://npmjs.com/package/libnpmorg", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^16.2.0" + "npm-registry-fetch": "^16.2.1" }, "engines": { "node": "^16.14.0 || >=18.0.0" diff --git a/workspaces/libnpmpack/lib/index.js b/workspaces/libnpmpack/lib/index.js index 70d67d360f0d9..00dc96974a968 100644 --- a/workspaces/libnpmpack/lib/index.js +++ b/workspaces/libnpmpack/lib/index.js @@ -15,10 +15,6 @@ async function pack (spec = 'file:.', opts = {}) { const manifest = await pacote.manifest(spec, opts) - // Default to true if no log options passed, set to false if we're in silent - // mode - const banner = !opts.silent - const stdio = opts.foregroundScripts ? 'inherit' : 'pipe' if (spec.type === 'directory' && !opts.ignoreScripts) { @@ -29,7 +25,6 @@ async function pack (spec = 'file:.', opts = {}) { path: spec.fetchSpec, stdio, pkg: manifest, - banner, }) } @@ -56,7 +51,6 @@ async function pack (spec = 'file:.', opts = {}) { path: spec.fetchSpec, stdio, pkg: manifest, - banner, env: { npm_package_from: tarball.from, npm_package_resolved: tarball.resolved, diff --git a/workspaces/libnpmpack/package.json b/workspaces/libnpmpack/package.json index 1782ab7143186..518e95420455c 100644 --- a/workspaces/libnpmpack/package.json +++ b/workspaces/libnpmpack/package.json @@ -37,9 +37,9 @@ "homepage": "https://npmjs.com/package/libnpmpack", "dependencies": { "@npmcli/arborist": "^7.2.1", - "@npmcli/run-script": "^7.0.2", - "npm-package-arg": "^11.0.1", - "pacote": "^17.0.4" + "@npmcli/run-script": "^8.0.0", + "npm-package-arg": "^11.0.2", + "pacote": "^18.0.0" }, "engines": { "node": "^16.14.0 || >=18.0.0" diff --git a/workspaces/libnpmpublish/lib/publish.js b/workspaces/libnpmpublish/lib/publish.js index b0ef782a166c6..9ffbc93426309 100644 --- a/workspaces/libnpmpublish/lib/publish.js +++ b/workspaces/libnpmpublish/lib/publish.js @@ -1,7 +1,7 @@ const { fixer } = require('normalize-package-data') const npmFetch = require('npm-registry-fetch') const npa = require('npm-package-arg') -const log = require('proc-log') +const { log } = require('proc-log') const semver = require('semver') const { URL } = require('url') const ssri = require('ssri') diff --git a/workspaces/libnpmpublish/package.json b/workspaces/libnpmpublish/package.json index 34f642794af40..d485e99b68ae0 100644 --- a/workspaces/libnpmpublish/package.json +++ b/workspaces/libnpmpublish/package.json @@ -40,9 +40,9 @@ "dependencies": { "ci-info": "^4.0.0", "normalize-package-data": "^6.0.0", - "npm-package-arg": "^11.0.1", - "npm-registry-fetch": "^16.2.0", - "proc-log": "^3.0.0", + "npm-package-arg": "^11.0.2", + "npm-registry-fetch": "^16.2.1", + "proc-log": "^4.0.0", "semver": "^7.3.7", "sigstore": "^2.2.0", "ssri": "^10.0.5" diff --git a/workspaces/libnpmpublish/test/publish.js b/workspaces/libnpmpublish/test/publish.js index 584508d34fe03..b9875097bf538 100644 --- a/workspaces/libnpmpublish/test/publish.js +++ b/workspaces/libnpmpublish/test/publish.js @@ -385,7 +385,7 @@ t.test('publish existing package with provenance in gha', async t => { const log = [] const { publish } = t.mock('..', { 'ci-info': t.mock('ci-info'), - 'proc-log': { notice: (...msg) => log.push(['notice', ...msg]) }, + 'proc-log': { log: { notice: (...msg) => log.push(['notice', ...msg]) } }, }) const registry = new MockRegistry({ tap: t, @@ -944,7 +944,7 @@ t.test('publish existing package with provenance in gitlab', async t => { const log = [] const { publish } = t.mock('..', { 'ci-info': t.mock('ci-info'), - 'proc-log': { notice: (...msg) => log.push(['notice', ...msg]) }, + 'proc-log': { log: { notice: (...msg) => log.push(['notice', ...msg]) } }, }) const registry = new MockRegistry({ tap: t, diff --git a/workspaces/libnpmsearch/package.json b/workspaces/libnpmsearch/package.json index c27673d2202c0..9edcd98913d3a 100644 --- a/workspaces/libnpmsearch/package.json +++ b/workspaces/libnpmsearch/package.json @@ -38,7 +38,7 @@ "bugs": "https://github.com/npm/libnpmsearch/issues", "homepage": "https://npmjs.com/package/libnpmsearch", "dependencies": { - "npm-registry-fetch": "^16.2.0" + "npm-registry-fetch": "^16.2.1" }, "engines": { "node": "^16.14.0 || >=18.0.0" diff --git a/workspaces/libnpmteam/package.json b/workspaces/libnpmteam/package.json index 110304fa0a156..b44847cc43a6a 100644 --- a/workspaces/libnpmteam/package.json +++ b/workspaces/libnpmteam/package.json @@ -32,7 +32,7 @@ "homepage": "https://npmjs.com/package/libnpmteam", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^16.2.0" + "npm-registry-fetch": "^16.2.1" }, "engines": { "node": "^16.14.0 || >=18.0.0" diff --git a/workspaces/libnpmversion/README.md b/workspaces/libnpmversion/README.md index ac9ee50ae35d9..857c4d52dc183 100644 --- a/workspaces/libnpmversion/README.md +++ b/workspaces/libnpmversion/README.md @@ -31,7 +31,6 @@ npmVersion(arg, { ignoreScripts: false, // do not run pre/post/version lifecycle scripts scriptShell: '/bin/bash', // shell to run lifecycle scripts in message: 'v%s', // message for tag and commit, replace %s with the version - silent: false, // passed to @npmcli/run-script to control whether it logs }).then(newVersion => { console.error('version updated!', newVersion) }) diff --git a/workspaces/libnpmversion/lib/enforce-clean.js b/workspaces/libnpmversion/lib/enforce-clean.js index 721f146221c15..25ebb5590e917 100644 --- a/workspaces/libnpmversion/lib/enforce-clean.js +++ b/workspaces/libnpmversion/lib/enforce-clean.js @@ -1,5 +1,5 @@ const git = require('@npmcli/git') -const log = require('proc-log') +const { log } = require('proc-log') // returns true if it's cool to do git stuff // throws if it's unclean, and not forced. diff --git a/workspaces/libnpmversion/lib/index.js b/workspaces/libnpmversion/lib/index.js index 95acd11b5e433..4d2fb45945a7b 100644 --- a/workspaces/libnpmversion/lib/index.js +++ b/workspaces/libnpmversion/lib/index.js @@ -15,7 +15,6 @@ module.exports = async (newversion, opts = {}) => { scriptShell = undefined, preid = null, message = 'v%s', - silent, } = opts const pkg = opts.pkg || await readJson(path + '/package.json') @@ -35,6 +34,5 @@ module.exports = async (newversion, opts = {}) => { preid, pkg, message, - silent, }) } diff --git a/workspaces/libnpmversion/lib/version.js b/workspaces/libnpmversion/lib/version.js index f14b95e3233f0..bfcd8a521496d 100644 --- a/workspaces/libnpmversion/lib/version.js +++ b/workspaces/libnpmversion/lib/version.js @@ -8,7 +8,7 @@ const readJson = require('./read-json.js') const git = require('@npmcli/git') const commit = require('./commit.js') const tag = require('./tag.js') -const log = require('proc-log') +const { log } = require('proc-log') const runScript = require('@npmcli/run-script') @@ -20,7 +20,6 @@ module.exports = async (newversion, opts) => { ignoreScripts, preid, pkg, - silent, } = opts const { valid, clean, inc } = semver @@ -65,7 +64,6 @@ module.exports = async (newversion, opts) => { pkg, stdio: 'inherit', event: 'preversion', - banner: !silent, env: { npm_old_version: current, npm_new_version: newV, @@ -101,7 +99,6 @@ module.exports = async (newversion, opts) => { pkg, stdio: 'inherit', event: 'version', - banner: !silent, env: { npm_old_version: current, npm_new_version: newV, @@ -128,7 +125,6 @@ module.exports = async (newversion, opts) => { pkg, stdio: 'inherit', event: 'postversion', - banner: !silent, env: { npm_old_version: current, npm_new_version: newV, diff --git a/workspaces/libnpmversion/package.json b/workspaces/libnpmversion/package.json index 782eeca7d2b79..62f34509d2882 100644 --- a/workspaces/libnpmversion/package.json +++ b/workspaces/libnpmversion/package.json @@ -37,10 +37,10 @@ "tap": "^16.3.8" }, "dependencies": { - "@npmcli/git": "^5.0.3", - "@npmcli/run-script": "^7.0.2", + "@npmcli/git": "^5.0.6", + "@npmcli/run-script": "^8.0.0", "json-parse-even-better-errors": "^3.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.0.0", "semver": "^7.3.7" }, "engines": { diff --git a/workspaces/libnpmversion/tap-snapshots/test/index.js.test.cjs b/workspaces/libnpmversion/tap-snapshots/test/index.js.test.cjs index 59224e13fae45..07bf61461bb0b 100644 --- a/workspaces/libnpmversion/tap-snapshots/test/index.js.test.cjs +++ b/workspaces/libnpmversion/tap-snapshots/test/index.js.test.cjs @@ -24,7 +24,6 @@ Array [ "scriptShell": undefined, "signGitCommit": false, "signGitTag": false, - "silent": undefined, "tagVersionPrefix": "v", }, ] @@ -49,7 +48,6 @@ Array [ "scriptShell": "/bin/bash", "signGitCommit": true, "signGitTag": true, - "silent": undefined, "tagVersionPrefix": "=", }, ] diff --git a/workspaces/libnpmversion/test/enforce-clean.js b/workspaces/libnpmversion/test/enforce-clean.js index 3badf47ea5bc4..a4af3061116bd 100644 --- a/workspaces/libnpmversion/test/enforce-clean.js +++ b/workspaces/libnpmversion/test/enforce-clean.js @@ -16,7 +16,7 @@ const enforceClean = requireInject('../lib/enforce-clean.js', { } }, }, - 'proc-log': { warn: (...msg) => warnings.push(msg) }, + 'proc-log': { log: { warn: (...msg) => warnings.push(msg) } }, }) const warnings = [] diff --git a/workspaces/libnpmversion/test/version.js b/workspaces/libnpmversion/test/version.js index 2cbd615c56916..4fee6f5cd2af9 100644 --- a/workspaces/libnpmversion/test/version.js +++ b/workspaces/libnpmversion/test/version.js @@ -23,7 +23,9 @@ const version = requireInject('../lib/version.js', { '@npmcli/git': gitMock, '@npmcli/run-script': async opt => actionLog.push(['run-script', opt.event, opt.env, opt]), 'proc-log': { - verbose: (...msg) => actionLog.push(['verbose', ...msg]), + log: { + verbose: (...msg) => actionLog.push(['verbose', ...msg]), + }, }, }) @@ -331,14 +333,14 @@ t.test('test out bumping the version in all the ways', async t => { t.equal(await version('=v3.2.1', { path, pkg, allowSameVersion: true }), '3.2.1') t.match(actionLog, [ ['run-script', 'preversion', { npm_old_version: '3.2.1', npm_new_version: '3.2.1' }, - { banner: true }], + {}], ['write-json', path + '/package.json', pkg], ['write-json', path + '/npm-shrinkwrap.json', pkg], ['run-script', 'version', { npm_old_version: '3.2.1', npm_new_version: '3.2.1' }, - { banner: true }], + {}], ['verbose', 'version', 'Not tagging: not in a git repo or no git cmd'], ['run-script', 'postversion', { npm_old_version: '3.2.1', npm_new_version: '3.2.1' }, - { banner: true }], + {}], ]) t.equal(pkg.version, '3.2.1') }) @@ -347,14 +349,14 @@ t.test('test out bumping the version in all the ways', async t => { { path, silent: true, pkg, allowSameVersion: true }), '3.2.1') t.match(actionLog, [ ['run-script', 'preversion', { npm_old_version: '3.2.1', npm_new_version: '3.2.1' }, - { banner: false }], + {}], ['write-json', path + '/package.json', pkg], ['write-json', path + '/npm-shrinkwrap.json', pkg], ['run-script', 'version', { npm_old_version: '3.2.1', npm_new_version: '3.2.1' }, - { banner: false }], + {}], ['verbose', 'version', 'Not tagging: not in a git repo or no git cmd'], ['run-script', 'postversion', { npm_old_version: '3.2.1', npm_new_version: '3.2.1' }, - { banner: false }], + {}], ]) t.equal(pkg.version, '3.2.1') })