diff --git a/deps/npm/docs/content/using-npm/config.md b/deps/npm/docs/content/using-npm/config.md
index a5017e61db914b..fe197e344dbc08 100644
--- a/deps/npm/docs/content/using-npm/config.md
+++ b/deps/npm/docs/content/using-npm/config.md
@@ -1014,8 +1014,8 @@ Ideal if all users are on npm version 7 and higher.
* Type: "silent", "error", "warn", "notice", "http", "timing", "info",
"verbose", or "silly"
-What level of logs to report. On failure, *all* logs are written to
-`npm-debug.log` in the current working directory.
+What level of logs to report. All logs are written to a debug log, with the
+path to that file printed if the execution of a command fails.
Any logs of a higher level than the setting are shown. The default is
"notice".
@@ -1387,7 +1387,7 @@ Save installed packages to a package.json file as `optionalDependencies`.
* Default: false
* Type: Boolean
-Save installed packages. to a package.json file as `peerDependencies`
+Save installed packages to a package.json file as `peerDependencies`
diff --git a/deps/npm/docs/content/using-npm/logging.md b/deps/npm/docs/content/using-npm/logging.md
new file mode 100644
index 00000000000000..b7c5e899778997
--- /dev/null
+++ b/deps/npm/docs/content/using-npm/logging.md
@@ -0,0 +1,60 @@
+---
+title: Logging
+section: 7
+description: Why, What & How we Log
+---
+
+### Description
+
+The `npm` CLI has various mechanisms for showing different levels of information back to end-users for certain commands, configurations & environments.
+
+### Setting Log Levels
+
+#### `loglevel`
+
+`loglevel` is a global argument/config that can be set to determine the type of information to be displayed.
+
+The default value of `loglevel` is `"notice"` but there are several levels/types of logs available, including:
+
+- `"silent"`
+- `"error"`
+- `"warn"`
+- `"notice"`
+- `"http"`
+- `"timing"`
+- `"info"`
+- `"verbose"`
+- `"silly"`
+
+All logs pertaining to a level proceeding the current setting will be shown.
+
+All logs are written to a debug log, with the path to that file printed if the execution of a command fails.
+
+##### Aliases
+
+The log levels listed above have various corresponding aliases, including:
+
+- `-d`: `--loglevel info`
+- `--dd`: `--loglevel verbose`
+- `--verbose`: `--loglevel verbose`
+- `--ddd`: `--loglevel silly`
+- `-q`: `--loglevel warn`
+- `--quiet`: `--loglevel warn`
+- `-s`: `--loglevel silent`
+- `--silent`: `--loglevel silent`
+
+#### `foreground-scripts`
+
+The `npm` CLI began hiding the output of lifecycle scripts for `npm install` as of `v7`. Notably, this means you will not see logs/output from packages that may be using "install scripts" to display information back to you or from your own project's scripts defined in `package.json`. If you'd like to change this behavior & log this output you can set `foreground-scripts` to `true`.
+
+### Registry Response Headers
+
+#### `npm-notice`
+
+The `npm` CLI reads from & logs any `npm-notice` headers that are returned from the configured registry. This mechanism can be used by third-party registries to provide useful information when network-dependent requests occur.
+
+This header is not cached, and will not be logged if the request is served from the cache.
+
+### See also
+
+* [config](/using-npm/config)
diff --git a/deps/npm/docs/content/using-npm/scripts.md b/deps/npm/docs/content/using-npm/scripts.md
index fba37c28600b3b..737cef3f43c83a 100644
--- a/deps/npm/docs/content/using-npm/scripts.md
+++ b/deps/npm/docs/content/using-npm/scripts.md
@@ -259,7 +259,7 @@ package.json file, then your package scripts would have the
in your code with `process.env.npm_package_name` and
`process.env.npm_package_version`, and so on for other fields.
-See [`package-json.md`](/configuring-npm/package-json) for more on package configs.
+See [`package.json`](/configuring-npm/package-json) for more on package configs.
#### current lifecycle event
diff --git a/deps/npm/docs/content/using-npm/workspaces.md b/deps/npm/docs/content/using-npm/workspaces.md
index fc299072253937..c2ecce5ef471c3 100644
--- a/deps/npm/docs/content/using-npm/workspaces.md
+++ b/deps/npm/docs/content/using-npm/workspaces.md
@@ -8,7 +8,7 @@ description: Working with workspaces
**Workspaces** is a generic term that refers to the set of features in the
npm cli that provides support to managing multiple packages from your local
-files system from within a singular top-level, root package.
+file system from within a singular top-level, root package.
This set of features makes up for a much more streamlined workflow handling
linked packages from the local file system. Automating the linking process
diff --git a/deps/npm/docs/output/commands/npm-ls.html b/deps/npm/docs/output/commands/npm-ls.html
index e344845a34db98..9fd0fb148aae03 100644
--- a/deps/npm/docs/output/commands/npm-ls.html
+++ b/deps/npm/docs/output/commands/npm-ls.html
@@ -160,7 +160,7 @@
Description
the results to only the paths to the packages named. Note that nested
packages will also show the paths to the specified packages. For
example, running npm ls promzard
in npm's source tree will show:
-npm@8.1.4 /path/to/npm
+npm@8.2.0 /path/to/npm
└─┬ init-package-json@0.0.4
└── promzard@0.1.5
diff --git a/deps/npm/docs/output/commands/npm.html b/deps/npm/docs/output/commands/npm.html
index dd111c40be91ff..8f1c16a4426975 100644
--- a/deps/npm/docs/output/commands/npm.html
+++ b/deps/npm/docs/output/commands/npm.html
@@ -149,7 +149,7 @@ Table of contents
npm <command> [args]
Version
-8.1.4
+8.2.0
Description
npm is the package manager for the Node JavaScript platform. It puts
modules in place so that node can find them, and manages dependency
diff --git a/deps/npm/docs/output/using-npm/config.html b/deps/npm/docs/output/using-npm/config.html
index 639ef624bca92e..f3db847b48abf1 100644
--- a/deps/npm/docs/output/using-npm/config.html
+++ b/deps/npm/docs/output/using-npm/config.html
@@ -962,8 +962,8 @@
loglevel
Type: "silent", "error", "warn", "notice", "http", "timing", "info",
"verbose", or "silly"
-What level of logs to report. On failure, all logs are written to
-npm-debug.log
in the current working directory.
+What level of logs to report. All logs are written to a debug log, with the
+path to that file printed if the execution of a command fails.
Any logs of a higher level than the setting are shown. The default is
"notice".
See also the foreground-scripts
config.
@@ -1259,7 +1259,7 @@ save-peer
Default: false
Type: Boolean
-Save installed packages. to a package.json file as peerDependencies
+Save installed packages to a package.json file as peerDependencies
save-prefix
diff --git a/deps/npm/docs/output/using-npm/logging.html b/deps/npm/docs/output/using-npm/logging.html
new file mode 100644
index 00000000000000..d4b9760967a018
--- /dev/null
+++ b/deps/npm/docs/output/using-npm/logging.html
@@ -0,0 +1,203 @@
+
+
+Logging
+
+
+
+
+
+
+
+
+
+
+
+npm command-line interface
+
+
+
+
+
+
+Logging
+Why, What & How we Log
+
+
+
+
+Description
+
The npm
CLI has various mechanisms for showing different levels of information back to end-users for certain commands, configurations & environments.
+
Setting Log Levels
+
loglevel
+
loglevel
is a global argument/config that can be set to determine the type of information to be displayed.
+
The default value of loglevel
is "notice"
but there are several levels/types of logs available, including:
+
+"silent"
+"error"
+"warn"
+"notice"
+"http"
+"timing"
+"info"
+"verbose"
+"silly"
+
+
All logs pertaining to a level proceeding the current setting will be shown.
+
All logs are written to a debug log, with the path to that file printed if the execution of a command fails.
+
Aliases
+
The log levels listed above have various corresponding aliases, including:
+
+-d
: --loglevel info
+--dd
: --loglevel verbose
+--verbose
: --loglevel verbose
+--ddd
: --loglevel silly
+-q
: --loglevel warn
+--quiet
: --loglevel warn
+-s
: --loglevel silent
+--silent
: --loglevel silent
+
+
foreground-scripts
+
The npm
CLI began hiding the output of lifecycle scripts for npm install
as of v7
. Notably, this means you will not see logs/output from packages that may be using "install scripts" to display information back to you or from your own project's scripts defined in package.json
. If you'd like to change this behavior & log this output you can set foreground-scripts
to true
.
+
+
npm-notice
+
The npm
CLI reads from & logs any npm-notice
headers that are returned from the configured registry. This mechanism can be used by third-party registries to provide useful information when network-dependent requests occur.
+
This header is not cached, and will not be logged if the request is served from the cache.
+
See also
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/deps/npm/docs/output/using-npm/scripts.html b/deps/npm/docs/output/using-npm/scripts.html
index 3a51b0570700c0..19082719efc1cc 100644
--- a/deps/npm/docs/output/using-npm/scripts.html
+++ b/deps/npm/docs/output/using-npm/scripts.html
@@ -380,7 +380,7 @@ package.json vars
npm_package_version
set to "1.2.5". You can access these variables
in your code with process.env.npm_package_name
and
process.env.npm_package_version
, and so on for other fields.
-See package-json.md
for more on package configs.
+See package.json
for more on package configs.
current lifecycle event
Lastly, the npm_lifecycle_event
environment variable is set to
whichever stage of the cycle is being executed. So, you could have a
diff --git a/deps/npm/docs/output/using-npm/workspaces.html b/deps/npm/docs/output/using-npm/workspaces.html
index 6f5a23e749ce97..42f10e5f3d66d3 100644
--- a/deps/npm/docs/output/using-npm/workspaces.html
+++ b/deps/npm/docs/output/using-npm/workspaces.html
@@ -148,7 +148,7 @@
Table of contents
Description
Workspaces is a generic term that refers to the set of features in the
npm cli that provides support to managing multiple packages from your local
-files system from within a singular top-level, root package.
+file system from within a singular top-level, root package.
This set of features makes up for a much more streamlined workflow handling
linked packages from the local file system. Automating the linking process
as part of npm install
and avoiding manually having to use npm link
in
diff --git a/deps/npm/lib/auth/legacy.js b/deps/npm/lib/auth/legacy.js
index 2da82e361db409..d1401ce14b9ef1 100644
--- a/deps/npm/lib/auth/legacy.js
+++ b/deps/npm/lib/auth/legacy.js
@@ -1,15 +1,12 @@
-const log = require('npmlog')
const profile = require('npm-profile')
-
+const log = require('../utils/log-shim')
const openUrl = require('../utils/open-url.js')
const read = require('../utils/read-user-info.js')
const loginPrompter = async (creds) => {
- const opts = { log: log }
-
- creds.username = await read.username('Username:', creds.username, opts)
+ creds.username = await read.username('Username:', creds.username)
creds.password = await read.password('Password:', creds.password)
- creds.email = await read.email('Email: (this IS public) ', creds.email, opts)
+ creds.email = await read.email('Email: (this IS public) ', creds.email)
return creds
}
@@ -19,7 +16,7 @@ const login = async (npm, opts) => {
const requestOTP = async () => {
const otp = await read.otp(
- 'Enter one-time password from your authenticator app: '
+ 'Enter one-time password: '
)
return profile.loginCouch(
diff --git a/deps/npm/lib/auth/sso.js b/deps/npm/lib/auth/sso.js
index 6fcfc30e5d3a8d..795eb8972a2236 100644
--- a/deps/npm/lib/auth/sso.js
+++ b/deps/npm/lib/auth/sso.js
@@ -7,10 +7,9 @@
// CLI, we can remove this, and fold the lib/auth/legacy.js back into
// lib/adduser.js
-const log = require('npmlog')
const profile = require('npm-profile')
const npmFetch = require('npm-registry-fetch')
-
+const log = require('../utils/log-shim')
const openUrl = require('../utils/open-url.js')
const otplease = require('../utils/otplease.js')
diff --git a/deps/npm/lib/cli.js b/deps/npm/lib/cli.js
index 9dcd9d04d2ff2c..3d0c32d4beda30 100644
--- a/deps/npm/lib/cli.js
+++ b/deps/npm/lib/cli.js
@@ -4,20 +4,23 @@ module.exports = async process => {
// leak any private CLI configs to other programs
process.title = 'npm'
- const { checkForBrokenNode, checkForUnsupportedNode } = require('../lib/utils/unsupported.js')
-
+ // We used to differentiate between known broken and unsupported
+ // versions of node and attempt to only log unsupported but still run.
+ // After we dropped node 10 support, we can use new features
+ // (like static, private, etc) which will only give vague syntax errors,
+ // so now both broken and unsupported use console, but only broken
+ // will process.exit. It is important to now perform *both* of these
+ // checks as early as possible so the user gets the error message.
+ const { checkForBrokenNode, checkForUnsupportedNode } = require('./utils/unsupported.js')
checkForBrokenNode()
-
- const log = require('npmlog')
- // pause it here so it can unpause when we've loaded the configs
- // and know what loglevel we should be printing.
- log.pause()
-
checkForUnsupportedNode()
- const Npm = require('../lib/npm.js')
+ const exitHandler = require('./utils/exit-handler.js')
+ process.on('uncaughtException', exitHandler)
+ process.on('unhandledRejection', exitHandler)
+
+ const Npm = require('./npm.js')
const npm = new Npm()
- const exitHandler = require('../lib/utils/exit-handler.js')
exitHandler.setNpm(npm)
// if npm is called as "npmg" or "npm_g", then
@@ -26,16 +29,14 @@ module.exports = async process => {
process.argv.splice(1, 1, 'npm', '-g')
}
- const replaceInfo = require('../lib/utils/replace-info.js')
+ const log = require('./utils/log-shim.js')
+ const replaceInfo = require('./utils/replace-info.js')
log.verbose('cli', replaceInfo(process.argv))
log.info('using', 'npm@%s', npm.version)
log.info('using', 'node@%s', process.version)
- process.on('uncaughtException', exitHandler)
- process.on('unhandledRejection', exitHandler)
-
- const updateNotifier = require('../lib/utils/update-notifier.js')
+ const updateNotifier = require('./utils/update-notifier.js')
let cmd
// now actually fire up npm and run the command.
@@ -63,7 +64,7 @@ module.exports = async process => {
}
await npm.exec(cmd, npm.argv)
- exitHandler()
+ return exitHandler()
} catch (err) {
if (err.code === 'EUNKNOWNCOMMAND') {
const didYouMean = require('./utils/did-you-mean.js')
diff --git a/deps/npm/lib/commands/adduser.js b/deps/npm/lib/commands/adduser.js
index 6cd6d3001c0e19..1cf70fffbf5411 100644
--- a/deps/npm/lib/commands/adduser.js
+++ b/deps/npm/lib/commands/adduser.js
@@ -1,4 +1,4 @@
-const log = require('npmlog')
+const log = require('../utils/log-shim.js')
const replaceInfo = require('../utils/replace-info.js')
const BaseCommand = require('../base-command.js')
const authTypes = {
@@ -31,6 +31,7 @@ class AddUser extends BaseCommand {
creds,
registry,
scope,
+ log,
})
await this.updateConfig({
diff --git a/deps/npm/lib/commands/bin.js b/deps/npm/lib/commands/bin.js
index 8f5ae0cc524e33..bb700d45a8f1b4 100644
--- a/deps/npm/lib/commands/bin.js
+++ b/deps/npm/lib/commands/bin.js
@@ -10,6 +10,7 @@ class Bin extends BaseCommand {
const b = this.npm.bin
this.npm.output(b)
if (this.npm.config.get('global') && !envPath.includes(b)) {
+ // XXX: does this need to be console?
console.error('(not in PATH env variable)')
}
}
diff --git a/deps/npm/lib/commands/bugs.js b/deps/npm/lib/commands/bugs.js
index 8ca8188ccd7935..5dfd1eb9189594 100644
--- a/deps/npm/lib/commands/bugs.js
+++ b/deps/npm/lib/commands/bugs.js
@@ -1,5 +1,5 @@
-const log = require('npmlog')
const pacote = require('pacote')
+const log = require('../utils/log-shim')
const openUrl = require('../utils/open-url.js')
const hostedFromMani = require('../utils/hosted-git-info-from-manifest.js')
const BaseCommand = require('../base-command.js')
diff --git a/deps/npm/lib/commands/cache.js b/deps/npm/lib/commands/cache.js
index b1c045bbfae7fb..ecb34cb8916c43 100644
--- a/deps/npm/lib/commands/cache.js
+++ b/deps/npm/lib/commands/cache.js
@@ -1,6 +1,5 @@
const cacache = require('cacache')
const { promisify } = require('util')
-const log = require('npmlog')
const pacote = require('pacote')
const path = require('path')
const rimraf = promisify(require('rimraf'))
@@ -9,6 +8,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('../utils/log-shim')
const searchCachePackage = async (path, spec, cacheKeys) => {
const parsed = npa(spec)
@@ -141,7 +141,7 @@ class Cache extends BaseCommand {
try {
entry = await cacache.get(cachePath, key)
} catch (err) {
- this.npm.log.warn(`Not Found: ${key}`)
+ log.warn(`Not Found: ${key}`)
break
}
this.npm.output(`Deleted: ${key}`)
diff --git a/deps/npm/lib/commands/ci.js b/deps/npm/lib/commands/ci.js
index e928a01d15b541..2c2f8da866653e 100644
--- a/deps/npm/lib/commands/ci.js
+++ b/deps/npm/lib/commands/ci.js
@@ -5,8 +5,7 @@ const reifyFinish = require('../utils/reify-finish.js')
const runScript = require('@npmcli/run-script')
const fs = require('fs')
const readdir = util.promisify(fs.readdir)
-
-const log = require('npmlog')
+const log = require('../utils/log-shim.js')
const removeNodeModules = async where => {
const rimrafOpts = { glob: false }
@@ -39,7 +38,7 @@ class CI extends ArboristWorkspaceCmd {
const opts = {
...this.npm.flatOptions,
path: where,
- log: this.npm.log,
+ log,
save: false, // npm ci should never modify the lockfile or package.json
workspaces: this.workspaceNames,
}
diff --git a/deps/npm/lib/commands/config.js b/deps/npm/lib/commands/config.js
index 0cdcd576f527a6..eb1d570c6ea259 100644
--- a/deps/npm/lib/commands/config.js
+++ b/deps/npm/lib/commands/config.js
@@ -11,6 +11,7 @@ const { spawn } = require('child_process')
const { EOL } = require('os')
const ini = require('ini')
const localeCompare = require('@isaacs/string-locale-compare')('en')
+const log = require('../utils/log-shim.js')
// take an array of `[key, value, k2=v2, k3, v3, ...]` and turn into
// { key: value, k2: v2, k3: v3 }
@@ -87,12 +88,12 @@ class Config extends BaseCommand {
}
async execWorkspaces (args, filters) {
- this.npm.log.warn('config', 'This command does not support workspaces.')
+ log.warn('config', 'This command does not support workspaces.')
return this.exec(args)
}
async exec ([action, ...args]) {
- this.npm.log.disableProgress()
+ log.disableProgress()
try {
switch (action) {
case 'set':
@@ -117,7 +118,7 @@ class Config extends BaseCommand {
throw this.usageError()
}
} finally {
- this.npm.log.enableProgress()
+ log.enableProgress()
}
}
@@ -128,10 +129,10 @@ class Config extends BaseCommand {
const where = this.npm.flatOptions.location
for (const [key, val] of Object.entries(keyValues(args))) {
- this.npm.log.info('config', 'set %j %j', key, val)
+ log.info('config', 'set %j %j', key, val)
this.npm.config.set(key, val || '', where)
if (!this.npm.config.validate(where)) {
- this.npm.log.warn('config', 'omitting invalid config values')
+ log.warn('config', 'omitting invalid config values')
}
}
diff --git a/deps/npm/lib/commands/dedupe.js b/deps/npm/lib/commands/dedupe.js
index e1eafbe3bc58d5..cc4b119d09d2ab 100644
--- a/deps/npm/lib/commands/dedupe.js
+++ b/deps/npm/lib/commands/dedupe.js
@@ -1,6 +1,7 @@
// dedupe duplicated packages, or find them in the tree
const Arborist = require('@npmcli/arborist')
const reifyFinish = require('../utils/reify-finish.js')
+const log = require('../utils/log-shim.js')
const ArboristWorkspaceCmd = require('../arborist-cmd.js')
@@ -32,7 +33,7 @@ class Dedupe extends ArboristWorkspaceCmd {
const where = this.npm.prefix
const opts = {
...this.npm.flatOptions,
- log: this.npm.log,
+ log,
path: where,
dryRun,
workspaces: this.workspaceNames,
diff --git a/deps/npm/lib/commands/diff.js b/deps/npm/lib/commands/diff.js
index 3134f502ea1519..d737a58dc43d8d 100644
--- a/deps/npm/lib/commands/diff.js
+++ b/deps/npm/lib/commands/diff.js
@@ -1,13 +1,11 @@
const { resolve } = require('path')
-
const semver = require('semver')
const libnpmdiff = require('libnpmdiff')
const npa = require('npm-package-arg')
const Arborist = require('@npmcli/arborist')
-const npmlog = require('npmlog')
const pacote = require('pacote')
const pickManifest = require('npm-pick-manifest')
-
+const log = require('../utils/log-shim')
const readPackageName = require('../utils/read-package-name.js')
const BaseCommand = require('../base-command.js')
@@ -57,7 +55,7 @@ class Diff extends BaseCommand {
}
const [a, b] = await this.retrieveSpecs(specs)
- npmlog.info('diff', { src: a, dst: b })
+ log.info('diff', { src: a, dst: b })
const res = await libnpmdiff([a, b], {
...this.npm.flatOptions,
@@ -83,7 +81,7 @@ class Diff extends BaseCommand {
try {
name = await readPackageName(this.prefix)
} catch (e) {
- npmlog.verbose('diff', 'could not read project dir package.json')
+ log.verbose('diff', 'could not read project dir package.json')
}
if (!name) {
@@ -116,7 +114,7 @@ class Diff extends BaseCommand {
try {
pkgName = await readPackageName(this.prefix)
} catch (e) {
- npmlog.verbose('diff', 'could not read project dir package.json')
+ log.verbose('diff', 'could not read project dir package.json')
noPackageJson = true
}
@@ -154,7 +152,7 @@ class Diff extends BaseCommand {
actualTree.inventory.query('name', spec.name)
.values().next().value
} catch (e) {
- npmlog.verbose('diff', 'failed to load actual install tree')
+ log.verbose('diff', 'failed to load actual install tree')
}
if (!node || !node.name || !node.package || !node.package.version) {
@@ -227,7 +225,7 @@ class Diff extends BaseCommand {
try {
pkgName = await readPackageName(this.prefix)
} catch (e) {
- npmlog.verbose('diff', 'could not read project dir package.json')
+ log.verbose('diff', 'could not read project dir package.json')
}
if (!pkgName) {
@@ -261,7 +259,7 @@ class Diff extends BaseCommand {
const arb = new Arborist(opts)
actualTree = await arb.loadActual(opts)
} catch (e) {
- npmlog.verbose('diff', 'failed to load actual install tree')
+ log.verbose('diff', 'failed to load actual install tree')
}
return specs.map(i => {
diff --git a/deps/npm/lib/commands/dist-tag.js b/deps/npm/lib/commands/dist-tag.js
index fa79b293c50d01..bf2dffe9120308 100644
--- a/deps/npm/lib/commands/dist-tag.js
+++ b/deps/npm/lib/commands/dist-tag.js
@@ -1,8 +1,7 @@
-const log = require('npmlog')
const npa = require('npm-package-arg')
const regFetch = require('npm-registry-fetch')
const semver = require('semver')
-
+const log = require('../utils/log-shim')
const otplease = require('../utils/otplease.js')
const readPackageName = require('../utils/read-package-name.js')
const BaseCommand = require('../base-command.js')
diff --git a/deps/npm/lib/commands/docs.js b/deps/npm/lib/commands/docs.js
index 9aba2420571786..19cd7356422625 100644
--- a/deps/npm/lib/commands/docs.js
+++ b/deps/npm/lib/commands/docs.js
@@ -1,8 +1,7 @@
-const log = require('npmlog')
const pacote = require('pacote')
const openUrl = require('../utils/open-url.js')
const hostedFromMani = require('../utils/hosted-git-info-from-manifest.js')
-
+const log = require('../utils/log-shim')
const BaseCommand = require('../base-command.js')
class Docs extends BaseCommand {
static description = 'Open documentation for a package in a web browser'
diff --git a/deps/npm/lib/commands/doctor.js b/deps/npm/lib/commands/doctor.js
index 6b8878b6f4f12e..47a522eb676d0e 100644
--- a/deps/npm/lib/commands/doctor.js
+++ b/deps/npm/lib/commands/doctor.js
@@ -8,6 +8,7 @@ const pacote = require('pacote')
const { resolve } = require('path')
const semver = require('semver')
const { promisify } = require('util')
+const log = require('../utils/log-shim.js')
const ansiTrim = require('../utils/ansi-trim.js')
const isWindows = require('../utils/is-windows.js')
const ping = require('../utils/ping.js')
@@ -42,7 +43,7 @@ class Doctor extends BaseCommand {
static params = ['registry']
async exec (args) {
- this.npm.log.info('Running checkup')
+ log.info('Running checkup')
// each message is [title, ok, message]
const messages = []
@@ -124,7 +125,7 @@ class Doctor extends BaseCommand {
stringLength: s => ansiTrim(s).length,
}
- const silent = this.npm.log.levels[this.npm.log.level] > this.npm.log.levels.error
+ const silent = log.levels[log.level] > log.levels.error
if (!silent) {
this.npm.output(table(outTable, tableOpts))
if (!allOk) {
@@ -137,7 +138,7 @@ class Doctor extends BaseCommand {
}
async checkPing () {
- const tracker = this.npm.log.newItem('checkPing', 1)
+ const tracker = log.newItem('checkPing', 1)
tracker.info('checkPing', 'Pinging registry')
try {
await ping(this.npm.flatOptions)
@@ -154,7 +155,7 @@ class Doctor extends BaseCommand {
}
async getLatestNpmVersion () {
- const tracker = this.npm.log.newItem('getLatestNpmVersion', 1)
+ const tracker = log.newItem('getLatestNpmVersion', 1)
tracker.info('getLatestNpmVersion', 'Getting npm package information')
try {
const latest = (await pacote.manifest('npm@latest', this.npm.flatOptions)).version
@@ -173,7 +174,7 @@ class Doctor extends BaseCommand {
const current = process.version
const currentRange = `^${current}`
const url = 'https://nodejs.org/dist/index.json'
- const tracker = this.npm.log.newItem('getLatestNodejsVersion', 1)
+ const tracker = log.newItem('getLatestNodejsVersion', 1)
tracker.info('getLatestNodejsVersion', 'Getting Node.js release information')
try {
const res = await fetch(url, { method: 'GET', ...this.npm.flatOptions })
@@ -207,7 +208,7 @@ class Doctor extends BaseCommand {
let ok = true
- const tracker = this.npm.log.newItem(root, 1)
+ const tracker = log.newItem(root, 1)
try {
const uid = process.getuid()
@@ -269,7 +270,7 @@ class Doctor extends BaseCommand {
}
async getGitPath () {
- const tracker = this.npm.log.newItem('getGitPath', 1)
+ const tracker = log.newItem('getGitPath', 1)
tracker.info('getGitPath', 'Finding git in your PATH')
try {
return await which('git').catch(er => {
@@ -282,7 +283,7 @@ class Doctor extends BaseCommand {
}
async verifyCachedFiles () {
- const tracker = this.npm.log.newItem('verifyCachedFiles', 1)
+ const tracker = log.newItem('verifyCachedFiles', 1)
tracker.info('verifyCachedFiles', 'Verifying the npm cache')
try {
const stats = await cacache.verify(this.npm.flatOptions.cache)
diff --git a/deps/npm/lib/commands/exec.js b/deps/npm/lib/commands/exec.js
index 515ac910f80e4c..61a6d965954aad 100644
--- a/deps/npm/lib/commands/exec.js
+++ b/deps/npm/lib/commands/exec.js
@@ -1,6 +1,7 @@
const libexec = require('libnpmexec')
const BaseCommand = require('../base-command.js')
const getLocationMsg = require('../exec/get-workspace-location-msg.js')
+const log = require('../utils/log-shim')
// it's like this:
//
@@ -59,7 +60,6 @@ class Exec extends BaseCommand {
const {
flatOptions,
localBin,
- log,
globalBin,
} = this.npm
const output = (...outputArgs) => this.npm.output(...outputArgs)
diff --git a/deps/npm/lib/commands/explore.js b/deps/npm/lib/commands/explore.js
index f94fff01c42ebc..90e6af69fe57ca 100644
--- a/deps/npm/lib/commands/explore.js
+++ b/deps/npm/lib/commands/explore.js
@@ -4,6 +4,7 @@
const rpj = require('read-package-json-fast')
const runScript = require('@npmcli/run-script')
const { join, resolve, relative } = require('path')
+const log = require('../utils/log-shim.js')
const completion = require('../utils/completion/installed-shallow.js')
const BaseCommand = require('../base-command.js')
@@ -37,7 +38,7 @@ class Explore extends BaseCommand {
// handle all the escaping and PATH setup stuff.
const pkg = await rpj(resolve(path, 'package.json')).catch(er => {
- this.npm.log.error('explore', `It doesn't look like ${pkgname} is installed.`)
+ log.error('explore', `It doesn't look like ${pkgname} is installed.`)
throw er
})
@@ -50,7 +51,7 @@ class Explore extends BaseCommand {
if (!args.length) {
this.npm.output(`\nExploring ${path}\nType 'exit' or ^D when finished\n`)
}
- this.npm.log.disableProgress()
+ log.disableProgress()
try {
return await runScript({
...this.npm.flatOptions,
@@ -71,7 +72,7 @@ class Explore extends BaseCommand {
}
})
} finally {
- this.npm.log.enableProgress()
+ log.enableProgress()
}
}
}
diff --git a/deps/npm/lib/commands/fund.js b/deps/npm/lib/commands/fund.js
index 81c6d9a1b07269..47a51c33a6841d 100644
--- a/deps/npm/lib/commands/fund.js
+++ b/deps/npm/lib/commands/fund.js
@@ -5,6 +5,7 @@ const pacote = require('pacote')
const semver = require('semver')
const npa = require('npm-package-arg')
const { depth } = require('treeverse')
+const log = require('../utils/log-shim.js')
const { readTree: getFundingInfo, normalizeFunding, isValidFunding } = require('libnpmfund')
const completion = require('../utils/completion/installed-deep.js')
@@ -68,7 +69,7 @@ class Fund extends ArboristWorkspaceCmd {
// TODO: add !workspacesEnabled option handling to libnpmfund
const fundingInfo = getFundingInfo(tree, {
...this.flatOptions,
- log: this.npm.log,
+ log,
workspaces: this.workspaceNames,
})
diff --git a/deps/npm/lib/commands/init.js b/deps/npm/lib/commands/init.js
index eaca2716ee112f..7e8a8f7a5c8ab8 100644
--- a/deps/npm/lib/commands/init.js
+++ b/deps/npm/lib/commands/init.js
@@ -7,6 +7,7 @@ const rpj = require('read-package-json-fast')
const libexec = require('libnpmexec')
const mapWorkspaces = require('@npmcli/map-workspaces')
const PackageJson = require('@npmcli/package-json')
+const log = require('../utils/log-shim.js')
const getLocationMsg = require('../exec/get-workspace-location-msg.js')
const BaseCommand = require('../base-command.js')
@@ -94,7 +95,6 @@ class Init extends BaseCommand {
const {
flatOptions,
localBin,
- log,
globalBin,
} = this.npm
// this function is definitely called. But because of coverage map stuff
@@ -125,8 +125,8 @@ class Init extends BaseCommand {
}
async template (path = process.cwd()) {
- this.npm.log.pause()
- this.npm.log.disableProgress()
+ log.pause()
+ log.disableProgress()
const initFile = this.npm.config.get('init-module')
if (!this.npm.config.get('yes') && !this.npm.config.get('force')) {
@@ -147,17 +147,17 @@ class Init extends BaseCommand {
// XXX promisify init-package-json
await new Promise((res, rej) => {
initJson(path, initFile, this.npm.config, (er, data) => {
- this.npm.log.resume()
- this.npm.log.enableProgress()
- this.npm.log.silly('package data', data)
+ log.resume()
+ log.enableProgress()
+ log.silly('package data', data)
if (er && er.message === 'canceled') {
- this.npm.log.warn('init', 'canceled')
+ log.warn('init', 'canceled')
return res()
}
if (er) {
rej(er)
} else {
- this.npm.log.info('init', 'written successfully')
+ log.info('init', 'written successfully')
res(data)
}
})
diff --git a/deps/npm/lib/commands/install.js b/deps/npm/lib/commands/install.js
index 02ccb572483414..a92a5edc5ebb77 100644
--- a/deps/npm/lib/commands/install.js
+++ b/deps/npm/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('npmlog')
+const log = require('../utils/log-shim.js')
const { resolve, join } = require('path')
const Arborist = require('@npmcli/arborist')
const runScript = require('@npmcli/run-script')
@@ -118,7 +118,7 @@ class Install extends ArboristWorkspaceCmd {
checks.checkEngine(npmManifest, npmManifest.version, process.version)
} catch (e) {
if (forced) {
- this.npm.log.warn(
+ log.warn(
'install',
/* eslint-disable-next-line max-len */
`Forcing global npm install with incompatible version ${npmManifest.version} into node ${process.version}`
@@ -147,7 +147,7 @@ class Install extends ArboristWorkspaceCmd {
const opts = {
...this.npm.flatOptions,
- log: this.npm.log,
+ log,
auditLevel: null,
path: where,
add: args,
diff --git a/deps/npm/lib/commands/link.js b/deps/npm/lib/commands/link.js
index 8755af6f68266e..e8e2c6b349aa9c 100644
--- a/deps/npm/lib/commands/link.js
+++ b/deps/npm/lib/commands/link.js
@@ -7,6 +7,7 @@ const Arborist = require('@npmcli/arborist')
const npa = require('npm-package-arg')
const rpj = require('read-package-json-fast')
const semver = require('semver')
+const log = require('../utils/log-shim.js')
const reifyFinish = require('../utils/reify-finish.js')
@@ -68,7 +69,7 @@ class Link extends ArboristWorkspaceCmd {
const globalOpts = {
...this.npm.flatOptions,
path: globalTop,
- log: this.npm.log,
+ log,
global: true,
prune: false,
}
@@ -117,7 +118,7 @@ class Link extends ArboristWorkspaceCmd {
const localArb = new Arborist({
...this.npm.flatOptions,
prune: false,
- log: this.npm.log,
+ log,
path: this.npm.prefix,
save,
})
@@ -125,7 +126,7 @@ class Link extends ArboristWorkspaceCmd {
...this.npm.flatOptions,
prune: false,
path: this.npm.prefix,
- log: this.npm.log,
+ log,
add: names.map(l => `file:${resolve(globalTop, 'node_modules', l)}`),
save,
workspaces: this.workspaceNames,
@@ -142,12 +143,12 @@ class Link extends ArboristWorkspaceCmd {
const arb = new Arborist({
...this.npm.flatOptions,
path: globalTop,
- log: this.npm.log,
+ log,
global: true,
})
await arb.reify({
add,
- log: this.npm.log,
+ log,
})
await reifyFinish(this.npm, arb)
}
diff --git a/deps/npm/lib/commands/logout.js b/deps/npm/lib/commands/logout.js
index e17b2b879002c7..4e6bab9859551c 100644
--- a/deps/npm/lib/commands/logout.js
+++ b/deps/npm/lib/commands/logout.js
@@ -1,6 +1,6 @@
-const log = require('npmlog')
const getAuth = require('npm-registry-fetch/auth.js')
const npmFetch = require('npm-registry-fetch')
+const log = require('../utils/log-shim')
const BaseCommand = require('../base-command.js')
class Logout extends BaseCommand {
diff --git a/deps/npm/lib/commands/owner.js b/deps/npm/lib/commands/owner.js
index 8f0b1f1eff6861..c027ad6464557c 100644
--- a/deps/npm/lib/commands/owner.js
+++ b/deps/npm/lib/commands/owner.js
@@ -1,8 +1,7 @@
-const log = require('npmlog')
const npa = require('npm-package-arg')
const npmFetch = require('npm-registry-fetch')
const pacote = require('pacote')
-
+const log = require('../utils/log-shim')
const otplease = require('../utils/otplease.js')
const readLocalPkgName = require('../utils/read-package-name.js')
const BaseCommand = require('../base-command.js')
diff --git a/deps/npm/lib/commands/pack.js b/deps/npm/lib/commands/pack.js
index d84dde86e83eca..0719fa3b858285 100644
--- a/deps/npm/lib/commands/pack.js
+++ b/deps/npm/lib/commands/pack.js
@@ -1,14 +1,11 @@
const util = require('util')
-const log = require('npmlog')
const pacote = require('pacote')
const libpack = require('libnpmpack')
const npa = require('npm-package-arg')
const path = require('path')
-
+const log = require('../utils/log-shim')
const { getContents, logTar } = require('../utils/tar.js')
-
const writeFile = util.promisify(require('fs').writeFile)
-
const BaseCommand = require('../base-command.js')
class Pack extends BaseCommand {
@@ -70,7 +67,7 @@ class Pack extends BaseCommand {
}
for (const tar of tarballs) {
- logTar(tar, { log, unicode })
+ logTar(tar, { unicode })
this.npm.output(tar.filename.replace(/^@/, '').replace(/\//, '-'))
}
}
@@ -82,7 +79,7 @@ class Pack extends BaseCommand {
const useWorkspaces = args.length === 0 || args.includes('.')
if (!useWorkspaces) {
- this.npm.log.warn('Ignoring workspaces for specified package(s)')
+ log.warn('Ignoring workspaces for specified package(s)')
return this.exec(args)
}
diff --git a/deps/npm/lib/commands/ping.js b/deps/npm/lib/commands/ping.js
index a049d24127dafb..993e029d45651a 100644
--- a/deps/npm/lib/commands/ping.js
+++ b/deps/npm/lib/commands/ping.js
@@ -1,4 +1,4 @@
-const log = require('npmlog')
+const log = require('../utils/log-shim')
const pingUtil = require('../utils/ping.js')
const BaseCommand = require('../base-command.js')
diff --git a/deps/npm/lib/commands/profile.js b/deps/npm/lib/commands/profile.js
index 0939013cc2c61e..1250ed7d1c756b 100644
--- a/deps/npm/lib/commands/profile.js
+++ b/deps/npm/lib/commands/profile.js
@@ -1,7 +1,7 @@
const inspect = require('util').inspect
const { URL } = require('url')
const ansistyles = require('ansistyles')
-const log = require('npmlog')
+const log = require('../utils/log-shim.js')
const npmProfile = require('npm-profile')
const qrcodeTerminal = require('qrcode-terminal')
const Table = require('cli-table3')
@@ -321,7 +321,7 @@ class Profile extends BaseCommand {
} else if (userInfo && userInfo.tfa) {
if (!conf.otp) {
conf.otp = await readUserInfo.otp(
- 'Enter one-time password from your authenticator app: '
+ 'Enter one-time password: '
)
}
}
@@ -386,7 +386,7 @@ class Profile extends BaseCommand {
const password = await readUserInfo.password()
if (!conf.otp) {
- const msg = 'Enter one-time password from your authenticator app: '
+ const msg = 'Enter one-time password: '
conf.otp = await readUserInfo.otp(msg)
}
diff --git a/deps/npm/lib/commands/prune.js b/deps/npm/lib/commands/prune.js
index 403575e024b277..5831df62859c23 100644
--- a/deps/npm/lib/commands/prune.js
+++ b/deps/npm/lib/commands/prune.js
@@ -1,5 +1,6 @@
// prune extraneous packages
const Arborist = require('@npmcli/arborist')
+const log = require('../utils/log-shim.js')
const reifyFinish = require('../utils/reify-finish.js')
const ArboristWorkspaceCmd = require('../arborist-cmd.js')
@@ -14,7 +15,7 @@ class Prune extends ArboristWorkspaceCmd {
const opts = {
...this.npm.flatOptions,
path: where,
- log: this.npm.log,
+ log,
workspaces: this.workspaceNames,
}
const arb = new Arborist(opts)
diff --git a/deps/npm/lib/commands/publish.js b/deps/npm/lib/commands/publish.js
index 88ddcae7bbdf2d..ad538668b63a38 100644
--- a/deps/npm/lib/commands/publish.js
+++ b/deps/npm/lib/commands/publish.js
@@ -1,5 +1,5 @@
const util = require('util')
-const log = require('npmlog')
+const log = require('../utils/log-shim.js')
const semver = require('semver')
const pack = require('libnpmpack')
const libpub = require('libnpmpublish').publish
@@ -94,10 +94,10 @@ class Publish extends BaseCommand {
flatten(manifest.publishConfig, opts)
}
- // note that logTar calls npmlog.notice(), so if we ARE in silent mode,
+ // note that logTar calls log.notice(), so if we ARE in silent mode,
// this will do nothing, but we still want it in the debuglog if it fails.
if (!json) {
- logTar(pkgContents, { log, unicode })
+ logTar(pkgContents, { unicode })
}
if (!dryRun) {
diff --git a/deps/npm/lib/commands/repo.js b/deps/npm/lib/commands/repo.js
index cc68e856502352..8ac4178f261ee1 100644
--- a/deps/npm/lib/commands/repo.js
+++ b/deps/npm/lib/commands/repo.js
@@ -1,7 +1,6 @@
-const log = require('npmlog')
const pacote = require('pacote')
const { URL } = require('url')
-
+const log = require('../utils/log-shim')
const hostedFromMani = require('../utils/hosted-git-info-from-manifest.js')
const openUrl = require('../utils/open-url.js')
diff --git a/deps/npm/lib/commands/run-script.js b/deps/npm/lib/commands/run-script.js
index 37140c8c539c64..cd877e0b3dfa4b 100644
--- a/deps/npm/lib/commands/run-script.js
+++ b/deps/npm/lib/commands/run-script.js
@@ -3,7 +3,7 @@ const chalk = require('chalk')
const runScript = require('@npmcli/run-script')
const { isServerPackage } = runScript
const rpj = require('read-package-json-fast')
-const log = require('npmlog')
+const log = require('../utils/log-shim.js')
const didYouMean = require('../utils/did-you-mean.js')
const isWindowsShell = require('../utils/is-windows-shell.js')
diff --git a/deps/npm/lib/commands/search.js b/deps/npm/lib/commands/search.js
index ff533ebbd1c1b5..bdeeffe816980f 100644
--- a/deps/npm/lib/commands/search.js
+++ b/deps/npm/lib/commands/search.js
@@ -1,7 +1,7 @@
const Minipass = require('minipass')
const Pipeline = require('minipass-pipeline')
const libSearch = require('libnpmsearch')
-const log = require('npmlog')
+const log = require('../utils/log-shim.js')
const formatPackageStream = require('../search/format-package-stream.js')
const packageFilter = require('../search/package-filter.js')
diff --git a/deps/npm/lib/commands/set-script.js b/deps/npm/lib/commands/set-script.js
index 58fd2726db6010..7c73ff01b9396e 100644
--- a/deps/npm/lib/commands/set-script.js
+++ b/deps/npm/lib/commands/set-script.js
@@ -1,7 +1,7 @@
const { resolve } = require('path')
-const log = require('npmlog')
const rpj = require('read-package-json-fast')
const PackageJson = require('@npmcli/package-json')
+const log = require('../utils/log-shim')
const BaseCommand = require('../base-command.js')
class SetScript extends BaseCommand {
diff --git a/deps/npm/lib/commands/shrinkwrap.js b/deps/npm/lib/commands/shrinkwrap.js
index dfb3c8e3815973..05e3f6d278618a 100644
--- a/deps/npm/lib/commands/shrinkwrap.js
+++ b/deps/npm/lib/commands/shrinkwrap.js
@@ -1,8 +1,7 @@
const { resolve, basename } = require('path')
const { unlink } = require('fs').promises
const Arborist = require('@npmcli/arborist')
-const log = require('npmlog')
-
+const log = require('../utils/log-shim')
const BaseCommand = require('../base-command.js')
class Shrinkwrap extends BaseCommand {
static description = 'Lock down dependency versions for publication'
diff --git a/deps/npm/lib/commands/star.js b/deps/npm/lib/commands/star.js
index 1bbd25efdafb81..ec116058994373 100644
--- a/deps/npm/lib/commands/star.js
+++ b/deps/npm/lib/commands/star.js
@@ -1,7 +1,6 @@
const fetch = require('npm-registry-fetch')
-const log = require('npmlog')
const npa = require('npm-package-arg')
-
+const log = require('../utils/log-shim')
const getIdentity = require('../utils/get-identity')
const BaseCommand = require('../base-command.js')
diff --git a/deps/npm/lib/commands/stars.js b/deps/npm/lib/commands/stars.js
index 1260655d073238..f45ec846dc7fe3 100644
--- a/deps/npm/lib/commands/stars.js
+++ b/deps/npm/lib/commands/stars.js
@@ -1,6 +1,5 @@
-const log = require('npmlog')
const fetch = require('npm-registry-fetch')
-
+const log = require('../utils/log-shim')
const getIdentity = require('../utils/get-identity.js')
const BaseCommand = require('../base-command.js')
diff --git a/deps/npm/lib/commands/token.js b/deps/npm/lib/commands/token.js
index db2374203831c0..df80f1afec44ee 100644
--- a/deps/npm/lib/commands/token.js
+++ b/deps/npm/lib/commands/token.js
@@ -1,7 +1,7 @@
const Table = require('cli-table3')
const ansistyles = require('ansistyles')
const { v4: isCidrV4, v6: isCidrV6 } = require('is-cidr')
-const log = require('npmlog')
+const log = require('../utils/log-shim.js')
const profile = require('npm-profile')
const otplease = require('../utils/otplease.js')
diff --git a/deps/npm/lib/commands/uninstall.js b/deps/npm/lib/commands/uninstall.js
index dba45e127a7a7c..b40c59bda44198 100644
--- a/deps/npm/lib/commands/uninstall.js
+++ b/deps/npm/lib/commands/uninstall.js
@@ -1,4 +1,5 @@
const { resolve } = require('path')
+const log = require('../utils/log-shim.js')
const Arborist = require('@npmcli/arborist')
const rpj = require('read-package-json-fast')
@@ -48,7 +49,7 @@ class Uninstall extends ArboristWorkspaceCmd {
const opts = {
...this.npm.flatOptions,
path,
- log: this.npm.log,
+ log,
rm: args,
workspaces: this.workspaceNames,
}
diff --git a/deps/npm/lib/commands/unpublish.js b/deps/npm/lib/commands/unpublish.js
index 3636dc58a69482..578890025d2249 100644
--- a/deps/npm/lib/commands/unpublish.js
+++ b/deps/npm/lib/commands/unpublish.js
@@ -5,7 +5,7 @@ const libaccess = require('libnpmaccess')
const npmFetch = require('npm-registry-fetch')
const libunpub = require('libnpmpublish').unpublish
const readJson = util.promisify(require('read-package-json'))
-
+const log = require('../utils/log-shim')
const otplease = require('../utils/otplease.js')
const getIdentity = require('../utils/get-identity.js')
@@ -66,8 +66,8 @@ class Unpublish extends BaseCommand {
let pkgName
let pkgVersion
- this.npm.log.silly('unpublish', 'args[0]', args[0])
- this.npm.log.silly('unpublish', 'spec', spec)
+ log.silly('unpublish', 'args[0]', args[0])
+ log.silly('unpublish', 'spec', spec)
if ((!spec || !spec.rawSpec) && !force) {
throw this.usageError(
@@ -92,7 +92,7 @@ class Unpublish extends BaseCommand {
}
}
- this.npm.log.verbose('unpublish', manifest)
+ log.verbose('unpublish', manifest)
const { name, version, publishConfig } = manifest
const pkgJsonSpec = npa.resolve(name, version)
diff --git a/deps/npm/lib/commands/update.js b/deps/npm/lib/commands/update.js
index 4bb74990bea20e..a8bbc4c969251d 100644
--- a/deps/npm/lib/commands/update.js
+++ b/deps/npm/lib/commands/update.js
@@ -1,7 +1,7 @@
const path = require('path')
const Arborist = require('@npmcli/arborist')
-const log = require('npmlog')
+const log = require('../utils/log-shim.js')
const reifyFinish = require('../utils/reify-finish.js')
const completion = require('../utils/completion/installed-deep.js')
@@ -47,7 +47,7 @@ class Update extends ArboristWorkspaceCmd {
const arb = new Arborist({
...this.npm.flatOptions,
- log: this.npm.log,
+ log,
path: where,
workspaces: this.workspaceNames,
})
diff --git a/deps/npm/lib/commands/view.js b/deps/npm/lib/commands/view.js
index 105ebc16dfc699..4f7464ddd76c19 100644
--- a/deps/npm/lib/commands/view.js
+++ b/deps/npm/lib/commands/view.js
@@ -4,7 +4,7 @@ const color = require('ansicolors')
const columns = require('cli-columns')
const fs = require('fs')
const jsonParse = require('json-parse-even-better-errors')
-const log = require('npmlog')
+const log = require('../utils/log-shim.js')
const npa = require('npm-package-arg')
const { resolve } = require('path')
const formatBytes = require('../utils/format-bytes.js')
@@ -139,7 +139,7 @@ class View extends BaseCommand {
const local = /^\.@/.test(pkg) || pkg === '.'
if (!local) {
- this.npm.log.warn('Ignoring workspaces for specified package(s)')
+ log.warn('Ignoring workspaces for specified package(s)')
return this.exec([pkg, ...args])
}
let wholePackument = false
diff --git a/deps/npm/lib/npm.js b/deps/npm/lib/npm.js
index ecc7f0a7de2066..4d22b531a4662c 100644
--- a/deps/npm/lib/npm.js
+++ b/deps/npm/lib/npm.js
@@ -1,34 +1,10 @@
const EventEmitter = require('events')
const { resolve, dirname } = require('path')
const Config = require('@npmcli/config')
-const log = require('npmlog')
// Patch the global fs module here at the app level
require('graceful-fs').gracefulify(require('fs'))
-// TODO make this only ever load once (or unload) in tests
-const procLogListener = require('./utils/proc-log-listener.js')
-
-// Timers in progress
-const timers = new Map()
-// Finished timers
-const timings = {}
-
-const processOnTimeHandler = name => {
- timers.set(name, Date.now())
-}
-
-const processOnTimeEndHandler = name => {
- if (timers.has(name)) {
- const ms = Date.now() - timers.get(name)
- log.timing(name, `Completed in ${ms}ms`)
- timings[name] = ms
- timers.delete(name)
- } else {
- log.silly('timing', "Tried to end timer that doesn't exist:", name)
- }
-}
-
const { definitions, flatten, shorthands } = require('./utils/config/index.js')
const { shellouts } = require('./utils/cmd-list.js')
const usage = require('./utils/npm-usage.js')
@@ -36,9 +12,11 @@ const usage = require('./utils/npm-usage.js')
const which = require('which')
const deref = require('./utils/deref-command.js')
-const setupLog = require('./utils/setup-log.js')
-const cleanUpLogFiles = require('./utils/cleanup-log-files.js')
-const getProjectScope = require('./utils/get-project-scope.js')
+const LogFile = require('./utils/log-file.js')
+const Timers = require('./utils/timers.js')
+const Display = require('./utils/display.js')
+const log = require('./utils/log-shim')
+const replaceInfo = require('./utils/replace-info.js')
let warnedNonDashArg = false
const _load = Symbol('_load')
@@ -51,21 +29,30 @@ class Npm extends EventEmitter {
return pkg.version
}
+ #unloaded = false
+ #timers = null
+ #logFile = null
+ #display = null
+
constructor () {
super()
- this.started = Date.now()
this.command = null
- this.timings = timings
- this.timers = timers
- process.on('time', processOnTimeHandler)
- process.on('timeEnd', processOnTimeEndHandler)
- procLogListener()
- process.emit('time', 'npm')
+ this.#logFile = new LogFile()
+ this.#display = new Display()
+ this.#timers = new Timers({
+ start: 'npm',
+ listener: (name, ms) => {
+ const args = ['timing', name, `Completed in ${ms}ms`]
+ this.#logFile.log(...args)
+ this.#display.log(...args)
+ },
+ })
this.config = new Config({
npmPath: dirname(__dirname),
definitions,
flatten,
shorthands,
+ log,
})
this[_title] = process.title
this.updateNotification = null
@@ -118,7 +105,7 @@ class Npm extends EventEmitter {
.filter(arg => /^[\u2010-\u2015\u2212\uFE58\uFE63\uFF0D]/.test(arg))
.forEach(arg => {
warnedNonDashArg = true
- this.log.error(
+ log.error(
'arg',
'Argument starts with non-ascii dash, this is probably invalid:',
arg
@@ -165,14 +152,13 @@ class Npm extends EventEmitter {
async load () {
if (!this.loadPromise) {
process.emit('time', 'npm:load')
- this.log.pause()
this.loadPromise = new Promise((resolve, reject) => {
this[_load]()
.catch(er => er)
.then(er => {
this.loadErr = er
if (!er && this.config.get('force')) {
- this.log.warn('using --force', 'Recommended protections disabled.')
+ log.warn('using --force', 'Recommended protections disabled.')
}
process.emit('timeEnd', 'npm:load')
@@ -190,6 +176,34 @@ class Npm extends EventEmitter {
return this.config.loaded
}
+ // This gets called at the end of the exit handler and
+ // during any tests to cleanup all of our listeners
+ // Everything in here should be synchronous
+ unload () {
+ // Track if we've already unloaded so we dont
+ // write multiple timing files. This is only an
+ // issue in tests right now since we unload
+ // in both tap teardowns and the exit handler
+ if (this.#unloaded) {
+ return
+ }
+ this.#timers.off()
+ this.#display.off()
+ this.#logFile.off()
+ if (this.loaded && this.config.get('timing')) {
+ this.#timers.writeFile({
+ command: process.argv.slice(2),
+ // We used to only ever report a single log file
+ // so to be backwards compatible report the last logfile
+ // XXX: remove this in npm 9 or just keep it forever
+ logfile: this.logFiles[this.logFiles.length - 1],
+ logfiles: this.logFiles,
+ version: this.version,
+ })
+ }
+ this.#unloaded = true
+ }
+
get title () {
return this[_title]
}
@@ -204,12 +218,12 @@ class Npm extends EventEmitter {
let node
try {
node = which.sync(process.argv[0])
- } catch (_) {
+ } catch {
// TODO should we throw here?
}
process.emit('timeEnd', 'npm:load:whichnode')
if (node && node.toUpperCase() !== process.execPath.toUpperCase()) {
- this.log.verbose('node symlink', node)
+ log.verbose('node symlink', node)
process.execPath = node
this.config.execPath = node
}
@@ -229,19 +243,35 @@ class Npm extends EventEmitter {
const tokrev = deref(this.argv[0]) === 'token' && this.argv[1] === 'revoke'
this.title = tokrev
? 'npm token revoke' + (this.argv[2] ? ' ***' : '')
- : ['npm', ...this.argv].join(' ')
+ : replaceInfo(['npm', ...this.argv].join(' '))
process.emit('timeEnd', 'npm:load:setTitle')
- process.emit('time', 'npm:load:setupLog')
- setupLog(this.config)
- process.emit('timeEnd', 'npm:load:setupLog')
+ process.emit('time', 'npm:load:display')
+ this.#display.load({
+ // Use logColor since that is based on stderr
+ color: this.logColor,
+ progress: this.flatOptions.progress,
+ timing: this.config.get('timing'),
+ loglevel: this.config.get('loglevel'),
+ unicode: this.config.get('unicode'),
+ heading: this.config.get('heading'),
+ })
+ process.emit('timeEnd', 'npm:load:display')
process.env.COLOR = this.color ? '1' : '0'
- process.emit('time', 'npm:load:cleanupLog')
- cleanUpLogFiles(this.cache, this.config.get('logs-max'), this.log.warn)
- process.emit('timeEnd', 'npm:load:cleanupLog')
+ process.emit('time', 'npm:load:logFile')
+ this.#logFile.load({
+ dir: resolve(this.cache, '_logs'),
+ logsMax: this.config.get('logs-max'),
+ })
+ log.verbose('logfile', this.#logFile.files[0])
+ process.emit('timeEnd', 'npm:load:logFile')
- this.log.resume()
+ process.emit('time', 'npm:load:timers')
+ this.#timers.load({
+ dir: this.cache,
+ })
+ process.emit('timeEnd', 'npm:load:timers')
process.emit('time', 'npm:load:configScope')
const configScope = this.config.get('scope')
@@ -249,10 +279,6 @@ class Npm extends EventEmitter {
this.config.set('scope', `@${configScope}`, this.config.find('scope'))
}
process.emit('timeEnd', 'npm:load:configScope')
-
- process.emit('time', 'npm:load:projectScope')
- this.projectScope = this.config.get('scope') || getProjectScope(this.prefix)
- process.emit('timeEnd', 'npm:load:projectScope')
}
get flatOptions () {
@@ -263,18 +289,35 @@ class Npm extends EventEmitter {
return flat
}
+ // color and logColor are a special derived values that takes into
+ // consideration not only the config, but whether or not we are operating
+ // in a tty with the associated output (stdout/stderr)
get color () {
- // This is a special derived value that takes into consideration not only
- // the config, but whether or not we are operating in a tty.
return this.flatOptions.color
}
+ get logColor () {
+ return this.flatOptions.logColor
+ }
+
get lockfileVersion () {
return 2
}
- get log () {
- return log
+ get unfinishedTimers () {
+ return this.#timers.unfinished
+ }
+
+ get finishedTimers () {
+ return this.#timers.finished
+ }
+
+ get started () {
+ return this.#timers.started
+ }
+
+ get logFiles () {
+ return this.#logFile.files
}
get cache () {
@@ -352,9 +395,10 @@ class Npm extends EventEmitter {
// output to stdout in a progress bar compatible way
output (...msg) {
- this.log.clearProgress()
+ log.clearProgress()
+ // eslint-disable-next-line no-console
console.log(...msg)
- this.log.showProgress()
+ log.showProgress()
}
}
module.exports = Npm
diff --git a/deps/npm/lib/utils/audit-error.js b/deps/npm/lib/utils/audit-error.js
index b4ab26fd0c6979..7feccc739b6a9f 100644
--- a/deps/npm/lib/utils/audit-error.js
+++ b/deps/npm/lib/utils/audit-error.js
@@ -1,3 +1,5 @@
+const log = require('./log-shim')
+
// print an error or just nothing if the audit report has an error
// this is called by the audit command, and by the reify-output util
// prints a JSON version of the error if it's --json
@@ -15,7 +17,7 @@ const auditError = (npm, report) => {
const { error } = report
// ok, we care about it, then
- npm.log.warn('audit', error.message)
+ log.warn('audit', error.message)
const { body: errBody } = error
const body = Buffer.isBuffer(errBody) ? errBody.toString() : errBody
if (npm.flatOptions.json) {
diff --git a/deps/npm/lib/utils/cleanup-log-files.js b/deps/npm/lib/utils/cleanup-log-files.js
deleted file mode 100644
index 8fb0fa1550281c..00000000000000
--- a/deps/npm/lib/utils/cleanup-log-files.js
+++ /dev/null
@@ -1,35 +0,0 @@
-// module to clean out the old log files in cache/_logs
-// this is a best-effort attempt. if a rm fails, we just
-// log a message about it and move on. We do return a
-// Promise that succeeds when we've tried to delete everything,
-// just for the benefit of testing this function properly.
-
-const { resolve } = require('path')
-const rimraf = require('rimraf')
-const glob = require('glob')
-module.exports = (cache, max, warn) => {
- return new Promise(done => {
- glob(resolve(cache, '_logs', '*-debug.log'), (er, files) => {
- if (er) {
- return done()
- }
-
- let pending = files.length - max
- if (pending <= 0) {
- return done()
- }
-
- for (let i = 0; i < files.length - max; i++) {
- rimraf(files[i], er => {
- if (er) {
- warn('log', 'failed to remove log file', files[i])
- }
-
- if (--pending === 0) {
- done()
- }
- })
- }
- })
- })
-}
diff --git a/deps/npm/lib/utils/config/definitions.js b/deps/npm/lib/utils/config/definitions.js
index b47a46de85e2e8..ac8a4e2f6749d5 100644
--- a/deps/npm/lib/utils/config/definitions.js
+++ b/deps/npm/lib/utils/config/definitions.js
@@ -472,7 +472,10 @@ define('color', {
flatten (key, obj, flatOptions) {
flatOptions.color = !obj.color ? false
: obj.color === 'always' ? true
- : process.stdout.isTTY
+ : !!process.stdout.isTTY
+ flatOptions.logColor = !obj.color ? false
+ : obj.color === 'always' ? true
+ : !!process.stderr.isTTY
},
})
@@ -1211,8 +1214,8 @@ define('loglevel', {
'silly',
],
description: `
- What level of logs to report. On failure, *all* logs are written to
- \`npm-debug.log\` in the current working directory.
+ What level of logs to report. All logs are written to a debug log,
+ with the path to that file printed if the execution of a command fails.
Any logs of a higher level than the setting are shown. The default is
"notice".
@@ -1533,6 +1536,10 @@ define('progress', {
Set to \`false\` to suppress the progress bar.
`,
+ flatten (key, obj, flatOptions) {
+ flatOptions.progress = !obj.progress ? false
+ : !!process.stderr.isTTY && process.env.TERM !== 'dumb'
+ },
})
define('proxy', {
@@ -1681,7 +1688,7 @@ define('save-peer', {
default: false,
type: Boolean,
description: `
- Save installed packages. to a package.json file as \`peerDependencies\`
+ Save installed packages to a package.json file as \`peerDependencies\`
`,
flatten (key, obj, flatOptions) {
if (!obj[key]) {
@@ -1782,7 +1789,10 @@ define('scope', {
`,
flatten (key, obj, flatOptions) {
const value = obj[key]
- flatOptions.projectScope = value && !/^@/.test(value) ? `@${value}` : value
+ const scope = value && !/^@/.test(value) ? `@${value}` : value
+ flatOptions.scope = scope
+ // projectScope is kept for compatibility with npm-registry-fetch
+ flatOptions.projectScope = scope
},
})
diff --git a/deps/npm/lib/utils/deref-command.js b/deps/npm/lib/utils/deref-command.js
index dd89fb5a4f2b25..0a3c8c90bc903d 100644
--- a/deps/npm/lib/utils/deref-command.js
+++ b/deps/npm/lib/utils/deref-command.js
@@ -1,6 +1,6 @@
// de-reference abbreviations and shorthands into canonical command name
-const { aliases, cmdList, plumbing } = require('../utils/cmd-list.js')
+const { aliases, cmdList, plumbing } = require('./cmd-list.js')
const aliasNames = Object.keys(aliases)
const fullList = cmdList.concat(aliasNames).filter(c => !plumbing.includes(c))
const abbrev = require('abbrev')
diff --git a/deps/npm/lib/utils/display.js b/deps/npm/lib/utils/display.js
new file mode 100644
index 00000000000000..aae51e8806f8a3
--- /dev/null
+++ b/deps/npm/lib/utils/display.js
@@ -0,0 +1,119 @@
+const { inspect } = require('util')
+const npmlog = require('npmlog')
+const log = require('./log-shim.js')
+const { explain } = require('./explain-eresolve.js')
+
+const _logHandler = Symbol('logHandler')
+const _eresolveWarn = Symbol('eresolveWarn')
+const _log = Symbol('log')
+const _npmlog = Symbol('npmlog')
+
+class Display {
+ constructor () {
+ // pause by default until config is loaded
+ this.on()
+ log.pause()
+ }
+
+ on () {
+ process.on('log', this[_logHandler])
+ }
+
+ off () {
+ process.off('log', this[_logHandler])
+ // Unbalanced calls to enable/disable progress
+ // will leave change listeners on the tracker
+ // This pretty much only happens in tests but
+ // this removes the event emitter listener warnings
+ log.tracker.removeAllListeners()
+ }
+
+ load (config) {
+ const {
+ color,
+ timing,
+ loglevel,
+ unicode,
+ progress,
+ heading = 'npm',
+ } = config
+
+ // XXX: decouple timing from loglevel
+ if (timing && loglevel === 'notice') {
+ log.level = 'timing'
+ } else {
+ log.level = loglevel
+ }
+
+ log.heading = heading
+
+ if (color) {
+ log.enableColor()
+ } else {
+ log.disableColor()
+ }
+
+ if (unicode) {
+ log.enableUnicode()
+ } else {
+ log.disableUnicode()
+ }
+
+ // if it's more than error, don't show progress
+ const silent = log.levels[log.level] > log.levels.error
+ if (progress && !silent) {
+ log.enableProgress()
+ } else {
+ log.disableProgress()
+ }
+
+ // Resume displaying logs now that we have config
+ log.resume()
+ }
+
+ log (...args) {
+ this[_logHandler](...args)
+ }
+
+ [_logHandler] = (level, ...args) => {
+ try {
+ this[_log](level, ...args)
+ } catch (ex) {
+ try {
+ // if it crashed once, it might again!
+ this[_npmlog]('verbose', `attempt to log ${inspect(args)} crashed`, ex)
+ } catch (ex2) {
+ // eslint-disable-next-line no-console
+ console.error(`attempt to log ${inspect(args)} crashed`, ex, ex2)
+ }
+ }
+ }
+
+ [_log] (...args) {
+ return this[_eresolveWarn](...args) || this[_npmlog](...args)
+ }
+
+ // Explicitly call these on npmlog and not log shim
+ // This is the final place we should call npmlog before removing it.
+ [_npmlog] (level, ...args) {
+ npmlog[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.
+ [_eresolveWarn] (level, heading, message, expl) {
+ if (level === 'warn' &&
+ heading === 'ERESOLVE' &&
+ expl && typeof expl === 'object'
+ ) {
+ this[_npmlog](level, heading, message)
+ this[_npmlog](level, '', explain(expl, log.useColor(), 2))
+ // Return true to short circuit other log in chain
+ return true
+ }
+ }
+}
+
+module.exports = Display
diff --git a/deps/npm/lib/utils/error-message.js b/deps/npm/lib/utils/error-message.js
index 48ad4676f471e2..4d584346d0f3bd 100644
--- a/deps/npm/lib/utils/error-message.js
+++ b/deps/npm/lib/utils/error-message.js
@@ -1,9 +1,9 @@
const { format } = require('util')
const { resolve } = require('path')
const nameValidator = require('validate-npm-package-name')
-const npmlog = require('npmlog')
const replaceInfo = require('./replace-info.js')
const { report } = require('./explain-eresolve.js')
+const log = require('./log-shim')
module.exports = (er, npm) => {
const short = []
@@ -20,7 +20,10 @@ module.exports = (er, npm) => {
case 'ERESOLVE':
short.push(['ERESOLVE', er.message])
detail.push(['', ''])
- detail.push(['', report(er, npm.color, resolve(npm.cache, 'eresolve-report.txt'))])
+ // XXX(display): error messages are logged so we use the logColor since that is based
+ // on stderr. This should be handled solely by the display layer so it could also be
+ // printed to stdout if necessary.
+ detail.push(['', report(er, !!npm.logColor, resolve(npm.cache, 'eresolve-report.txt'))])
break
case 'ENOLOCK': {
@@ -61,7 +64,7 @@ module.exports = (er, npm) => {
if (!isWindows && (isCachePath || isCacheDest)) {
// user probably doesn't need this, but still add it to the debug log
- npmlog.verbose(er.stack)
+ log.verbose(er.stack)
short.push([
'',
[
diff --git a/deps/npm/lib/utils/exit-handler.js b/deps/npm/lib/utils/exit-handler.js
index 5b2811468eca39..32434662422ae9 100644
--- a/deps/npm/lib/utils/exit-handler.js
+++ b/deps/npm/lib/utils/exit-handler.js
@@ -1,119 +1,108 @@
const os = require('os')
-const path = require('path')
-const writeFileAtomic = require('write-file-atomic')
-const mkdirp = require('mkdirp-infer-owner')
-const fs = require('graceful-fs')
+const log = require('./log-shim.js')
const errorMessage = require('./error-message.js')
const replaceInfo = require('./replace-info.js')
-let exitHandlerCalled = false
-let logFileName
-let npm // set by the cli
-let wroteLogFile = false
-
-const getLogFile = () => {
- // we call this multiple times, so we need to treat it as a singleton because
- // the date is part of the name
- if (!logFileName) {
- logFileName = path.resolve(
- npm.config.get('cache'),
- '_logs',
- new Date().toISOString().replace(/[.:]/g, '_') + '-debug.log'
- )
- }
+const messageText = msg => msg.map(line => line.slice(1).join(' ')).join('\n')
- return logFileName
-}
+let npm = null // set by the cli
+let exitHandlerCalled = false
+let showLogFileMessage = false
process.on('exit', code => {
+ log.disableProgress()
+
// process.emit is synchronous, so the timeEnd handler will run before the
// unfinished timer check below
process.emit('timeEnd', 'npm')
- npm.log.disableProgress()
- for (const [name, timers] of npm.timers) {
- npm.log.verbose('unfinished npm timer', name, timers)
- }
- if (npm.config.loaded && npm.config.get('timing')) {
- try {
- const file = path.resolve(npm.config.get('cache'), '_timing.json')
- const dir = path.dirname(npm.config.get('cache'))
- mkdirp.sync(dir)
-
- fs.appendFileSync(
- file,
- JSON.stringify({
- command: process.argv.slice(2),
- logfile: getLogFile(),
- version: npm.version,
- ...npm.timings,
- }) + '\n'
- )
-
- const st = fs.lstatSync(path.dirname(npm.config.get('cache')))
- fs.chownSync(dir, st.uid, st.gid)
- fs.chownSync(file, st.uid, st.gid)
- } catch (ex) {
- // ignore
+ const hasNpm = !!npm
+ const hasLoadedNpm = hasNpm && npm.config.loaded
+
+ // Unfinished timers can be read before config load
+ if (hasNpm) {
+ for (const [name, timer] of npm.unfinishedTimers) {
+ log.verbose('unfinished npm timer', name, timer)
}
}
if (!code) {
- npm.log.info('ok')
+ log.info('ok')
} else {
- npm.log.verbose('code', code)
+ log.verbose('code', code)
}
if (!exitHandlerCalled) {
process.exitCode = code || 1
- npm.log.error('', 'Exit handler never called!')
+ log.error('', 'Exit handler never called!')
console.error('')
- npm.log.error('', 'This is an error with npm itself. Please report this error at:')
- npm.log.error('', ' ')
- // TODO this doesn't have an npm.config.loaded guard
- writeLogFile()
+ log.error('', 'This is an error with npm itself. Please report this error at:')
+ log.error('', ' ')
+ showLogFileMessage = true
}
- // In timing mode we always write the log file
- if (npm.config.loaded && npm.config.get('timing') && !wroteLogFile) {
- writeLogFile()
+
+ // In timing mode we always show the log file message
+ if (hasLoadedNpm && npm.config.get('timing')) {
+ showLogFileMessage = true
}
- if (wroteLogFile) {
+
+ // npm must be loaded to know where the log file was written
+ if (showLogFileMessage && hasLoadedNpm) {
// just a line break
- if (npm.log.levels[npm.log.level] <= npm.log.levels.error) {
+ if (log.levels[log.level] <= log.levels.error) {
console.error('')
}
- npm.log.error(
+ log.error(
'',
- ['A complete log of this run can be found in:', ' ' + getLogFile()].join('\n')
+ [
+ 'A complete log of this run can be found in:',
+ ...npm.logFiles.map(f => ' ' + f),
+ ].join('\n')
)
}
+ // This removes any listeners npm setup and writes files if necessary
+ // This is mostly used for tests to avoid max listener warnings
+ if (hasLoadedNpm) {
+ npm.unload()
+ }
+
// these are needed for the tests to have a clean slate in each test case
exitHandlerCalled = false
- wroteLogFile = false
+ showLogFileMessage = false
})
const exitHandler = err => {
- npm.log.disableProgress()
- if (!npm.config.loaded) {
+ exitHandlerCalled = true
+
+ log.disableProgress()
+
+ const hasNpm = !!npm
+ const hasLoadedNpm = hasNpm && npm.config.loaded
+
+ if (!hasNpm) {
+ err = err || new Error('Exit prior to setting npm in exit handler')
+ console.error(err.stack || err.message)
+ return process.exit(1)
+ }
+
+ if (!hasLoadedNpm) {
err = err || new Error('Exit prior to config file resolving.')
console.error(err.stack || err.message)
}
// only show the notification if it finished.
if (typeof npm.updateNotification === 'string') {
- const { level } = npm.log
- npm.log.level = 'notice'
- npm.log.notice('', npm.updateNotification)
- npm.log.level = level
+ const { level } = log
+ log.level = 'notice'
+ log.notice('', npm.updateNotification)
+ log.level = level
}
- exitHandlerCalled = true
-
let exitCode
- let noLog
+ let noLogMessage
if (err) {
exitCode = 1
@@ -125,13 +114,13 @@ const exitHandler = err => {
const quietShellout = isShellout && typeof err.code === 'number' && err.code
if (quietShellout) {
exitCode = err.code
- noLog = true
+ noLogMessage = true
} else if (typeof err === 'string') {
- noLog = true
- npm.log.error('', err)
+ log.error('', err)
+ noLogMessage = true
} else if (!(err instanceof Error)) {
- noLog = true
- npm.log.error('weird error', err)
+ log.error('weird error', err)
+ noLogMessage = true
} else {
if (!err.code) {
const matchErrorCode = err.message.match(/^(?:Error: )?(E[A-Z]+)/)
@@ -141,31 +130,30 @@ const exitHandler = err => {
for (const k of ['type', 'stack', 'statusCode', 'pkgid']) {
const v = err[k]
if (v) {
- npm.log.verbose(k, replaceInfo(v))
+ log.verbose(k, replaceInfo(v))
}
}
- npm.log.verbose('cwd', process.cwd())
-
const args = replaceInfo(process.argv)
- npm.log.verbose('', os.type() + ' ' + os.release())
- npm.log.verbose('argv', args.map(JSON.stringify).join(' '))
- npm.log.verbose('node', process.version)
- npm.log.verbose('npm ', 'v' + npm.version)
+ log.verbose('cwd', process.cwd())
+ log.verbose('', os.type() + ' ' + os.release())
+ log.verbose('argv', args.map(JSON.stringify).join(' '))
+ log.verbose('node', process.version)
+ log.verbose('npm ', 'v' + npm.version)
for (const k of ['code', 'syscall', 'file', 'path', 'dest', 'errno']) {
const v = err[k]
if (v) {
- npm.log.error(k, v)
+ log.error(k, v)
}
}
const msg = errorMessage(err, npm)
for (const errline of [...msg.summary, ...msg.detail]) {
- npm.log.error(...errline)
+ log.error(...errline)
}
- if (npm.config.loaded && npm.config.get('json')) {
+ if (hasLoadedNpm && npm.config.get('json')) {
const error = {
error: {
code: err.code,
@@ -183,17 +171,12 @@ const exitHandler = err => {
}
}
}
- npm.log.verbose('exit', exitCode || 0)
- if (npm.log.level === 'silent') {
- noLog = true
- }
+ log.verbose('exit', exitCode || 0)
- // noLog is true if there was an error, including if config wasn't loaded, so
- // this doesn't need a config.loaded guard
- if (exitCode && !noLog) {
- writeLogFile()
- }
+ showLogFileMessage = log.level === 'silent' || noLogMessage
+ ? false
+ : !!exitCode
// explicitly call process.exit now so we don't hang on things like the
// update notifier, also flush stdout beforehand because process.exit doesn't
@@ -201,42 +184,6 @@ const exitHandler = err => {
process.stdout.write('', () => process.exit(exitCode))
}
-const messageText = msg => msg.map(line => line.slice(1).join(' ')).join('\n')
-
-const writeLogFile = () => {
- try {
- let logOutput = ''
- npm.log.record.forEach(m => {
- const p = [m.id, m.level]
- if (m.prefix) {
- p.push(m.prefix)
- }
- const pref = p.join(' ')
-
- m.message
- .trim()
- .split(/\r?\n/)
- .map(line => (pref + ' ' + line).trim())
- .forEach(line => {
- logOutput += line + os.EOL
- })
- })
-
- const file = getLogFile()
- const dir = path.dirname(file)
- mkdirp.sync(dir)
- writeFileAtomic.sync(file, logOutput)
-
- const st = fs.lstatSync(path.dirname(npm.config.get('cache')))
- fs.chownSync(dir, st.uid, st.gid)
- fs.chownSync(file, st.uid, st.gid)
-
- // truncate once it's been written.
- npm.log.record.length = 0
- wroteLogFile = true
- } catch (ex) {}
-}
-
module.exports = exitHandler
module.exports.setNpm = n => {
npm = n
diff --git a/deps/npm/lib/utils/get-project-scope.js b/deps/npm/lib/utils/get-project-scope.js
deleted file mode 100644
index dc1b4deba3dc29..00000000000000
--- a/deps/npm/lib/utils/get-project-scope.js
+++ /dev/null
@@ -1,19 +0,0 @@
-const { resolve } = require('path')
-module.exports = prefix => {
- try {
- const { name } = require(resolve(prefix, 'package.json'))
- if (!name || typeof name !== 'string') {
- return ''
- }
-
- const split = name.split('/')
- if (split.length < 2) {
- return ''
- }
-
- const scope = split[0]
- return /^@/.test(scope) ? scope : ''
- } catch (er) {
- return ''
- }
-}
diff --git a/deps/npm/lib/utils/log-file.js b/deps/npm/lib/utils/log-file.js
new file mode 100644
index 00000000000000..b37fd23e079c04
--- /dev/null
+++ b/deps/npm/lib/utils/log-file.js
@@ -0,0 +1,245 @@
+const os = require('os')
+const path = require('path')
+const { format, promisify } = require('util')
+const rimraf = promisify(require('rimraf'))
+const glob = promisify(require('glob'))
+const MiniPass = require('minipass')
+const fsMiniPass = require('fs-minipass')
+const log = require('./log-shim')
+const withChownSync = require('./with-chown-sync')
+
+const _logHandler = Symbol('logHandler')
+const _formatLogItem = Symbol('formatLogItem')
+const _getLogFilePath = Symbol('getLogFilePath')
+const _openLogFile = Symbol('openLogFile')
+const _cleanLogs = Symbol('cleanlogs')
+const _endStream = Symbol('endStream')
+const _isBuffered = Symbol('isBuffered')
+
+class LogFiles {
+ // If we write multiple log files we want them all to have the same
+ // identifier for sorting and matching purposes
+ #logId = null
+
+ // Default to a plain minipass stream so we can buffer
+ // initial writes before we know the cache location
+ #logStream = null
+
+ // We cap log files at a certain number of log events per file.
+ // Note that each log event can write more than one line to the
+ // file. Then we rotate log files once this number of events is reached
+ #MAX_LOGS_PER_FILE = null
+
+ // Now that we write logs continuously we need to have a backstop
+ // here for infinite loops that still log. This is also partially handled
+ // by the config.get('max-files') option, but this is a failsafe to
+ // prevent runaway log file creation
+ #MAX_LOG_FILES_PER_PROCESS = null
+
+ #fileLogCount = 0
+ #totalLogCount = 0
+ #dir = null
+ #logsMax = null
+ #files = []
+
+ constructor ({
+ maxLogsPerFile = 50_000,
+ maxFilesPerProcess = 5,
+ } = {}) {
+ this.#logId = LogFiles.logId(new Date())
+ this.#MAX_LOGS_PER_FILE = maxLogsPerFile
+ this.#MAX_LOG_FILES_PER_PROCESS = maxFilesPerProcess
+ this.on()
+ }
+
+ static logId (d) {
+ return d.toISOString().replace(/[.:]/g, '_')
+ }
+
+ static fileName (prefix, suffix) {
+ return `${prefix}-debug-${suffix}.log`
+ }
+
+ static format (count, level, title, ...args) {
+ let prefix = `${count} ${level}`
+ if (title) {
+ prefix += ` ${title}`
+ }
+
+ return format(...args)
+ .split(/\r?\n/)
+ .reduce((lines, line) =>
+ lines += prefix + (line ? ' ' : '') + line + os.EOL,
+ ''
+ )
+ }
+
+ on () {
+ this.#logStream = new MiniPass()
+ process.on('log', this[_logHandler])
+ }
+
+ off () {
+ process.off('log', this[_logHandler])
+ this[_endStream]()
+ }
+
+ load ({ dir, logsMax } = {}) {
+ this.#dir = dir
+ this.#logsMax = logsMax
+
+ // Log stream has already ended
+ if (!this.#logStream) {
+ return
+ }
+ // Pipe our initial stream to our new file stream and
+ // set that as the new log logstream for future writes
+ const initialFile = this[_openLogFile]()
+ if (initialFile) {
+ this.#logStream = this.#logStream.pipe(initialFile)
+ }
+
+ // Kickoff cleaning process. This is async but it wont delete
+ // our next log file since it deletes oldest first. Return the
+ // result so it can be awaited in tests
+ return this[_cleanLogs]()
+ }
+
+ log (...args) {
+ this[_logHandler](...args)
+ }
+
+ get files () {
+ return this.#files
+ }
+
+ get [_isBuffered] () {
+ return this.#logStream instanceof MiniPass
+ }
+
+ [_endStream] (output) {
+ if (this.#logStream) {
+ this.#logStream.end(output)
+ this.#logStream = null
+ }
+ }
+
+ [_logHandler] = (level, ...args) => {
+ // Ignore pause and resume events since we
+ // write everything to the log file
+ if (level === 'pause' || level === 'resume') {
+ return
+ }
+
+ // If the stream is ended then do nothing
+ if (!this.#logStream) {
+ return
+ }
+
+ const logOutput = this[_formatLogItem](level, ...args)
+
+ if (this[_isBuffered]) {
+ // Cant do anything but buffer the output if we dont
+ // have a file stream yet
+ this.#logStream.write(logOutput)
+ return
+ }
+
+ // Open a new log file if we've written too many logs to this one
+ if (this.#fileLogCount >= this.#MAX_LOGS_PER_FILE) {
+ // Write last chunk to the file and close it
+ this[_endStream](logOutput)
+ if (this.#files.length >= this.#MAX_LOG_FILES_PER_PROCESS) {
+ // but if its way too many then we just stop listening
+ this.off()
+ } else {
+ // otherwise we are ready for a new file for the next event
+ this.#logStream = this[_openLogFile]()
+ }
+ } else {
+ this.#logStream.write(logOutput)
+ }
+ }
+
+ [_formatLogItem] (...args) {
+ this.#fileLogCount += 1
+ return LogFiles.format(this.#totalLogCount++, ...args)
+ }
+
+ [_getLogFilePath] (prefix, suffix) {
+ return path.resolve(this.#dir, LogFiles.fileName(prefix, suffix))
+ }
+
+ [_openLogFile] () {
+ // Count in filename will be 0 indexed
+ const count = this.#files.length
+
+ // Pad with zeros so that our log files are always sorted properly
+ // We never want to write files ending in `-9.log` and `-10.log` because
+ // log file cleaning is done by deleting the oldest so in this example
+ // `-10.log` would be deleted next
+ const countDigits = this.#MAX_LOG_FILES_PER_PROCESS.toString().length
+
+ try {
+ const logStream = withChownSync(
+ this[_getLogFilePath](this.#logId, count.toString().padStart(countDigits, '0')),
+ // Some effort was made to make the async, but we need to write logs
+ // during process.on('exit') which has to be synchronous. So in order
+ // to never drop log messages, it is easiest to make it sync all the time
+ // and this was measured to be about 1.5% slower for 40k lines of output
+ (f) => new fsMiniPass.WriteStreamSync(f, { flags: 'a' })
+ )
+ if (count > 0) {
+ // Reset file log count if we are opening
+ // after our first file
+ this.#fileLogCount = 0
+ }
+ this.#files.push(logStream.path)
+ return logStream
+ } catch (e) {
+ // XXX: do something here for errors?
+ // log to display only?
+ return null
+ }
+ }
+
+ async [_cleanLogs] () {
+ // module to clean out the old log files
+ // this is a best-effort attempt. if a rm fails, we just
+ // log a message about it and move on. We do return a
+ // Promise that succeeds when we've tried to delete everything,
+ // just for the benefit of testing this function properly.
+
+ if (typeof this.#logsMax !== 'number') {
+ return
+ }
+
+ // Add 1 to account for the current log file and make
+ // minimum config 0 so current log file is never deleted
+ // XXX: we should make a separate documented option to
+ // disable log file writing
+ const max = Math.max(this.#logsMax, 0) + 1
+ try {
+ const files = await glob(this[_getLogFilePath]('*', '*'))
+ const toDelete = files.length - max
+
+ if (toDelete <= 0) {
+ return
+ }
+
+ log.silly('logfile', `start cleaning logs, removing ${toDelete} files`)
+
+ for (const file of files.slice(0, toDelete)) {
+ try {
+ await rimraf(file)
+ } catch (e) {
+ log.warn('logfile', 'error removing log file', file, e)
+ }
+ }
+ } catch (e) {
+ log.warn('logfile', 'error cleaning log files', e)
+ }
+ }
+}
+
+module.exports = LogFiles
diff --git a/deps/npm/lib/utils/log-shim.js b/deps/npm/lib/utils/log-shim.js
new file mode 100644
index 00000000000000..9d5a36d967413f
--- /dev/null
+++ b/deps/npm/lib/utils/log-shim.js
@@ -0,0 +1,59 @@
+const NPMLOG = require('npmlog')
+const PROCLOG = require('proc-log')
+
+// Sets getter and optionally a setter
+// otherwise setting should throw
+const accessors = (obj, set) => (k) => ({
+ get: () => obj[k],
+ set: set ? (v) => (obj[k] = v) : () => {
+ throw new Error(`Cant set ${k}`)
+ },
+})
+
+// Set the value to a bound function on the object
+const value = (obj) => (k) => ({
+ value: (...args) => obj[k].apply(obj, args),
+})
+
+const properties = {
+ // npmlog getters/setters
+ level: accessors(NPMLOG, true),
+ heading: accessors(NPMLOG, true),
+ levels: accessors(NPMLOG),
+ gauge: accessors(NPMLOG),
+ stream: accessors(NPMLOG),
+ tracker: accessors(NPMLOG),
+ progressEnabled: accessors(NPMLOG),
+ // npmlog methods
+ useColor: value(NPMLOG),
+ enableColor: value(NPMLOG),
+ disableColor: value(NPMLOG),
+ enableUnicode: value(NPMLOG),
+ disableUnicode: value(NPMLOG),
+ enableProgress: value(NPMLOG),
+ disableProgress: value(NPMLOG),
+ clearProgress: value(NPMLOG),
+ showProgress: value(NPMLOG),
+ newItem: value(NPMLOG),
+ newGroup: value(NPMLOG),
+ // proclog methods
+ notice: value(PROCLOG),
+ error: value(PROCLOG),
+ warn: value(PROCLOG),
+ info: value(PROCLOG),
+ verbose: value(PROCLOG),
+ http: value(PROCLOG),
+ silly: value(PROCLOG),
+ pause: value(PROCLOG),
+ resume: value(PROCLOG),
+}
+
+const descriptors = Object.entries(properties).reduce((acc, [k, v]) => {
+ acc[k] = { enumerable: true, ...v(k) }
+ return acc
+}, {})
+
+// Create an object with the allowed properties rom npm log and all
+// the logging methods from proc log
+// XXX: this should go away and requires of this should be replaced with proc-log + new display
+module.exports = Object.freeze(Object.defineProperties({}, descriptors))
diff --git a/deps/npm/lib/utils/proc-log-listener.js b/deps/npm/lib/utils/proc-log-listener.js
deleted file mode 100644
index 2cfe94ecb0cf24..00000000000000
--- a/deps/npm/lib/utils/proc-log-listener.js
+++ /dev/null
@@ -1,22 +0,0 @@
-const log = require('npmlog')
-const { inspect } = require('util')
-module.exports = () => {
- process.on('log', (level, ...args) => {
- try {
- log[level](...args)
- } catch (ex) {
- try {
- // if it crashed once, it might again!
- log.verbose(`attempt to log ${inspect([level, ...args])} crashed`, ex)
- } catch (ex2) {
- console.error(`attempt to log ${inspect([level, ...args])} crashed`, ex)
- }
- }
- })
-}
-
-// for tests
-/* istanbul ignore next */
-module.exports.reset = () => {
- process.removeAllListeners('log')
-}
diff --git a/deps/npm/lib/utils/pulse-till-done.js b/deps/npm/lib/utils/pulse-till-done.js
index a88b8aacd862b8..22294141474839 100644
--- a/deps/npm/lib/utils/pulse-till-done.js
+++ b/deps/npm/lib/utils/pulse-till-done.js
@@ -1,4 +1,4 @@
-const log = require('npmlog')
+const log = require('./log-shim.js')
let pulseTimer = null
const withPromise = async (promise) => {
diff --git a/deps/npm/lib/utils/read-user-info.js b/deps/npm/lib/utils/read-user-info.js
index 993aa886f6b4cf..ac24396c6abb94 100644
--- a/deps/npm/lib/utils/read-user-info.js
+++ b/deps/npm/lib/utils/read-user-info.js
@@ -1,7 +1,7 @@
const { promisify } = require('util')
const readAsync = promisify(require('read'))
const userValidate = require('npm-user-validate')
-const log = require('npmlog')
+const log = require('./log-shim.js')
exports.otp = readOTP
exports.password = readPassword
@@ -40,30 +40,30 @@ function readPassword (msg = passwordPrompt, password, isRetry) {
.then((password) => readPassword(msg, password, true))
}
-function readUsername (msg = usernamePrompt, username, opts = {}, isRetry) {
+function readUsername (msg = usernamePrompt, username, isRetry) {
if (isRetry && username) {
const error = userValidate.username(username)
if (error) {
- opts.log && opts.log.warn(error.message)
+ log.warn(error.message)
} else {
return Promise.resolve(username.trim())
}
}
return read({ prompt: msg, default: username || '' })
- .then((username) => readUsername(msg, username, opts, true))
+ .then((username) => readUsername(msg, username, true))
}
-function readEmail (msg = emailPrompt, email, opts = {}, isRetry) {
+function readEmail (msg = emailPrompt, email, isRetry) {
if (isRetry && email) {
const error = userValidate.email(email)
if (error) {
- opts.log && opts.log.warn(error.message)
+ log.warn(error.message)
} else {
return email.trim()
}
}
return read({ prompt: msg, default: email || '' })
- .then((username) => readEmail(msg, username, opts, true))
+ .then((username) => readEmail(msg, username, true))
}
diff --git a/deps/npm/lib/utils/reify-output.js b/deps/npm/lib/utils/reify-output.js
index 7741b72200dd8f..b4114c1b2fe04a 100644
--- a/deps/npm/lib/utils/reify-output.js
+++ b/deps/npm/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('npmlog')
+const log = require('./log-shim.js')
const { depth } = require('treeverse')
const ms = require('ms')
const auditReport = require('npm-audit-report')
diff --git a/deps/npm/lib/utils/setup-log.js b/deps/npm/lib/utils/setup-log.js
deleted file mode 100644
index 05ca38c8282403..00000000000000
--- a/deps/npm/lib/utils/setup-log.js
+++ /dev/null
@@ -1,66 +0,0 @@
-// module to set the appropriate log settings based on configs
-// returns a boolean to say whether we should enable color on
-// stdout or not.
-//
-// 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.
-const log = require('npmlog')
-const { explain } = require('./explain-eresolve.js')
-
-module.exports = (config) => {
- const color = config.get('color')
-
- const { warn } = log
-
- const stdoutTTY = process.stdout.isTTY
- const stderrTTY = process.stderr.isTTY
- const dumbTerm = process.env.TERM === 'dumb'
- const stderrNotDumb = stderrTTY && !dumbTerm
- // this logic is duplicated in the config 'color' flattener
- const enableColorStderr = color === 'always' ? true
- : color === false ? false
- : stderrTTY
-
- const enableColorStdout = color === 'always' ? true
- : color === false ? false
- : stdoutTTY
-
- log.warn = (heading, ...args) => {
- if (heading === 'ERESOLVE' && args[1] && typeof args[1] === 'object') {
- warn(heading, args[0])
- return warn('', explain(args[1], enableColorStdout, 2))
- }
- return warn(heading, ...args)
- }
-
- if (config.get('timing') && config.get('loglevel') === 'notice') {
- log.level = 'timing'
- } else {
- log.level = config.get('loglevel')
- }
-
- log.heading = config.get('heading') || 'npm'
-
- if (enableColorStderr) {
- log.enableColor()
- } else {
- log.disableColor()
- }
-
- if (config.get('unicode')) {
- log.enableUnicode()
- } else {
- log.disableUnicode()
- }
-
- // if it's more than error, don't show progress
- const quiet = log.levels[log.level] > log.levels.error
-
- if (config.get('progress') && stderrNotDumb && !quiet) {
- log.enableProgress()
- } else {
- log.disableProgress()
- }
-}
diff --git a/deps/npm/lib/utils/tar.js b/deps/npm/lib/utils/tar.js
index 26e7a98df6b494..2f2773c6d49bca 100644
--- a/deps/npm/lib/utils/tar.js
+++ b/deps/npm/lib/utils/tar.js
@@ -1,6 +1,6 @@
const tar = require('tar')
const ssri = require('ssri')
-const npmlog = require('npmlog')
+const log = require('./log-shim')
const formatBytes = require('./format-bytes.js')
const columnify = require('columnify')
const localeCompare = require('@isaacs/string-locale-compare')('en', {
@@ -9,7 +9,7 @@ const localeCompare = require('@isaacs/string-locale-compare')('en', {
})
const logTar = (tarball, opts = {}) => {
- const { unicode = false, log = npmlog } = opts
+ const { unicode = false } = opts
log.notice('')
log.notice('', `${unicode ? '📦 ' : 'package:'} ${tarball.name}@${tarball.version}`)
log.notice('=== Tarball Contents ===')
diff --git a/deps/npm/lib/utils/timers.js b/deps/npm/lib/utils/timers.js
new file mode 100644
index 00000000000000..acff29eb0521bb
--- /dev/null
+++ b/deps/npm/lib/utils/timers.js
@@ -0,0 +1,111 @@
+const EE = require('events')
+const path = require('path')
+const fs = require('graceful-fs')
+const log = require('./log-shim')
+const withChownSync = require('./with-chown-sync.js')
+
+const _timeListener = Symbol('timeListener')
+const _timeEndListener = Symbol('timeEndListener')
+const _init = Symbol('init')
+
+// 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 {
+ #unfinished = new Map()
+ #finished = {}
+ #onTimeEnd = Symbol('onTimeEnd')
+ #dir = null
+ #initialListener = null
+ #initialTimer = null
+
+ constructor ({ listener = null, start = 'npm' } = {}) {
+ super()
+ this.#initialListener = listener
+ this.#initialTimer = start
+ this[_init]()
+ }
+
+ get unfinished () {
+ return this.#unfinished
+ }
+
+ get finished () {
+ 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])
+ }
+ }
+
+ off (listener) {
+ if (listener) {
+ super.off(this.#onTimeEnd, listener)
+ } else {
+ this.removeAllListeners(this.#onTimeEnd)
+ process.off('time', this[_timeListener])
+ process.off('timeEnd', this[_timeEndListener])
+ }
+ }
+
+ load ({ dir }) {
+ this.#dir = dir
+ }
+
+ writeFile (fileData) {
+ try {
+ const globalStart = this.started
+ const globalEnd = this.#finished.npm || Date.now()
+ const content = {
+ ...fileData,
+ ...this.#finished,
+ // add any unfinished timers with their relative start/end
+ unfinished: [...this.#unfinished.entries()].reduce((acc, [name, start]) => {
+ acc[name] = [start - globalStart, globalEnd - globalStart]
+ return acc
+ }, {}),
+ }
+ withChownSync(
+ path.resolve(this.#dir, '_timing.json'),
+ (f) =>
+ // we append line delimited json to this file...forever
+ // XXX: should we also write a process specific timing file?
+ // with similar rules to the debug log (max files, etc)
+ fs.appendFileSync(f, JSON.stringify(content) + '\n')
+ )
+ } catch (e) {
+ log.warn('timing', 'could not write timing file', e)
+ }
+ }
+
+ [_timeListener] = (name) => {
+ this.#unfinished.set(name, Date.now())
+ }
+
+ [_timeEndListener] = (name) => {
+ if (this.#unfinished.has(name)) {
+ const ms = Date.now() - this.#unfinished.get(name)
+ this.#finished[name] = ms
+ this.#unfinished.delete(name)
+ this.emit(this.#onTimeEnd, name, ms)
+ } else {
+ log.silly('timing', "Tried to end timer that doesn't exist:", name)
+ }
+ }
+}
+
+module.exports = Timers
diff --git a/deps/npm/lib/utils/unsupported.js b/deps/npm/lib/utils/unsupported.js
index 5f6a341a83d20d..75aad5e780ec41 100644
--- a/deps/npm/lib/utils/unsupported.js
+++ b/deps/npm/lib/utils/unsupported.js
@@ -1,7 +1,14 @@
+/* eslint-disable no-console */
const semver = require('semver')
const supported = require('../../package.json').engines.node
const knownBroken = '<6.2.0 || 9 <9.3.0'
+// Keep this file compatible with all practical versions of node
+// so we dont get syntax errors when trying to give the users
+// a nice error message. Don't use our log handler because
+// if we encounter a syntax error early on, that will never
+// get displayed to the user.
+
const checkVersion = exports.checkVersion = version => {
const versionNoPrerelease = version.replace(/-.*$/, '')
return {
@@ -24,10 +31,9 @@ exports.checkForBrokenNode = () => {
exports.checkForUnsupportedNode = () => {
const nodejs = checkVersion(process.version)
if (nodejs.unsupported) {
- const log = require('npmlog')
- log.warn('npm', 'npm does not support Node.js ' + process.version)
- log.warn('npm', 'You should probably upgrade to a newer version of node as we')
- log.warn('npm', "can't make any promises that npm will work with this version.")
- log.warn('npm', 'You can find the latest version at https://nodejs.org/')
+ console.error('npm does not support Node.js ' + process.version)
+ console.error('You should probably upgrade to a newer version of node as we')
+ console.error("can't make any promises that npm will work with this version.")
+ console.error('You can find the latest version at https://nodejs.org/')
}
}
diff --git a/deps/npm/lib/utils/update-notifier.js b/deps/npm/lib/utils/update-notifier.js
index 2b45d54c815e0f..44b6a5433c09a5 100644
--- a/deps/npm/lib/utils/update-notifier.js
+++ b/deps/npm/lib/utils/update-notifier.js
@@ -10,6 +10,7 @@ const { promisify } = require('util')
const stat = promisify(require('fs').stat)
const writeFile = promisify(require('fs').writeFile)
const { resolve } = require('path')
+const log = require('./log-shim.js')
const isGlobalNpmUpdate = npm => {
return npm.flatOptions.global &&
@@ -61,7 +62,7 @@ const updateNotifier = async (npm, spec = 'latest') => {
// if they're currently using a prerelease, nudge to the next prerelease
// otherwise, nudge to latest.
- const useColor = npm.log.useColor()
+ const useColor = log.useColor()
const mani = await pacote.manifest(`npm@${spec}`, {
// always prefer latest, even if doing --tag=whatever on the cmd
diff --git a/deps/npm/lib/utils/usage.js b/deps/npm/lib/utils/usage.js
index e23e50c51c42a6..39eaa45e4101e1 100644
--- a/deps/npm/lib/utils/usage.js
+++ b/deps/npm/lib/utils/usage.js
@@ -1,4 +1,4 @@
-const aliases = require('../utils/cmd-list').aliases
+const aliases = require('./cmd-list').aliases
module.exports = function usage (cmd, txt, opt) {
const post = Object.keys(aliases).reduce(function (p, c) {
diff --git a/deps/npm/lib/utils/with-chown-sync.js b/deps/npm/lib/utils/with-chown-sync.js
new file mode 100644
index 00000000000000..481b5696ddabf7
--- /dev/null
+++ b/deps/npm/lib/utils/with-chown-sync.js
@@ -0,0 +1,13 @@
+const mkdirp = require('mkdirp-infer-owner')
+const fs = require('graceful-fs')
+const path = require('path')
+
+module.exports = (file, method) => {
+ const dir = path.dirname(file)
+ mkdirp.sync(dir)
+ const result = method(file)
+ const st = fs.lstatSync(dir)
+ fs.chownSync(dir, st.uid, st.gid)
+ fs.chownSync(file, st.uid, st.gid)
+ return result
+}
diff --git a/deps/npm/man/man1/npm-access.1 b/deps/npm/man/man1/npm-access.1
index 6ee369df5a920c..e6786f2a04ccea 100644
--- a/deps/npm/man/man1/npm-access.1
+++ b/deps/npm/man/man1/npm-access.1
@@ -1,4 +1,4 @@
-.TH "NPM\-ACCESS" "1" "November 2021" "" ""
+.TH "NPM\-ACCESS" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-access\fR \- Set access level on published packages
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-adduser.1 b/deps/npm/man/man1/npm-adduser.1
index 10d035f75304b8..859088196eef33 100644
--- a/deps/npm/man/man1/npm-adduser.1
+++ b/deps/npm/man/man1/npm-adduser.1
@@ -1,4 +1,4 @@
-.TH "NPM\-ADDUSER" "1" "November 2021" "" ""
+.TH "NPM\-ADDUSER" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-adduser\fR \- Add a registry user account
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-audit.1 b/deps/npm/man/man1/npm-audit.1
index 4f2c25c6753fe8..9279f1f6e815ab 100644
--- a/deps/npm/man/man1/npm-audit.1
+++ b/deps/npm/man/man1/npm-audit.1
@@ -1,4 +1,4 @@
-.TH "NPM\-AUDIT" "1" "November 2021" "" ""
+.TH "NPM\-AUDIT" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-audit\fR \- Run a security audit
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-bin.1 b/deps/npm/man/man1/npm-bin.1
index 927373bc4be172..fa1abc087e1193 100644
--- a/deps/npm/man/man1/npm-bin.1
+++ b/deps/npm/man/man1/npm-bin.1
@@ -1,4 +1,4 @@
-.TH "NPM\-BIN" "1" "November 2021" "" ""
+.TH "NPM\-BIN" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-bin\fR \- Display npm bin folder
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-bugs.1 b/deps/npm/man/man1/npm-bugs.1
index 2356611d4c5776..857b78727ad09d 100644
--- a/deps/npm/man/man1/npm-bugs.1
+++ b/deps/npm/man/man1/npm-bugs.1
@@ -1,4 +1,4 @@
-.TH "NPM\-BUGS" "1" "November 2021" "" ""
+.TH "NPM\-BUGS" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-bugs\fR \- Report bugs for a package in a web browser
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-cache.1 b/deps/npm/man/man1/npm-cache.1
index 1f93ecf7e551d5..0ae5e8251e159d 100644
--- a/deps/npm/man/man1/npm-cache.1
+++ b/deps/npm/man/man1/npm-cache.1
@@ -1,4 +1,4 @@
-.TH "NPM\-CACHE" "1" "November 2021" "" ""
+.TH "NPM\-CACHE" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-cache\fR \- Manipulates packages cache
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-ci.1 b/deps/npm/man/man1/npm-ci.1
index 9e9951fbbf64e3..fdd6edbdc03805 100644
--- a/deps/npm/man/man1/npm-ci.1
+++ b/deps/npm/man/man1/npm-ci.1
@@ -1,4 +1,4 @@
-.TH "NPM\-CI" "1" "November 2021" "" ""
+.TH "NPM\-CI" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-ci\fR \- Install a project with a clean slate
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-completion.1 b/deps/npm/man/man1/npm-completion.1
index c79b8b0d889c45..93b7785ec905ff 100644
--- a/deps/npm/man/man1/npm-completion.1
+++ b/deps/npm/man/man1/npm-completion.1
@@ -1,4 +1,4 @@
-.TH "NPM\-COMPLETION" "1" "November 2021" "" ""
+.TH "NPM\-COMPLETION" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-completion\fR \- Tab Completion for npm
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-config.1 b/deps/npm/man/man1/npm-config.1
index 87b2e4082b62a6..8b667c03d9c9ca 100644
--- a/deps/npm/man/man1/npm-config.1
+++ b/deps/npm/man/man1/npm-config.1
@@ -1,4 +1,4 @@
-.TH "NPM\-CONFIG" "1" "November 2021" "" ""
+.TH "NPM\-CONFIG" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-config\fR \- Manage the npm configuration files
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-dedupe.1 b/deps/npm/man/man1/npm-dedupe.1
index e619784485cc39..dff883b8270510 100644
--- a/deps/npm/man/man1/npm-dedupe.1
+++ b/deps/npm/man/man1/npm-dedupe.1
@@ -1,4 +1,4 @@
-.TH "NPM\-DEDUPE" "1" "November 2021" "" ""
+.TH "NPM\-DEDUPE" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-dedupe\fR \- Reduce duplication in the package tree
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-deprecate.1 b/deps/npm/man/man1/npm-deprecate.1
index a4eb24c0be060e..f83b46a156dbbc 100644
--- a/deps/npm/man/man1/npm-deprecate.1
+++ b/deps/npm/man/man1/npm-deprecate.1
@@ -1,4 +1,4 @@
-.TH "NPM\-DEPRECATE" "1" "November 2021" "" ""
+.TH "NPM\-DEPRECATE" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-deprecate\fR \- Deprecate a version of a package
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-diff.1 b/deps/npm/man/man1/npm-diff.1
index 74e801df1e6035..e730b597a6ee32 100644
--- a/deps/npm/man/man1/npm-diff.1
+++ b/deps/npm/man/man1/npm-diff.1
@@ -1,4 +1,4 @@
-.TH "NPM\-DIFF" "1" "November 2021" "" ""
+.TH "NPM\-DIFF" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-diff\fR \- The registry diff command
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-dist-tag.1 b/deps/npm/man/man1/npm-dist-tag.1
index 5d52da1d13953a..e2bd3c0e28d5a4 100644
--- a/deps/npm/man/man1/npm-dist-tag.1
+++ b/deps/npm/man/man1/npm-dist-tag.1
@@ -1,4 +1,4 @@
-.TH "NPM\-DIST\-TAG" "1" "November 2021" "" ""
+.TH "NPM\-DIST\-TAG" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-dist-tag\fR \- Modify package distribution tags
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-docs.1 b/deps/npm/man/man1/npm-docs.1
index edbeef32a4430a..d0f2ce82c2d771 100644
--- a/deps/npm/man/man1/npm-docs.1
+++ b/deps/npm/man/man1/npm-docs.1
@@ -1,4 +1,4 @@
-.TH "NPM\-DOCS" "1" "November 2021" "" ""
+.TH "NPM\-DOCS" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-docs\fR \- Open documentation for a package in a web browser
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-doctor.1 b/deps/npm/man/man1/npm-doctor.1
index 9c371ff0cce6d9..3b863eddab456c 100644
--- a/deps/npm/man/man1/npm-doctor.1
+++ b/deps/npm/man/man1/npm-doctor.1
@@ -1,4 +1,4 @@
-.TH "NPM\-DOCTOR" "1" "November 2021" "" ""
+.TH "NPM\-DOCTOR" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-doctor\fR \- Check your npm environment
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-edit.1 b/deps/npm/man/man1/npm-edit.1
index b8b0404eb5aefd..4d3bf1711d15cd 100644
--- a/deps/npm/man/man1/npm-edit.1
+++ b/deps/npm/man/man1/npm-edit.1
@@ -1,4 +1,4 @@
-.TH "NPM\-EDIT" "1" "November 2021" "" ""
+.TH "NPM\-EDIT" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-edit\fR \- Edit an installed package
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-exec.1 b/deps/npm/man/man1/npm-exec.1
index 6d6100c15d3997..545d799306ae12 100644
--- a/deps/npm/man/man1/npm-exec.1
+++ b/deps/npm/man/man1/npm-exec.1
@@ -1,4 +1,4 @@
-.TH "NPM\-EXEC" "1" "November 2021" "" ""
+.TH "NPM\-EXEC" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-exec\fR \- Run a command from a local or remote npm package
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-explain.1 b/deps/npm/man/man1/npm-explain.1
index 239c988cf5a187..91a66ff3f53591 100644
--- a/deps/npm/man/man1/npm-explain.1
+++ b/deps/npm/man/man1/npm-explain.1
@@ -1,4 +1,4 @@
-.TH "NPM\-EXPLAIN" "1" "November 2021" "" ""
+.TH "NPM\-EXPLAIN" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-explain\fR \- Explain installed packages
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-explore.1 b/deps/npm/man/man1/npm-explore.1
index 8f0097241d7c97..79e4e5a7dfb7bb 100644
--- a/deps/npm/man/man1/npm-explore.1
+++ b/deps/npm/man/man1/npm-explore.1
@@ -1,4 +1,4 @@
-.TH "NPM\-EXPLORE" "1" "November 2021" "" ""
+.TH "NPM\-EXPLORE" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-explore\fR \- Browse an installed package
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-find-dupes.1 b/deps/npm/man/man1/npm-find-dupes.1
index 49fff29263f000..bd157ab7fd347e 100644
--- a/deps/npm/man/man1/npm-find-dupes.1
+++ b/deps/npm/man/man1/npm-find-dupes.1
@@ -1,4 +1,4 @@
-.TH "NPM\-FIND\-DUPES" "1" "November 2021" "" ""
+.TH "NPM\-FIND\-DUPES" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-find-dupes\fR \- Find duplication in the package tree
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-fund.1 b/deps/npm/man/man1/npm-fund.1
index de01552c76daf9..488dd168c62400 100644
--- a/deps/npm/man/man1/npm-fund.1
+++ b/deps/npm/man/man1/npm-fund.1
@@ -1,4 +1,4 @@
-.TH "NPM\-FUND" "1" "November 2021" "" ""
+.TH "NPM\-FUND" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-fund\fR \- Retrieve funding information
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-help-search.1 b/deps/npm/man/man1/npm-help-search.1
index 12ee237f06c074..8566e38185acdc 100644
--- a/deps/npm/man/man1/npm-help-search.1
+++ b/deps/npm/man/man1/npm-help-search.1
@@ -1,4 +1,4 @@
-.TH "NPM\-HELP\-SEARCH" "1" "November 2021" "" ""
+.TH "NPM\-HELP\-SEARCH" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-help-search\fR \- Search npm help documentation
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-help.1 b/deps/npm/man/man1/npm-help.1
index aa62e72ac016d3..260a253fedef3c 100644
--- a/deps/npm/man/man1/npm-help.1
+++ b/deps/npm/man/man1/npm-help.1
@@ -1,4 +1,4 @@
-.TH "NPM\-HELP" "1" "November 2021" "" ""
+.TH "NPM\-HELP" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-help\fR \- Get help on npm
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-hook.1 b/deps/npm/man/man1/npm-hook.1
index 8ebd352d87bf76..609604155b369b 100644
--- a/deps/npm/man/man1/npm-hook.1
+++ b/deps/npm/man/man1/npm-hook.1
@@ -1,4 +1,4 @@
-.TH "NPM\-HOOK" "1" "November 2021" "" ""
+.TH "NPM\-HOOK" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-hook\fR \- Manage registry hooks
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-init.1 b/deps/npm/man/man1/npm-init.1
index 65108e2c0778af..8119ff10fda318 100644
--- a/deps/npm/man/man1/npm-init.1
+++ b/deps/npm/man/man1/npm-init.1
@@ -1,4 +1,4 @@
-.TH "NPM\-INIT" "1" "November 2021" "" ""
+.TH "NPM\-INIT" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-init\fR \- Create a package\.json file
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-install-ci-test.1 b/deps/npm/man/man1/npm-install-ci-test.1
index df9f22e7da56c3..5b2e09cf1c285f 100644
--- a/deps/npm/man/man1/npm-install-ci-test.1
+++ b/deps/npm/man/man1/npm-install-ci-test.1
@@ -1,4 +1,4 @@
-.TH "NPM\-INSTALL\-CI\-TEST" "1" "November 2021" "" ""
+.TH "NPM\-INSTALL\-CI\-TEST" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-install-ci-test\fR \- Install a project with a clean slate and run tests
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-install-test.1 b/deps/npm/man/man1/npm-install-test.1
index 7250721f6d63b4..451ae94e87c6e3 100644
--- a/deps/npm/man/man1/npm-install-test.1
+++ b/deps/npm/man/man1/npm-install-test.1
@@ -1,4 +1,4 @@
-.TH "NPM\-INSTALL\-TEST" "1" "November 2021" "" ""
+.TH "NPM\-INSTALL\-TEST" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-install-test\fR \- Install package(s) and run tests
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-install.1 b/deps/npm/man/man1/npm-install.1
index 7f0c422ded3c2a..cf93650b30a53c 100644
--- a/deps/npm/man/man1/npm-install.1
+++ b/deps/npm/man/man1/npm-install.1
@@ -1,4 +1,4 @@
-.TH "NPM\-INSTALL" "1" "November 2021" "" ""
+.TH "NPM\-INSTALL" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-install\fR \- Install a package
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-link.1 b/deps/npm/man/man1/npm-link.1
index 83700438ce032c..b15ac7bce6d624 100644
--- a/deps/npm/man/man1/npm-link.1
+++ b/deps/npm/man/man1/npm-link.1
@@ -1,4 +1,4 @@
-.TH "NPM\-LINK" "1" "November 2021" "" ""
+.TH "NPM\-LINK" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-link\fR \- Symlink a package folder
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-logout.1 b/deps/npm/man/man1/npm-logout.1
index a9f0ebe55e17e6..17534e845fc3ef 100644
--- a/deps/npm/man/man1/npm-logout.1
+++ b/deps/npm/man/man1/npm-logout.1
@@ -1,4 +1,4 @@
-.TH "NPM\-LOGOUT" "1" "November 2021" "" ""
+.TH "NPM\-LOGOUT" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-logout\fR \- Log out of the registry
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-ls.1 b/deps/npm/man/man1/npm-ls.1
index 784b338ec970d1..5320cc51fbf810 100644
--- a/deps/npm/man/man1/npm-ls.1
+++ b/deps/npm/man/man1/npm-ls.1
@@ -1,4 +1,4 @@
-.TH "NPM\-LS" "1" "November 2021" "" ""
+.TH "NPM\-LS" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-ls\fR \- List installed packages
.SS Synopsis
@@ -26,7 +26,7 @@ example, running \fBnpm ls promzard\fP in npm's source tree will show:
.P
.RS 2
.nf
-npm@8\.1\.4 /path/to/npm
+npm@8\.2\.0 /path/to/npm
└─┬ init\-package\-json@0\.0\.4
└── promzard@0\.1\.5
.fi
diff --git a/deps/npm/man/man1/npm-org.1 b/deps/npm/man/man1/npm-org.1
index c92d90a759d24b..3ca826bd6c75c2 100644
--- a/deps/npm/man/man1/npm-org.1
+++ b/deps/npm/man/man1/npm-org.1
@@ -1,4 +1,4 @@
-.TH "NPM\-ORG" "1" "November 2021" "" ""
+.TH "NPM\-ORG" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-org\fR \- Manage orgs
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-outdated.1 b/deps/npm/man/man1/npm-outdated.1
index 6477c2ea0d7c64..e596e77c346d96 100644
--- a/deps/npm/man/man1/npm-outdated.1
+++ b/deps/npm/man/man1/npm-outdated.1
@@ -1,4 +1,4 @@
-.TH "NPM\-OUTDATED" "1" "November 2021" "" ""
+.TH "NPM\-OUTDATED" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-outdated\fR \- Check for outdated packages
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-owner.1 b/deps/npm/man/man1/npm-owner.1
index a7d6b45b74ef2a..289d67a66886f0 100644
--- a/deps/npm/man/man1/npm-owner.1
+++ b/deps/npm/man/man1/npm-owner.1
@@ -1,4 +1,4 @@
-.TH "NPM\-OWNER" "1" "November 2021" "" ""
+.TH "NPM\-OWNER" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-owner\fR \- Manage package owners
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-pack.1 b/deps/npm/man/man1/npm-pack.1
index 13bc7336664764..42ab2fa74f2bba 100644
--- a/deps/npm/man/man1/npm-pack.1
+++ b/deps/npm/man/man1/npm-pack.1
@@ -1,4 +1,4 @@
-.TH "NPM\-PACK" "1" "November 2021" "" ""
+.TH "NPM\-PACK" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-pack\fR \- Create a tarball from a package
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-ping.1 b/deps/npm/man/man1/npm-ping.1
index 75db070280e8ad..885cbd837d449f 100644
--- a/deps/npm/man/man1/npm-ping.1
+++ b/deps/npm/man/man1/npm-ping.1
@@ -1,4 +1,4 @@
-.TH "NPM\-PING" "1" "November 2021" "" ""
+.TH "NPM\-PING" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-ping\fR \- Ping npm registry
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-pkg.1 b/deps/npm/man/man1/npm-pkg.1
index aaa37abe842785..dcb6a8bb4d728b 100644
--- a/deps/npm/man/man1/npm-pkg.1
+++ b/deps/npm/man/man1/npm-pkg.1
@@ -1,4 +1,4 @@
-.TH "NPM\-PKG" "1" "November 2021" "" ""
+.TH "NPM\-PKG" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-pkg\fR \- Manages your package\.json
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-prefix.1 b/deps/npm/man/man1/npm-prefix.1
index f986f28c758bf3..259b85e7ee9ca0 100644
--- a/deps/npm/man/man1/npm-prefix.1
+++ b/deps/npm/man/man1/npm-prefix.1
@@ -1,4 +1,4 @@
-.TH "NPM\-PREFIX" "1" "November 2021" "" ""
+.TH "NPM\-PREFIX" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-prefix\fR \- Display prefix
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-profile.1 b/deps/npm/man/man1/npm-profile.1
index e3a365ecd1e665..176afb69c24155 100644
--- a/deps/npm/man/man1/npm-profile.1
+++ b/deps/npm/man/man1/npm-profile.1
@@ -1,4 +1,4 @@
-.TH "NPM\-PROFILE" "1" "November 2021" "" ""
+.TH "NPM\-PROFILE" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-profile\fR \- Change settings on your registry profile
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-prune.1 b/deps/npm/man/man1/npm-prune.1
index 4fb47b337b2d00..54204593ff5fbe 100644
--- a/deps/npm/man/man1/npm-prune.1
+++ b/deps/npm/man/man1/npm-prune.1
@@ -1,4 +1,4 @@
-.TH "NPM\-PRUNE" "1" "November 2021" "" ""
+.TH "NPM\-PRUNE" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-prune\fR \- Remove extraneous packages
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-publish.1 b/deps/npm/man/man1/npm-publish.1
index 6657ee20e58e9e..ca9a3041bfd4bc 100644
--- a/deps/npm/man/man1/npm-publish.1
+++ b/deps/npm/man/man1/npm-publish.1
@@ -1,4 +1,4 @@
-.TH "NPM\-PUBLISH" "1" "November 2021" "" ""
+.TH "NPM\-PUBLISH" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-publish\fR \- Publish a package
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-rebuild.1 b/deps/npm/man/man1/npm-rebuild.1
index 1f5ecab8dd1290..5b0e96d04b864a 100644
--- a/deps/npm/man/man1/npm-rebuild.1
+++ b/deps/npm/man/man1/npm-rebuild.1
@@ -1,4 +1,4 @@
-.TH "NPM\-REBUILD" "1" "November 2021" "" ""
+.TH "NPM\-REBUILD" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-rebuild\fR \- Rebuild a package
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-repo.1 b/deps/npm/man/man1/npm-repo.1
index e763152ac8c041..178816429ad91c 100644
--- a/deps/npm/man/man1/npm-repo.1
+++ b/deps/npm/man/man1/npm-repo.1
@@ -1,4 +1,4 @@
-.TH "NPM\-REPO" "1" "November 2021" "" ""
+.TH "NPM\-REPO" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-repo\fR \- Open package repository page in the browser
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-restart.1 b/deps/npm/man/man1/npm-restart.1
index d113d2fdb695fb..37060c2b6f508d 100644
--- a/deps/npm/man/man1/npm-restart.1
+++ b/deps/npm/man/man1/npm-restart.1
@@ -1,4 +1,4 @@
-.TH "NPM\-RESTART" "1" "November 2021" "" ""
+.TH "NPM\-RESTART" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-restart\fR \- Restart a package
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-root.1 b/deps/npm/man/man1/npm-root.1
index 24b6a36e2348c5..9ac47bbeb38208 100644
--- a/deps/npm/man/man1/npm-root.1
+++ b/deps/npm/man/man1/npm-root.1
@@ -1,4 +1,4 @@
-.TH "NPM\-ROOT" "1" "November 2021" "" ""
+.TH "NPM\-ROOT" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-root\fR \- Display npm root
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-run-script.1 b/deps/npm/man/man1/npm-run-script.1
index da566d33f2fd50..22b80dbf024242 100644
--- a/deps/npm/man/man1/npm-run-script.1
+++ b/deps/npm/man/man1/npm-run-script.1
@@ -1,4 +1,4 @@
-.TH "NPM\-RUN\-SCRIPT" "1" "November 2021" "" ""
+.TH "NPM\-RUN\-SCRIPT" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-run-script\fR \- Run arbitrary package scripts
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-search.1 b/deps/npm/man/man1/npm-search.1
index 281ad48c3fb2e4..5b16ae5babc62c 100644
--- a/deps/npm/man/man1/npm-search.1
+++ b/deps/npm/man/man1/npm-search.1
@@ -1,4 +1,4 @@
-.TH "NPM\-SEARCH" "1" "November 2021" "" ""
+.TH "NPM\-SEARCH" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-search\fR \- Search for packages
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-set-script.1 b/deps/npm/man/man1/npm-set-script.1
index 453a2ccec6d970..960d5d81fa8a2d 100644
--- a/deps/npm/man/man1/npm-set-script.1
+++ b/deps/npm/man/man1/npm-set-script.1
@@ -1,4 +1,4 @@
-.TH "NPM\-SET\-SCRIPT" "1" "November 2021" "" ""
+.TH "NPM\-SET\-SCRIPT" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-set-script\fR \- Set tasks in the scripts section of package\.json
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-shrinkwrap.1 b/deps/npm/man/man1/npm-shrinkwrap.1
index 793c13d6d7283c..166ec5da10362a 100644
--- a/deps/npm/man/man1/npm-shrinkwrap.1
+++ b/deps/npm/man/man1/npm-shrinkwrap.1
@@ -1,4 +1,4 @@
-.TH "NPM\-SHRINKWRAP" "1" "November 2021" "" ""
+.TH "NPM\-SHRINKWRAP" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-shrinkwrap\fR \- Lock down dependency versions for publication
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-star.1 b/deps/npm/man/man1/npm-star.1
index ed2cb430043a6f..7b580abec8daf1 100644
--- a/deps/npm/man/man1/npm-star.1
+++ b/deps/npm/man/man1/npm-star.1
@@ -1,4 +1,4 @@
-.TH "NPM\-STAR" "1" "November 2021" "" ""
+.TH "NPM\-STAR" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-star\fR \- Mark your favorite packages
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-stars.1 b/deps/npm/man/man1/npm-stars.1
index 93221b69d1ed66..3cf9bdc96ea2f0 100644
--- a/deps/npm/man/man1/npm-stars.1
+++ b/deps/npm/man/man1/npm-stars.1
@@ -1,4 +1,4 @@
-.TH "NPM\-STARS" "1" "November 2021" "" ""
+.TH "NPM\-STARS" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-stars\fR \- View packages marked as favorites
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-start.1 b/deps/npm/man/man1/npm-start.1
index ca5d0490ed3084..66b9a935ff96ad 100644
--- a/deps/npm/man/man1/npm-start.1
+++ b/deps/npm/man/man1/npm-start.1
@@ -1,4 +1,4 @@
-.TH "NPM\-START" "1" "November 2021" "" ""
+.TH "NPM\-START" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-start\fR \- Start a package
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-stop.1 b/deps/npm/man/man1/npm-stop.1
index ff301333aa72b9..daf293986b6568 100644
--- a/deps/npm/man/man1/npm-stop.1
+++ b/deps/npm/man/man1/npm-stop.1
@@ -1,4 +1,4 @@
-.TH "NPM\-STOP" "1" "November 2021" "" ""
+.TH "NPM\-STOP" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-stop\fR \- Stop a package
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-team.1 b/deps/npm/man/man1/npm-team.1
index 97e06883db62e6..a75060f1b2ec01 100644
--- a/deps/npm/man/man1/npm-team.1
+++ b/deps/npm/man/man1/npm-team.1
@@ -1,4 +1,4 @@
-.TH "NPM\-TEAM" "1" "November 2021" "" ""
+.TH "NPM\-TEAM" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-team\fR \- Manage organization teams and team memberships
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-test.1 b/deps/npm/man/man1/npm-test.1
index abff79323aa9c3..44e0d716c8903b 100644
--- a/deps/npm/man/man1/npm-test.1
+++ b/deps/npm/man/man1/npm-test.1
@@ -1,4 +1,4 @@
-.TH "NPM\-TEST" "1" "November 2021" "" ""
+.TH "NPM\-TEST" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-test\fR \- Test a package
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-token.1 b/deps/npm/man/man1/npm-token.1
index 99476c0ce1f818..a1ff1bc88318fd 100644
--- a/deps/npm/man/man1/npm-token.1
+++ b/deps/npm/man/man1/npm-token.1
@@ -1,4 +1,4 @@
-.TH "NPM\-TOKEN" "1" "November 2021" "" ""
+.TH "NPM\-TOKEN" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-token\fR \- Manage your authentication tokens
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-uninstall.1 b/deps/npm/man/man1/npm-uninstall.1
index 16af51f32e4c74..f1015a4174b8d5 100644
--- a/deps/npm/man/man1/npm-uninstall.1
+++ b/deps/npm/man/man1/npm-uninstall.1
@@ -1,4 +1,4 @@
-.TH "NPM\-UNINSTALL" "1" "November 2021" "" ""
+.TH "NPM\-UNINSTALL" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-uninstall\fR \- Remove a package
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-unpublish.1 b/deps/npm/man/man1/npm-unpublish.1
index 8d3b3e0298f21c..052d7ef4c46a17 100644
--- a/deps/npm/man/man1/npm-unpublish.1
+++ b/deps/npm/man/man1/npm-unpublish.1
@@ -1,4 +1,4 @@
-.TH "NPM\-UNPUBLISH" "1" "November 2021" "" ""
+.TH "NPM\-UNPUBLISH" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-unpublish\fR \- Remove a package from the registry
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-unstar.1 b/deps/npm/man/man1/npm-unstar.1
index c61a8a5bd503fc..ef9fe6e386660c 100644
--- a/deps/npm/man/man1/npm-unstar.1
+++ b/deps/npm/man/man1/npm-unstar.1
@@ -1,4 +1,4 @@
-.TH "NPM\-UNSTAR" "1" "November 2021" "" ""
+.TH "NPM\-UNSTAR" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-unstar\fR \- Remove an item from your favorite packages
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-update.1 b/deps/npm/man/man1/npm-update.1
index 800b69de2dc81e..4188dda6b1ab9f 100644
--- a/deps/npm/man/man1/npm-update.1
+++ b/deps/npm/man/man1/npm-update.1
@@ -1,4 +1,4 @@
-.TH "NPM\-UPDATE" "1" "November 2021" "" ""
+.TH "NPM\-UPDATE" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-update\fR \- Update packages
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-version.1 b/deps/npm/man/man1/npm-version.1
index ebe993deb50fef..73fcf0bdfa9d82 100644
--- a/deps/npm/man/man1/npm-version.1
+++ b/deps/npm/man/man1/npm-version.1
@@ -1,4 +1,4 @@
-.TH "NPM\-VERSION" "1" "November 2021" "" ""
+.TH "NPM\-VERSION" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-version\fR \- Bump a package version
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-view.1 b/deps/npm/man/man1/npm-view.1
index 5af03df4b35a57..4ff00fa93403b3 100644
--- a/deps/npm/man/man1/npm-view.1
+++ b/deps/npm/man/man1/npm-view.1
@@ -1,4 +1,4 @@
-.TH "NPM\-VIEW" "1" "November 2021" "" ""
+.TH "NPM\-VIEW" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-view\fR \- View registry info
.SS Synopsis
diff --git a/deps/npm/man/man1/npm-whoami.1 b/deps/npm/man/man1/npm-whoami.1
index e3c75244550c69..bd3aea36aa9165 100644
--- a/deps/npm/man/man1/npm-whoami.1
+++ b/deps/npm/man/man1/npm-whoami.1
@@ -1,4 +1,4 @@
-.TH "NPM\-WHOAMI" "1" "November 2021" "" ""
+.TH "NPM\-WHOAMI" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm-whoami\fR \- Display npm username
.SS Synopsis
diff --git a/deps/npm/man/man1/npm.1 b/deps/npm/man/man1/npm.1
index 5bd83235ffe5e8..bddb695d5548e6 100644
--- a/deps/npm/man/man1/npm.1
+++ b/deps/npm/man/man1/npm.1
@@ -1,4 +1,4 @@
-.TH "NPM" "1" "November 2021" "" ""
+.TH "NPM" "1" "December 2021" "" ""
.SH "NAME"
\fBnpm\fR \- javascript package manager
.SS Synopsis
@@ -10,7 +10,7 @@ npm [args]
.RE
.SS Version
.P
-8\.1\.4
+8\.2\.0
.SS Description
.P
npm is the package manager for the Node JavaScript platform\. It puts
diff --git a/deps/npm/man/man1/npx.1 b/deps/npm/man/man1/npx.1
index 46c9be0529e673..f210e94f0981de 100644
--- a/deps/npm/man/man1/npx.1
+++ b/deps/npm/man/man1/npx.1
@@ -1,4 +1,4 @@
-.TH "NPX" "1" "November 2021" "" ""
+.TH "NPX" "1" "December 2021" "" ""
.SH "NAME"
\fBnpx\fR \- Run a command from a local or remote npm package
.SS Synopsis
diff --git a/deps/npm/man/man5/folders.5 b/deps/npm/man/man5/folders.5
index 859e3b38bf6c7a..7b0161242f911d 100644
--- a/deps/npm/man/man5/folders.5
+++ b/deps/npm/man/man5/folders.5
@@ -1,4 +1,4 @@
-.TH "FOLDERS" "5" "November 2021" "" ""
+.TH "FOLDERS" "5" "December 2021" "" ""
.SH "NAME"
\fBfolders\fR \- Folder Structures Used by npm
.SS Description
diff --git a/deps/npm/man/man5/install.5 b/deps/npm/man/man5/install.5
index 99a90dcaaf8546..1879e6557f568b 100644
--- a/deps/npm/man/man5/install.5
+++ b/deps/npm/man/man5/install.5
@@ -1,4 +1,4 @@
-.TH "INSTALL" "5" "November 2021" "" ""
+.TH "INSTALL" "5" "December 2021" "" ""
.SH "NAME"
\fBinstall\fR \- Download and install node and npm
.SS Description
diff --git a/deps/npm/man/man5/npm-shrinkwrap-json.5 b/deps/npm/man/man5/npm-shrinkwrap-json.5
index 9fdb54c6b1a781..05f6cf4fd8b8c2 100644
--- a/deps/npm/man/man5/npm-shrinkwrap-json.5
+++ b/deps/npm/man/man5/npm-shrinkwrap-json.5
@@ -1,4 +1,4 @@
-.TH "NPM\-SHRINKWRAP\.JSON" "5" "November 2021" "" ""
+.TH "NPM\-SHRINKWRAP\.JSON" "5" "December 2021" "" ""
.SH "NAME"
\fBnpm-shrinkwrap.json\fR \- A publishable lockfile
.SS Description
diff --git a/deps/npm/man/man5/npmrc.5 b/deps/npm/man/man5/npmrc.5
index 60c03a8c14947c..33f011e7958385 100644
--- a/deps/npm/man/man5/npmrc.5
+++ b/deps/npm/man/man5/npmrc.5
@@ -1,4 +1,4 @@
-.TH "NPMRC" "5" "November 2021" "" ""
+.TH "NPMRC" "5" "December 2021" "" ""
.SH "NAME"
\fBnpmrc\fR \- The npm config files
.SS Description
diff --git a/deps/npm/man/man5/package-json.5 b/deps/npm/man/man5/package-json.5
index 857d5649530e47..6f38ff876b9aa5 100644
--- a/deps/npm/man/man5/package-json.5
+++ b/deps/npm/man/man5/package-json.5
@@ -1,4 +1,4 @@
-.TH "PACKAGE\.JSON" "5" "November 2021" "" ""
+.TH "PACKAGE\.JSON" "5" "December 2021" "" ""
.SH "NAME"
\fBpackage.json\fR \- Specifics of npm's package\.json handling
.SS Description
diff --git a/deps/npm/man/man5/package-lock-json.5 b/deps/npm/man/man5/package-lock-json.5
index 8544d70b711916..22cccd59d326bf 100644
--- a/deps/npm/man/man5/package-lock-json.5
+++ b/deps/npm/man/man5/package-lock-json.5
@@ -1,4 +1,4 @@
-.TH "PACKAGE\-LOCK\.JSON" "5" "November 2021" "" ""
+.TH "PACKAGE\-LOCK\.JSON" "5" "December 2021" "" ""
.SH "NAME"
\fBpackage-lock.json\fR \- A manifestation of the manifest
.SS Description
diff --git a/deps/npm/man/man7/config.7 b/deps/npm/man/man7/config.7
index 2157f70cceeaa6..c366ec1bef6196 100644
--- a/deps/npm/man/man7/config.7
+++ b/deps/npm/man/man7/config.7
@@ -1,4 +1,4 @@
-.TH "CONFIG" "7" "November 2021" "" ""
+.TH "CONFIG" "7" "December 2021" "" ""
.SH "NAME"
\fBconfig\fR \- More than you probably want to know about npm configuration
.SS Description
@@ -1286,8 +1286,8 @@ Type: "silent", "error", "warn", "notice", "http", "timing", "info",
.RE
.P
-What level of logs to report\. On failure, \fIall\fR logs are written to
-\fBnpm\-debug\.log\fP in the current working directory\.
+What level of logs to report\. All logs are written to a debug log, with the
+path to that file printed if the execution of a command fails\.
.P
Any logs of a higher level than the setting are shown\. The default is
"notice"\.
@@ -1752,7 +1752,7 @@ Type: Boolean
.RE
.P
-Save installed packages\. to a package\.json file as \fBpeerDependencies\fP
+Save installed packages to a package\.json file as \fBpeerDependencies\fP
diff --git a/deps/npm/man/man7/developers.7 b/deps/npm/man/man7/developers.7
index 9461ca9fc85549..017beab9daa03e 100644
--- a/deps/npm/man/man7/developers.7
+++ b/deps/npm/man/man7/developers.7
@@ -1,4 +1,4 @@
-.TH "DEVELOPERS" "7" "November 2021" "" ""
+.TH "DEVELOPERS" "7" "December 2021" "" ""
.SH "NAME"
\fBdevelopers\fR \- Developer Guide
.SS Description
diff --git a/deps/npm/man/man7/logging.7 b/deps/npm/man/man7/logging.7
new file mode 100644
index 00000000000000..9098c38849590f
--- /dev/null
+++ b/deps/npm/man/man7/logging.7
@@ -0,0 +1,74 @@
+.TH "LOGGING" "7" "December 2021" "" ""
+.SH "NAME"
+\fBLogging\fR \- Why, What & How we Log
+.SS Description
+.P
+The \fBnpm\fP CLI has various mechanisms for showing different levels of information back to end\-users for certain commands, configurations & environments\.
+.SS Setting Log Levels
+.SS \fBloglevel\fP
+.P
+\fBloglevel\fP is a global argument/config that can be set to determine the type of information to be displayed\.
+.P
+The default value of \fBloglevel\fP is \fB"notice"\fP but there are several levels/types of logs available, including:
+.RS 0
+.IP \(bu 2
+\fB"silent"\fP
+.IP \(bu 2
+\fB"error"\fP
+.IP \(bu 2
+\fB"warn"\fP
+.IP \(bu 2
+\fB"notice"\fP
+.IP \(bu 2
+\fB"http"\fP
+.IP \(bu 2
+\fB"timing"\fP
+.IP \(bu 2
+\fB"info"\fP
+.IP \(bu 2
+\fB"verbose"\fP
+.IP \(bu 2
+\fB"silly"\fP
+
+.RE
+.P
+All logs pertaining to a level proceeding the current setting will be shown\.
+.P
+All logs are written to a debug log, with the path to that file printed if the execution of a command fails\.
+.SS Aliases
+.P
+The log levels listed above have various corresponding aliases, including:
+.RS 0
+.IP \(bu 2
+\fB\-d\fP: \fB\-\-loglevel info\fP
+.IP \(bu 2
+\fB\-\-dd\fP: \fB\-\-loglevel verbose\fP
+.IP \(bu 2
+\fB\-\-verbose\fP: \fB\-\-loglevel verbose\fP
+.IP \(bu 2
+\fB\-\-ddd\fP: \fB\-\-loglevel silly\fP
+.IP \(bu 2
+\fB\-q\fP: \fB\-\-loglevel warn\fP
+.IP \(bu 2
+\fB\-\-quiet\fP: \fB\-\-loglevel warn\fP
+.IP \(bu 2
+\fB\-s\fP: \fB\-\-loglevel silent\fP
+.IP \(bu 2
+\fB\-\-silent\fP: \fB\-\-loglevel silent\fP
+
+.RE
+.SS \fBforeground\-scripts\fP
+.P
+The \fBnpm\fP CLI began hiding the output of lifecycle scripts for \fBnpm install\fP as of \fBv7\fP\|\. Notably, this means you will not see logs/output from packages that may be using "install scripts" to display information back to you or from your own project's scripts defined in \fBpackage\.json\fP\|\. If you'd like to change this behavior & log this output you can set \fBforeground\-scripts\fP to \fBtrue\fP\|\.
+.SS Registry Response Headers
+.SS \fBnpm\-notice\fP
+.P
+The \fBnpm\fP CLI reads from & logs any \fBnpm\-notice\fP headers that are returned from the configured registry\. This mechanism can be used by third\-party registries to provide useful information when network\-dependent requests occur\.
+.P
+This header is not cached, and will not be logged if the request is served from the cache\.
+.SS See also
+.RS 0
+.IP \(bu 2
+npm help config
+
+.RE
diff --git a/deps/npm/man/man7/orgs.7 b/deps/npm/man/man7/orgs.7
index a6664a1dac7bc4..32941be2f6f1f4 100644
--- a/deps/npm/man/man7/orgs.7
+++ b/deps/npm/man/man7/orgs.7
@@ -1,4 +1,4 @@
-.TH "ORGS" "7" "November 2021" "" ""
+.TH "ORGS" "7" "December 2021" "" ""
.SH "NAME"
\fBorgs\fR \- Working with Teams & Orgs
.SS Description
diff --git a/deps/npm/man/man7/registry.7 b/deps/npm/man/man7/registry.7
index 6b46806bf026ed..3f5a28edcd01cb 100644
--- a/deps/npm/man/man7/registry.7
+++ b/deps/npm/man/man7/registry.7
@@ -1,4 +1,4 @@
-.TH "REGISTRY" "7" "November 2021" "" ""
+.TH "REGISTRY" "7" "December 2021" "" ""
.SH "NAME"
\fBregistry\fR \- The JavaScript Package Registry
.SS Description
diff --git a/deps/npm/man/man7/removal.7 b/deps/npm/man/man7/removal.7
index 24d66dfa92edb2..daf28731842eac 100644
--- a/deps/npm/man/man7/removal.7
+++ b/deps/npm/man/man7/removal.7
@@ -1,4 +1,4 @@
-.TH "REMOVAL" "7" "November 2021" "" ""
+.TH "REMOVAL" "7" "December 2021" "" ""
.SH "NAME"
\fBremoval\fR \- Cleaning the Slate
.SS Synopsis
diff --git a/deps/npm/man/man7/scope.7 b/deps/npm/man/man7/scope.7
index f5fa03206b79ce..d4702277a7bacb 100644
--- a/deps/npm/man/man7/scope.7
+++ b/deps/npm/man/man7/scope.7
@@ -1,4 +1,4 @@
-.TH "SCOPE" "7" "November 2021" "" ""
+.TH "SCOPE" "7" "December 2021" "" ""
.SH "NAME"
\fBscope\fR \- Scoped packages
.SS Description
diff --git a/deps/npm/man/man7/scripts.7 b/deps/npm/man/man7/scripts.7
index 9d1659eeee015d..2c121b1f4adfdd 100644
--- a/deps/npm/man/man7/scripts.7
+++ b/deps/npm/man/man7/scripts.7
@@ -1,4 +1,4 @@
-.TH "SCRIPTS" "7" "November 2021" "" ""
+.TH "SCRIPTS" "7" "December 2021" "" ""
.SH "NAME"
\fBscripts\fR \- How npm handles the "scripts" field
.SS Description
@@ -351,7 +351,7 @@ package\.json file, then your package scripts would have the
in your code with \fBprocess\.env\.npm_package_name\fP and
\fBprocess\.env\.npm_package_version\fP, and so on for other fields\.
.P
-See npm help \fBpackage\-json\.md\fP for more on package configs\.
+See npm help \fBpackage\.json\fP for more on package configs\.
.SS current lifecycle event
.P
Lastly, the \fBnpm_lifecycle_event\fP environment variable is set to
diff --git a/deps/npm/man/man7/workspaces.7 b/deps/npm/man/man7/workspaces.7
index c72ae28b11035c..c809092741f842 100644
--- a/deps/npm/man/man7/workspaces.7
+++ b/deps/npm/man/man7/workspaces.7
@@ -1,11 +1,11 @@
-.TH "WORKSPACES" "7" "November 2021" "" ""
+.TH "WORKSPACES" "7" "December 2021" "" ""
.SH "NAME"
\fBworkspaces\fR \- Working with workspaces
.SS Description
.P
\fBWorkspaces\fR is a generic term that refers to the set of features in the
npm cli that provides support to managing multiple packages from your local
-files system from within a singular top\-level, root package\.
+file system from within a singular top\-level, root package\.
.P
This set of features makes up for a much more streamlined workflow handling
linked packages from the local file system\. Automating the linking process
diff --git a/deps/npm/node_modules/@npmcli/config/lib/index.js b/deps/npm/node_modules/@npmcli/config/lib/index.js
index 724ce14c38fc94..e52f7a14f7d7ce 100644
--- a/deps/npm/node_modules/@npmcli/config/lib/index.js
+++ b/deps/npm/node_modules/@npmcli/config/lib/index.js
@@ -497,15 +497,17 @@ class Config {
}
async loadProjectConfig () {
+ // the localPrefix can be set by the CLI config, but otherwise is
+ // found by walking up the folder tree. either way, we load it before
+ // we return to make sure localPrefix is set
+ await this.loadLocalPrefix()
+
if (this[_get]('global') === true || this[_get]('location') === 'global') {
this.data.get('project').source = '(global mode enabled, ignored)'
this.sources.set(this.data.get('project').source, 'project')
return
}
- // the localPrefix can be set by the CLI config, but otherwise is
- // found by walking up the folder tree
- await this.loadLocalPrefix()
const projectFile = resolve(this.localPrefix, '.npmrc')
// if we're in the ~ directory, and there happens to be a node_modules
// folder (which is not TOO uncommon, it turns out), then we can end
diff --git a/deps/npm/node_modules/@npmcli/config/package.json b/deps/npm/node_modules/@npmcli/config/package.json
index f36d8f7b11ec59..299202ec2d0faa 100644
--- a/deps/npm/node_modules/@npmcli/config/package.json
+++ b/deps/npm/node_modules/@npmcli/config/package.json
@@ -1,6 +1,6 @@
{
"name": "@npmcli/config",
- "version": "2.3.1",
+ "version": "2.3.2",
"files": [
"lib"
],
diff --git a/deps/npm/node_modules/are-we-there-yet/package.json b/deps/npm/node_modules/are-we-there-yet/package.json
index d3901a86d67c67..5714e09c3b3714 100644
--- a/deps/npm/node_modules/are-we-there-yet/package.json
+++ b/deps/npm/node_modules/are-we-there-yet/package.json
@@ -1,6 +1,6 @@
{
"name": "are-we-there-yet",
- "version": "1.1.6",
+ "version": "2.0.0",
"description": "Keep track of the overall completion of many disparate processes",
"main": "lib/index.js",
"scripts": {
diff --git a/deps/npm/node_modules/code-point-at/index.js b/deps/npm/node_modules/code-point-at/index.js
deleted file mode 100644
index 0432fe6a30af45..00000000000000
--- a/deps/npm/node_modules/code-point-at/index.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/* eslint-disable babel/new-cap, xo/throw-new-error */
-'use strict';
-module.exports = function (str, pos) {
- if (str === null || str === undefined) {
- throw TypeError();
- }
-
- str = String(str);
-
- var size = str.length;
- var i = pos ? Number(pos) : 0;
-
- if (Number.isNaN(i)) {
- i = 0;
- }
-
- if (i < 0 || i >= size) {
- return undefined;
- }
-
- var first = str.charCodeAt(i);
-
- if (first >= 0xD800 && first <= 0xDBFF && size > i + 1) {
- var second = str.charCodeAt(i + 1);
-
- if (second >= 0xDC00 && second <= 0xDFFF) {
- return ((first - 0xD800) * 0x400) + second - 0xDC00 + 0x10000;
- }
- }
-
- return first;
-};
diff --git a/deps/npm/node_modules/code-point-at/license b/deps/npm/node_modules/code-point-at/license
deleted file mode 100644
index 654d0bfe943437..00000000000000
--- a/deps/npm/node_modules/code-point-at/license
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) Sindre Sorhus (sindresorhus.com)
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/deps/npm/node_modules/code-point-at/package.json b/deps/npm/node_modules/code-point-at/package.json
deleted file mode 100644
index c5907a50788db3..00000000000000
--- a/deps/npm/node_modules/code-point-at/package.json
+++ /dev/null
@@ -1,38 +0,0 @@
-{
- "name": "code-point-at",
- "version": "1.1.0",
- "description": "ES2015 `String#codePointAt()` ponyfill",
- "license": "MIT",
- "repository": "sindresorhus/code-point-at",
- "author": {
- "name": "Sindre Sorhus",
- "email": "sindresorhus@gmail.com",
- "url": "sindresorhus.com"
- },
- "engines": {
- "node": ">=0.10.0"
- },
- "scripts": {
- "test": "xo && ava"
- },
- "files": [
- "index.js"
- ],
- "keywords": [
- "es2015",
- "ponyfill",
- "polyfill",
- "shim",
- "string",
- "str",
- "code",
- "point",
- "at",
- "codepoint",
- "unicode"
- ],
- "devDependencies": {
- "ava": "*",
- "xo": "^0.16.0"
- }
-}
diff --git a/deps/npm/node_modules/code-point-at/readme.md b/deps/npm/node_modules/code-point-at/readme.md
deleted file mode 100644
index 4c97730e69e6f4..00000000000000
--- a/deps/npm/node_modules/code-point-at/readme.md
+++ /dev/null
@@ -1,32 +0,0 @@
-# code-point-at [![Build Status](https://travis-ci.org/sindresorhus/code-point-at.svg?branch=master)](https://travis-ci.org/sindresorhus/code-point-at)
-
-> ES2015 [`String#codePointAt()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt) [ponyfill](https://ponyfill.com)
-
-
-## Install
-
-```
-$ npm install --save code-point-at
-```
-
-
-## Usage
-
-```js
-var codePointAt = require('code-point-at');
-
-codePointAt('🐴');
-//=> 128052
-
-codePointAt('abc', 2);
-//=> 99
-```
-
-## API
-
-### codePointAt(input, [position])
-
-
-## License
-
-MIT © [Sindre Sorhus](https://sindresorhus.com)
diff --git a/deps/npm/node_modules/node-gyp/CHANGELOG.md b/deps/npm/node_modules/node-gyp/CHANGELOG.md
index e5d1a4d065d980..1e54fd69a6d5a8 100644
--- a/deps/npm/node_modules/node-gyp/CHANGELOG.md
+++ b/deps/npm/node_modules/node-gyp/CHANGELOG.md
@@ -1,5 +1,22 @@
# Changelog
+### [8.4.1](https://www.github.com/nodejs/node-gyp/compare/v8.4.0...v8.4.1) (2021-11-19)
+
+
+### Bug Fixes
+
+* windows command missing space ([#2553](https://www.github.com/nodejs/node-gyp/issues/2553)) ([cc37b88](https://www.github.com/nodejs/node-gyp/commit/cc37b880690706d3c5d04d5a68c76c392a0a23ed))
+
+
+### Doc
+
+* fix typo in powershell node-gyp update ([787cf7f](https://www.github.com/nodejs/node-gyp/commit/787cf7f8e5ddd5039e02b64ace6b7b15e06fe0a4))
+
+
+### Core
+
+* npmlog@6.0.0 ([8083f6b](https://www.github.com/nodejs/node-gyp/commit/8083f6b855bd7f3326af04c5f5269fc28d7f2508))
+
## [8.4.0](https://www.github.com/nodejs/node-gyp/compare/v8.3.0...v8.4.0) (2021-11-05)
diff --git a/deps/npm/node_modules/node-gyp/docs/Updating-npm-bundled-node-gyp.md b/deps/npm/node_modules/node-gyp/docs/Updating-npm-bundled-node-gyp.md
index 01ad5642b2009d..0777687c2267f7 100644
--- a/deps/npm/node_modules/node-gyp/docs/Updating-npm-bundled-node-gyp.md
+++ b/deps/npm/node_modules/node-gyp/docs/Updating-npm-bundled-node-gyp.md
@@ -27,13 +27,13 @@ npm config set node_gyp $(npm prefix -g)/lib/node_modules/node-gyp/bin/node-gyp.
### Windows Command Prompt
```
npm install --global node-gyp@latest
-for /f "delims=" %P in ('npm prefix -g') do npm config set node_gyp"%P\node_modules\node-gyp\bin\node-gyp.js"
+for /f "delims=" %P in ('npm prefix -g') do npm config set node_gyp "%P\node_modules\node-gyp\bin\node-gyp.js"
```
### Powershell
```
npm install --global node-gyp@latest
-npm prefix -g | % {npm config set node_gyp "$_\node_modules\node-gyp\bin\node-gypjs"}
+npm prefix -g | % {npm config set node_gyp "$_\node_modules\node-gyp\bin\node-gyp.js"}
```
## Undo
diff --git a/deps/npm/node_modules/node-gyp/node_modules/aproba/LICENSE b/deps/npm/node_modules/node-gyp/node_modules/aproba/LICENSE
deleted file mode 100644
index 2a4982dc40cb69..00000000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/aproba/LICENSE
+++ /dev/null
@@ -1,13 +0,0 @@
-Copyright (c) 2015, Rebecca Turner
-
-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/deps/npm/node_modules/node-gyp/node_modules/aproba/index.js b/deps/npm/node_modules/node-gyp/node_modules/aproba/index.js
deleted file mode 100644
index 6f3f797c09a750..00000000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/aproba/index.js
+++ /dev/null
@@ -1,105 +0,0 @@
-'use strict'
-
-function isArguments (thingy) {
- return thingy != null && typeof thingy === 'object' && thingy.hasOwnProperty('callee')
-}
-
-var types = {
- '*': {label: 'any', check: function () { return true }},
- A: {label: 'array', check: function (thingy) { return Array.isArray(thingy) || isArguments(thingy) }},
- S: {label: 'string', check: function (thingy) { return typeof thingy === 'string' }},
- N: {label: 'number', check: function (thingy) { return typeof thingy === 'number' }},
- F: {label: 'function', check: function (thingy) { return typeof thingy === 'function' }},
- O: {label: 'object', check: function (thingy) { return typeof thingy === 'object' && thingy != null && !types.A.check(thingy) && !types.E.check(thingy) }},
- B: {label: 'boolean', check: function (thingy) { return typeof thingy === 'boolean' }},
- E: {label: 'error', check: function (thingy) { return thingy instanceof Error }},
- Z: {label: 'null', check: function (thingy) { return thingy == null }}
-}
-
-function addSchema (schema, arity) {
- var group = arity[schema.length] = arity[schema.length] || []
- if (group.indexOf(schema) === -1) group.push(schema)
-}
-
-var validate = module.exports = function (rawSchemas, args) {
- if (arguments.length !== 2) throw wrongNumberOfArgs(['SA'], arguments.length)
- if (!rawSchemas) throw missingRequiredArg(0, 'rawSchemas')
- if (!args) throw missingRequiredArg(1, 'args')
- if (!types.S.check(rawSchemas)) throw invalidType(0, ['string'], rawSchemas)
- if (!types.A.check(args)) throw invalidType(1, ['array'], args)
- var schemas = rawSchemas.split('|')
- var arity = {}
-
- schemas.forEach(function (schema) {
- for (var ii = 0; ii < schema.length; ++ii) {
- var type = schema[ii]
- if (!types[type]) throw unknownType(ii, type)
- }
- if (/E.*E/.test(schema)) throw moreThanOneError(schema)
- addSchema(schema, arity)
- if (/E/.test(schema)) {
- addSchema(schema.replace(/E.*$/, 'E'), arity)
- addSchema(schema.replace(/E/, 'Z'), arity)
- if (schema.length === 1) addSchema('', arity)
- }
- })
- var matching = arity[args.length]
- if (!matching) {
- throw wrongNumberOfArgs(Object.keys(arity), args.length)
- }
- for (var ii = 0; ii < args.length; ++ii) {
- var newMatching = matching.filter(function (schema) {
- var type = schema[ii]
- var typeCheck = types[type].check
- return typeCheck(args[ii])
- })
- if (!newMatching.length) {
- var labels = matching.map(function (schema) {
- return types[schema[ii]].label
- }).filter(function (schema) { return schema != null })
- throw invalidType(ii, labels, args[ii])
- }
- matching = newMatching
- }
-}
-
-function missingRequiredArg (num) {
- return newException('EMISSINGARG', 'Missing required argument #' + (num + 1))
-}
-
-function unknownType (num, type) {
- return newException('EUNKNOWNTYPE', 'Unknown type ' + type + ' in argument #' + (num + 1))
-}
-
-function invalidType (num, expectedTypes, value) {
- var valueType
- Object.keys(types).forEach(function (typeCode) {
- if (types[typeCode].check(value)) valueType = types[typeCode].label
- })
- return newException('EINVALIDTYPE', 'Argument #' + (num + 1) + ': Expected ' +
- englishList(expectedTypes) + ' but got ' + valueType)
-}
-
-function englishList (list) {
- return list.join(', ').replace(/, ([^,]+)$/, ' or $1')
-}
-
-function wrongNumberOfArgs (expected, got) {
- var english = englishList(expected)
- var args = expected.every(function (ex) { return ex.length === 1 })
- ? 'argument'
- : 'arguments'
- return newException('EWRONGARGCOUNT', 'Expected ' + english + ' ' + args + ' but got ' + got)
-}
-
-function moreThanOneError (schema) {
- return newException('ETOOMANYERRORTYPES',
- 'Only one error type per argument signature is allowed, more than one found in "' + schema + '"')
-}
-
-function newException (code, msg) {
- var e = new Error(msg)
- e.code = code
- if (Error.captureStackTrace) Error.captureStackTrace(e, validate)
- return e
-}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/aproba/package.json b/deps/npm/node_modules/node-gyp/node_modules/aproba/package.json
deleted file mode 100644
index f008787bc265e0..00000000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/aproba/package.json
+++ /dev/null
@@ -1,34 +0,0 @@
-{
- "name": "aproba",
- "version": "1.2.0",
- "description": "A ridiculously light-weight argument validator (now browser friendly)",
- "main": "index.js",
- "directories": {
- "test": "test"
- },
- "dependencies": {},
- "devDependencies": {
- "standard": "^10.0.3",
- "tap": "^10.0.2"
- },
- "files": [
- "index.js"
- ],
- "scripts": {
- "test": "standard && tap -j3 test/*.js"
- },
- "repository": {
- "type": "git",
- "url": "https://github.com/iarna/aproba"
- },
- "keywords": [
- "argument",
- "validate"
- ],
- "author": "Rebecca Turner ",
- "license": "ISC",
- "bugs": {
- "url": "https://github.com/iarna/aproba/issues"
- },
- "homepage": "https://github.com/iarna/aproba"
-}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/gauge/LICENSE b/deps/npm/node_modules/node-gyp/node_modules/gauge/LICENSE
deleted file mode 100644
index e756052969b780..00000000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/gauge/LICENSE
+++ /dev/null
@@ -1,13 +0,0 @@
-Copyright (c) 2014, Rebecca Turner
-
-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/deps/npm/node_modules/node-gyp/node_modules/gauge/base-theme.js b/deps/npm/node_modules/node-gyp/node_modules/gauge/base-theme.js
deleted file mode 100644
index 0b67638e0211d0..00000000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/gauge/base-theme.js
+++ /dev/null
@@ -1,14 +0,0 @@
-'use strict'
-var spin = require('./spin.js')
-var progressBar = require('./progress-bar.js')
-
-module.exports = {
- activityIndicator: function (values, theme, width) {
- if (values.spun == null) return
- return spin(theme, values.spun)
- },
- progressbar: function (values, theme, width) {
- if (values.completed == null) return
- return progressBar(theme, width, values.completed)
- }
-}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/gauge/error.js b/deps/npm/node_modules/node-gyp/node_modules/gauge/error.js
deleted file mode 100644
index d9914ba5335d25..00000000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/gauge/error.js
+++ /dev/null
@@ -1,24 +0,0 @@
-'use strict'
-var util = require('util')
-
-var User = exports.User = function User (msg) {
- var err = new Error(msg)
- Error.captureStackTrace(err, User)
- err.code = 'EGAUGE'
- return err
-}
-
-exports.MissingTemplateValue = function MissingTemplateValue (item, values) {
- var err = new User(util.format('Missing template value "%s"', item.type))
- Error.captureStackTrace(err, MissingTemplateValue)
- err.template = item
- err.values = values
- return err
-}
-
-exports.Internal = function Internal (msg) {
- var err = new Error(msg)
- Error.captureStackTrace(err, Internal)
- err.code = 'EGAUGEINTERNAL'
- return err
-}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/gauge/has-color.js b/deps/npm/node_modules/node-gyp/node_modules/gauge/has-color.js
deleted file mode 100644
index e283a256f26b74..00000000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/gauge/has-color.js
+++ /dev/null
@@ -1,12 +0,0 @@
-'use strict'
-
-module.exports = isWin32() || isColorTerm()
-
-function isWin32 () {
- return process.platform === 'win32'
-}
-
-function isColorTerm () {
- var termHasColor = /^screen|^xterm|^vt100|color|ansi|cygwin|linux/i
- return !!process.env.COLORTERM || termHasColor.test(process.env.TERM)
-}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/gauge/index.js b/deps/npm/node_modules/node-gyp/node_modules/gauge/index.js
deleted file mode 100644
index c55324008cbfaf..00000000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/gauge/index.js
+++ /dev/null
@@ -1,233 +0,0 @@
-'use strict'
-var Plumbing = require('./plumbing.js')
-var hasUnicode = require('has-unicode')
-var hasColor = require('./has-color.js')
-var onExit = require('signal-exit')
-var defaultThemes = require('./themes')
-var setInterval = require('./set-interval.js')
-var process = require('./process.js')
-var setImmediate = require('./set-immediate')
-
-module.exports = Gauge
-
-function callWith (obj, method) {
- return function () {
- return method.call(obj)
- }
-}
-
-function Gauge (arg1, arg2) {
- var options, writeTo
- if (arg1 && arg1.write) {
- writeTo = arg1
- options = arg2 || {}
- } else if (arg2 && arg2.write) {
- writeTo = arg2
- options = arg1 || {}
- } else {
- writeTo = process.stderr
- options = arg1 || arg2 || {}
- }
-
- this._status = {
- spun: 0,
- section: '',
- subsection: ''
- }
- this._paused = false // are we paused for back pressure?
- this._disabled = true // are all progress bar updates disabled?
- this._showing = false // do we WANT the progress bar on screen
- this._onScreen = false // IS the progress bar on screen
- this._needsRedraw = false // should we print something at next tick?
- this._hideCursor = options.hideCursor == null ? true : options.hideCursor
- this._fixedFramerate = options.fixedFramerate == null
- ? !(/^v0\.8\./.test(process.version))
- : options.fixedFramerate
- this._lastUpdateAt = null
- this._updateInterval = options.updateInterval == null ? 50 : options.updateInterval
-
- this._themes = options.themes || defaultThemes
- this._theme = options.theme
- var theme = this._computeTheme(options.theme)
- var template = options.template || [
- {type: 'progressbar', length: 20},
- {type: 'activityIndicator', kerning: 1, length: 1},
- {type: 'section', kerning: 1, default: ''},
- {type: 'subsection', kerning: 1, default: ''}
- ]
- this.setWriteTo(writeTo, options.tty)
- var PlumbingClass = options.Plumbing || Plumbing
- this._gauge = new PlumbingClass(theme, template, this.getWidth())
-
- this._$$doRedraw = callWith(this, this._doRedraw)
- this._$$handleSizeChange = callWith(this, this._handleSizeChange)
-
- this._cleanupOnExit = options.cleanupOnExit == null || options.cleanupOnExit
- this._removeOnExit = null
-
- if (options.enabled || (options.enabled == null && this._tty && this._tty.isTTY)) {
- this.enable()
- } else {
- this.disable()
- }
-}
-Gauge.prototype = {}
-
-Gauge.prototype.isEnabled = function () {
- return !this._disabled
-}
-
-Gauge.prototype.setTemplate = function (template) {
- this._gauge.setTemplate(template)
- if (this._showing) this._requestRedraw()
-}
-
-Gauge.prototype._computeTheme = function (theme) {
- if (!theme) theme = {}
- if (typeof theme === 'string') {
- theme = this._themes.getTheme(theme)
- } else if (theme && (Object.keys(theme).length === 0 || theme.hasUnicode != null || theme.hasColor != null)) {
- var useUnicode = theme.hasUnicode == null ? hasUnicode() : theme.hasUnicode
- var useColor = theme.hasColor == null ? hasColor : theme.hasColor
- theme = this._themes.getDefault({hasUnicode: useUnicode, hasColor: useColor, platform: theme.platform})
- }
- return theme
-}
-
-Gauge.prototype.setThemeset = function (themes) {
- this._themes = themes
- this.setTheme(this._theme)
-}
-
-Gauge.prototype.setTheme = function (theme) {
- this._gauge.setTheme(this._computeTheme(theme))
- if (this._showing) this._requestRedraw()
- this._theme = theme
-}
-
-Gauge.prototype._requestRedraw = function () {
- this._needsRedraw = true
- if (!this._fixedFramerate) this._doRedraw()
-}
-
-Gauge.prototype.getWidth = function () {
- return ((this._tty && this._tty.columns) || 80) - 1
-}
-
-Gauge.prototype.setWriteTo = function (writeTo, tty) {
- var enabled = !this._disabled
- if (enabled) this.disable()
- this._writeTo = writeTo
- this._tty = tty ||
- (writeTo === process.stderr && process.stdout.isTTY && process.stdout) ||
- (writeTo.isTTY && writeTo) ||
- this._tty
- if (this._gauge) this._gauge.setWidth(this.getWidth())
- if (enabled) this.enable()
-}
-
-Gauge.prototype.enable = function () {
- if (!this._disabled) return
- this._disabled = false
- if (this._tty) this._enableEvents()
- if (this._showing) this.show()
-}
-
-Gauge.prototype.disable = function () {
- if (this._disabled) return
- if (this._showing) {
- this._lastUpdateAt = null
- this._showing = false
- this._doRedraw()
- this._showing = true
- }
- this._disabled = true
- if (this._tty) this._disableEvents()
-}
-
-Gauge.prototype._enableEvents = function () {
- if (this._cleanupOnExit) {
- this._removeOnExit = onExit(callWith(this, this.disable))
- }
- this._tty.on('resize', this._$$handleSizeChange)
- if (this._fixedFramerate) {
- this.redrawTracker = setInterval(this._$$doRedraw, this._updateInterval)
- if (this.redrawTracker.unref) this.redrawTracker.unref()
- }
-}
-
-Gauge.prototype._disableEvents = function () {
- this._tty.removeListener('resize', this._$$handleSizeChange)
- if (this._fixedFramerate) clearInterval(this.redrawTracker)
- if (this._removeOnExit) this._removeOnExit()
-}
-
-Gauge.prototype.hide = function (cb) {
- if (this._disabled) return cb && process.nextTick(cb)
- if (!this._showing) return cb && process.nextTick(cb)
- this._showing = false
- this._doRedraw()
- cb && setImmediate(cb)
-}
-
-Gauge.prototype.show = function (section, completed) {
- this._showing = true
- if (typeof section === 'string') {
- this._status.section = section
- } else if (typeof section === 'object') {
- var sectionKeys = Object.keys(section)
- for (var ii = 0; ii < sectionKeys.length; ++ii) {
- var key = sectionKeys[ii]
- this._status[key] = section[key]
- }
- }
- if (completed != null) this._status.completed = completed
- if (this._disabled) return
- this._requestRedraw()
-}
-
-Gauge.prototype.pulse = function (subsection) {
- this._status.subsection = subsection || ''
- this._status.spun ++
- if (this._disabled) return
- if (!this._showing) return
- this._requestRedraw()
-}
-
-Gauge.prototype._handleSizeChange = function () {
- this._gauge.setWidth(this._tty.columns - 1)
- this._requestRedraw()
-}
-
-Gauge.prototype._doRedraw = function () {
- if (this._disabled || this._paused) return
- if (!this._fixedFramerate) {
- var now = Date.now()
- if (this._lastUpdateAt && now - this._lastUpdateAt < this._updateInterval) return
- this._lastUpdateAt = now
- }
- if (!this._showing && this._onScreen) {
- this._onScreen = false
- var result = this._gauge.hide()
- if (this._hideCursor) {
- result += this._gauge.showCursor()
- }
- return this._writeTo.write(result)
- }
- if (!this._showing && !this._onScreen) return
- if (this._showing && !this._onScreen) {
- this._onScreen = true
- this._needsRedraw = true
- if (this._hideCursor) {
- this._writeTo.write(this._gauge.hideCursor())
- }
- }
- if (!this._needsRedraw) return
- if (!this._writeTo.write(this._gauge.show(this._status))) {
- this._paused = true
- this._writeTo.on('drain', callWith(this, function () {
- this._paused = false
- this._doRedraw()
- }))
- }
-}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/gauge/package.json b/deps/npm/node_modules/node-gyp/node_modules/gauge/package.json
deleted file mode 100644
index 4882cff8390d87..00000000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/gauge/package.json
+++ /dev/null
@@ -1,63 +0,0 @@
-{
- "name": "gauge",
- "version": "2.7.4",
- "description": "A terminal based horizontal guage",
- "main": "index.js",
- "scripts": {
- "test": "standard && tap test/*.js --coverage",
- "prepublish": "rm -f *~"
- },
- "repository": {
- "type": "git",
- "url": "https://github.com/iarna/gauge"
- },
- "keywords": [
- "progressbar",
- "progress",
- "gauge"
- ],
- "author": "Rebecca Turner ",
- "license": "ISC",
- "bugs": {
- "url": "https://github.com/iarna/gauge/issues"
- },
- "homepage": "https://github.com/iarna/gauge",
- "dependencies": {
- "aproba": "^1.0.3",
- "console-control-strings": "^1.0.0",
- "has-unicode": "^2.0.0",
- "object-assign": "^4.1.0",
- "signal-exit": "^3.0.0",
- "string-width": "^1.0.1",
- "strip-ansi": "^3.0.1",
- "wide-align": "^1.1.0"
- },
- "devDependencies": {
- "readable-stream": "^2.0.6",
- "require-inject": "^1.4.0",
- "standard": "^7.1.2",
- "tap": "^5.7.2",
- "through2": "^2.0.0"
- },
- "files": [
- "base-theme.js",
- "CHANGELOG.md",
- "error.js",
- "has-color.js",
- "index.js",
- "LICENSE",
- "package.json",
- "plumbing.js",
- "process.js",
- "progress-bar.js",
- "README.md",
- "render-template.js",
- "set-immediate.js",
- "set-interval.js",
- "spin.js",
- "template-item.js",
- "theme-set.js",
- "themes.js",
- "wide-truncate.js"
- ]
-}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/gauge/plumbing.js b/deps/npm/node_modules/node-gyp/node_modules/gauge/plumbing.js
deleted file mode 100644
index 1afb4af6d50174..00000000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/gauge/plumbing.js
+++ /dev/null
@@ -1,48 +0,0 @@
-'use strict'
-var consoleControl = require('console-control-strings')
-var renderTemplate = require('./render-template.js')
-var validate = require('aproba')
-
-var Plumbing = module.exports = function (theme, template, width) {
- if (!width) width = 80
- validate('OAN', [theme, template, width])
- this.showing = false
- this.theme = theme
- this.width = width
- this.template = template
-}
-Plumbing.prototype = {}
-
-Plumbing.prototype.setTheme = function (theme) {
- validate('O', [theme])
- this.theme = theme
-}
-
-Plumbing.prototype.setTemplate = function (template) {
- validate('A', [template])
- this.template = template
-}
-
-Plumbing.prototype.setWidth = function (width) {
- validate('N', [width])
- this.width = width
-}
-
-Plumbing.prototype.hide = function () {
- return consoleControl.gotoSOL() + consoleControl.eraseLine()
-}
-
-Plumbing.prototype.hideCursor = consoleControl.hideCursor
-
-Plumbing.prototype.showCursor = consoleControl.showCursor
-
-Plumbing.prototype.show = function (status) {
- var values = Object.create(this.theme)
- for (var key in status) {
- values[key] = status[key]
- }
-
- return renderTemplate(this.width, this.template, values).trim() +
- consoleControl.color('reset') +
- consoleControl.eraseLine() + consoleControl.gotoSOL()
-}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/gauge/process.js b/deps/npm/node_modules/node-gyp/node_modules/gauge/process.js
deleted file mode 100644
index 05e85694d755b6..00000000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/gauge/process.js
+++ /dev/null
@@ -1,3 +0,0 @@
-'use strict'
-// this exists so we can replace it during testing
-module.exports = process
diff --git a/deps/npm/node_modules/node-gyp/node_modules/gauge/progress-bar.js b/deps/npm/node_modules/node-gyp/node_modules/gauge/progress-bar.js
deleted file mode 100644
index 7f8dd68be24cf0..00000000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/gauge/progress-bar.js
+++ /dev/null
@@ -1,35 +0,0 @@
-'use strict'
-var validate = require('aproba')
-var renderTemplate = require('./render-template.js')
-var wideTruncate = require('./wide-truncate')
-var stringWidth = require('string-width')
-
-module.exports = function (theme, width, completed) {
- validate('ONN', [theme, width, completed])
- if (completed < 0) completed = 0
- if (completed > 1) completed = 1
- if (width <= 0) return ''
- var sofar = Math.round(width * completed)
- var rest = width - sofar
- var template = [
- {type: 'complete', value: repeat(theme.complete, sofar), length: sofar},
- {type: 'remaining', value: repeat(theme.remaining, rest), length: rest}
- ]
- return renderTemplate(width, template, theme)
-}
-
-// lodash's way of repeating
-function repeat (string, width) {
- var result = ''
- var n = width
- do {
- if (n % 2) {
- result += string
- }
- n = Math.floor(n / 2)
- /*eslint no-self-assign: 0*/
- string += string
- } while (n && stringWidth(result) < width)
-
- return wideTruncate(result, width)
-}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/gauge/render-template.js b/deps/npm/node_modules/node-gyp/node_modules/gauge/render-template.js
deleted file mode 100644
index 3261bfbe6f4be5..00000000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/gauge/render-template.js
+++ /dev/null
@@ -1,181 +0,0 @@
-'use strict'
-var align = require('wide-align')
-var validate = require('aproba')
-var objectAssign = require('object-assign')
-var wideTruncate = require('./wide-truncate')
-var error = require('./error')
-var TemplateItem = require('./template-item')
-
-function renderValueWithValues (values) {
- return function (item) {
- return renderValue(item, values)
- }
-}
-
-var renderTemplate = module.exports = function (width, template, values) {
- var items = prepareItems(width, template, values)
- var rendered = items.map(renderValueWithValues(values)).join('')
- return align.left(wideTruncate(rendered, width), width)
-}
-
-function preType (item) {
- var cappedTypeName = item.type[0].toUpperCase() + item.type.slice(1)
- return 'pre' + cappedTypeName
-}
-
-function postType (item) {
- var cappedTypeName = item.type[0].toUpperCase() + item.type.slice(1)
- return 'post' + cappedTypeName
-}
-
-function hasPreOrPost (item, values) {
- if (!item.type) return
- return values[preType(item)] || values[postType(item)]
-}
-
-function generatePreAndPost (baseItem, parentValues) {
- var item = objectAssign({}, baseItem)
- var values = Object.create(parentValues)
- var template = []
- var pre = preType(item)
- var post = postType(item)
- if (values[pre]) {
- template.push({value: values[pre]})
- values[pre] = null
- }
- item.minLength = null
- item.length = null
- item.maxLength = null
- template.push(item)
- values[item.type] = values[item.type]
- if (values[post]) {
- template.push({value: values[post]})
- values[post] = null
- }
- return function ($1, $2, length) {
- return renderTemplate(length, template, values)
- }
-}
-
-function prepareItems (width, template, values) {
- function cloneAndObjectify (item, index, arr) {
- var cloned = new TemplateItem(item, width)
- var type = cloned.type
- if (cloned.value == null) {
- if (!(type in values)) {
- if (cloned.default == null) {
- throw new error.MissingTemplateValue(cloned, values)
- } else {
- cloned.value = cloned.default
- }
- } else {
- cloned.value = values[type]
- }
- }
- if (cloned.value == null || cloned.value === '') return null
- cloned.index = index
- cloned.first = index === 0
- cloned.last = index === arr.length - 1
- if (hasPreOrPost(cloned, values)) cloned.value = generatePreAndPost(cloned, values)
- return cloned
- }
-
- var output = template.map(cloneAndObjectify).filter(function (item) { return item != null })
-
- var outputLength = 0
- var remainingSpace = width
- var variableCount = output.length
-
- function consumeSpace (length) {
- if (length > remainingSpace) length = remainingSpace
- outputLength += length
- remainingSpace -= length
- }
-
- function finishSizing (item, length) {
- if (item.finished) throw new error.Internal('Tried to finish template item that was already finished')
- if (length === Infinity) throw new error.Internal('Length of template item cannot be infinity')
- if (length != null) item.length = length
- item.minLength = null
- item.maxLength = null
- --variableCount
- item.finished = true
- if (item.length == null) item.length = item.getBaseLength()
- if (item.length == null) throw new error.Internal('Finished template items must have a length')
- consumeSpace(item.getLength())
- }
-
- output.forEach(function (item) {
- if (!item.kerning) return
- var prevPadRight = item.first ? 0 : output[item.index - 1].padRight
- if (!item.first && prevPadRight < item.kerning) item.padLeft = item.kerning - prevPadRight
- if (!item.last) item.padRight = item.kerning
- })
-
- // Finish any that have a fixed (literal or intuited) length
- output.forEach(function (item) {
- if (item.getBaseLength() == null) return
- finishSizing(item)
- })
-
- var resized = 0
- var resizing
- var hunkSize
- do {
- resizing = false
- hunkSize = Math.round(remainingSpace / variableCount)
- output.forEach(function (item) {
- if (item.finished) return
- if (!item.maxLength) return
- if (item.getMaxLength() < hunkSize) {
- finishSizing(item, item.maxLength)
- resizing = true
- }
- })
- } while (resizing && resized++ < output.length)
- if (resizing) throw new error.Internal('Resize loop iterated too many times while determining maxLength')
-
- resized = 0
- do {
- resizing = false
- hunkSize = Math.round(remainingSpace / variableCount)
- output.forEach(function (item) {
- if (item.finished) return
- if (!item.minLength) return
- if (item.getMinLength() >= hunkSize) {
- finishSizing(item, item.minLength)
- resizing = true
- }
- })
- } while (resizing && resized++ < output.length)
- if (resizing) throw new error.Internal('Resize loop iterated too many times while determining minLength')
-
- hunkSize = Math.round(remainingSpace / variableCount)
- output.forEach(function (item) {
- if (item.finished) return
- finishSizing(item, hunkSize)
- })
-
- return output
-}
-
-function renderFunction (item, values, length) {
- validate('OON', arguments)
- if (item.type) {
- return item.value(values, values[item.type + 'Theme'] || {}, length)
- } else {
- return item.value(values, {}, length)
- }
-}
-
-function renderValue (item, values) {
- var length = item.getBaseLength()
- var value = typeof item.value === 'function' ? renderFunction(item, values, length) : item.value
- if (value == null || value === '') return ''
- var alignWith = align[item.align] || align.left
- var leftPadding = item.padLeft ? align.left('', item.padLeft) : ''
- var rightPadding = item.padRight ? align.right('', item.padRight) : ''
- var truncated = wideTruncate(String(value), length)
- var aligned = alignWith(truncated, length)
- return leftPadding + aligned + rightPadding
-}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/gauge/set-immediate.js b/deps/npm/node_modules/node-gyp/node_modules/gauge/set-immediate.js
deleted file mode 100644
index 6650a485c49933..00000000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/gauge/set-immediate.js
+++ /dev/null
@@ -1,7 +0,0 @@
-'use strict'
-var process = require('./process')
-try {
- module.exports = setImmediate
-} catch (ex) {
- module.exports = process.nextTick
-}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/gauge/set-interval.js b/deps/npm/node_modules/node-gyp/node_modules/gauge/set-interval.js
deleted file mode 100644
index 576198793c5504..00000000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/gauge/set-interval.js
+++ /dev/null
@@ -1,3 +0,0 @@
-'use strict'
-// this exists so we can replace it during testing
-module.exports = setInterval
diff --git a/deps/npm/node_modules/node-gyp/node_modules/gauge/spin.js b/deps/npm/node_modules/node-gyp/node_modules/gauge/spin.js
deleted file mode 100644
index 34142ee31acc7c..00000000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/gauge/spin.js
+++ /dev/null
@@ -1,5 +0,0 @@
-'use strict'
-
-module.exports = function spin (spinstr, spun) {
- return spinstr[spun % spinstr.length]
-}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/gauge/template-item.js b/deps/npm/node_modules/node-gyp/node_modules/gauge/template-item.js
deleted file mode 100644
index 4f02fefaa23eca..00000000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/gauge/template-item.js
+++ /dev/null
@@ -1,72 +0,0 @@
-'use strict'
-var stringWidth = require('string-width')
-
-module.exports = TemplateItem
-
-function isPercent (num) {
- if (typeof num !== 'string') return false
- return num.slice(-1) === '%'
-}
-
-function percent (num) {
- return Number(num.slice(0, -1)) / 100
-}
-
-function TemplateItem (values, outputLength) {
- this.overallOutputLength = outputLength
- this.finished = false
- this.type = null
- this.value = null
- this.length = null
- this.maxLength = null
- this.minLength = null
- this.kerning = null
- this.align = 'left'
- this.padLeft = 0
- this.padRight = 0
- this.index = null
- this.first = null
- this.last = null
- if (typeof values === 'string') {
- this.value = values
- } else {
- for (var prop in values) this[prop] = values[prop]
- }
- // Realize percents
- if (isPercent(this.length)) {
- this.length = Math.round(this.overallOutputLength * percent(this.length))
- }
- if (isPercent(this.minLength)) {
- this.minLength = Math.round(this.overallOutputLength * percent(this.minLength))
- }
- if (isPercent(this.maxLength)) {
- this.maxLength = Math.round(this.overallOutputLength * percent(this.maxLength))
- }
- return this
-}
-
-TemplateItem.prototype = {}
-
-TemplateItem.prototype.getBaseLength = function () {
- var length = this.length
- if (length == null && typeof this.value === 'string' && this.maxLength == null && this.minLength == null) {
- length = stringWidth(this.value)
- }
- return length
-}
-
-TemplateItem.prototype.getLength = function () {
- var length = this.getBaseLength()
- if (length == null) return null
- return length + this.padLeft + this.padRight
-}
-
-TemplateItem.prototype.getMaxLength = function () {
- if (this.maxLength == null) return null
- return this.maxLength + this.padLeft + this.padRight
-}
-
-TemplateItem.prototype.getMinLength = function () {
- if (this.minLength == null) return null
- return this.minLength + this.padLeft + this.padRight
-}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/gauge/theme-set.js b/deps/npm/node_modules/node-gyp/node_modules/gauge/theme-set.js
deleted file mode 100644
index c022d61cf13cb0..00000000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/gauge/theme-set.js
+++ /dev/null
@@ -1,114 +0,0 @@
-'use strict'
-var objectAssign = require('object-assign')
-
-module.exports = function () {
- return ThemeSetProto.newThemeSet()
-}
-
-var ThemeSetProto = {}
-
-ThemeSetProto.baseTheme = require('./base-theme.js')
-
-ThemeSetProto.newTheme = function (parent, theme) {
- if (!theme) {
- theme = parent
- parent = this.baseTheme
- }
- return objectAssign({}, parent, theme)
-}
-
-ThemeSetProto.getThemeNames = function () {
- return Object.keys(this.themes)
-}
-
-ThemeSetProto.addTheme = function (name, parent, theme) {
- this.themes[name] = this.newTheme(parent, theme)
-}
-
-ThemeSetProto.addToAllThemes = function (theme) {
- var themes = this.themes
- Object.keys(themes).forEach(function (name) {
- objectAssign(themes[name], theme)
- })
- objectAssign(this.baseTheme, theme)
-}
-
-ThemeSetProto.getTheme = function (name) {
- if (!this.themes[name]) throw this.newMissingThemeError(name)
- return this.themes[name]
-}
-
-ThemeSetProto.setDefault = function (opts, name) {
- if (name == null) {
- name = opts
- opts = {}
- }
- var platform = opts.platform == null ? 'fallback' : opts.platform
- var hasUnicode = !!opts.hasUnicode
- var hasColor = !!opts.hasColor
- if (!this.defaults[platform]) this.defaults[platform] = {true: {}, false: {}}
- this.defaults[platform][hasUnicode][hasColor] = name
-}
-
-ThemeSetProto.getDefault = function (opts) {
- if (!opts) opts = {}
- var platformName = opts.platform || process.platform
- var platform = this.defaults[platformName] || this.defaults.fallback
- var hasUnicode = !!opts.hasUnicode
- var hasColor = !!opts.hasColor
- if (!platform) throw this.newMissingDefaultThemeError(platformName, hasUnicode, hasColor)
- if (!platform[hasUnicode][hasColor]) {
- if (hasUnicode && hasColor && platform[!hasUnicode][hasColor]) {
- hasUnicode = false
- } else if (hasUnicode && hasColor && platform[hasUnicode][!hasColor]) {
- hasColor = false
- } else if (hasUnicode && hasColor && platform[!hasUnicode][!hasColor]) {
- hasUnicode = false
- hasColor = false
- } else if (hasUnicode && !hasColor && platform[!hasUnicode][hasColor]) {
- hasUnicode = false
- } else if (!hasUnicode && hasColor && platform[hasUnicode][!hasColor]) {
- hasColor = false
- } else if (platform === this.defaults.fallback) {
- throw this.newMissingDefaultThemeError(platformName, hasUnicode, hasColor)
- }
- }
- if (platform[hasUnicode][hasColor]) {
- return this.getTheme(platform[hasUnicode][hasColor])
- } else {
- return this.getDefault(objectAssign({}, opts, {platform: 'fallback'}))
- }
-}
-
-ThemeSetProto.newMissingThemeError = function newMissingThemeError (name) {
- var err = new Error('Could not find a gauge theme named "' + name + '"')
- Error.captureStackTrace.call(err, newMissingThemeError)
- err.theme = name
- err.code = 'EMISSINGTHEME'
- return err
-}
-
-ThemeSetProto.newMissingDefaultThemeError = function newMissingDefaultThemeError (platformName, hasUnicode, hasColor) {
- var err = new Error(
- 'Could not find a gauge theme for your platform/unicode/color use combo:\n' +
- ' platform = ' + platformName + '\n' +
- ' hasUnicode = ' + hasUnicode + '\n' +
- ' hasColor = ' + hasColor)
- Error.captureStackTrace.call(err, newMissingDefaultThemeError)
- err.platform = platformName
- err.hasUnicode = hasUnicode
- err.hasColor = hasColor
- err.code = 'EMISSINGTHEME'
- return err
-}
-
-ThemeSetProto.newThemeSet = function () {
- var themeset = function (opts) {
- return themeset.getDefault(opts)
- }
- return objectAssign(themeset, ThemeSetProto, {
- themes: objectAssign({}, this.themes),
- baseTheme: objectAssign({}, this.baseTheme),
- defaults: JSON.parse(JSON.stringify(this.defaults || {}))
- })
-}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/gauge/themes.js b/deps/npm/node_modules/node-gyp/node_modules/gauge/themes.js
deleted file mode 100644
index eb5a4f5b5e1034..00000000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/gauge/themes.js
+++ /dev/null
@@ -1,54 +0,0 @@
-'use strict'
-var consoleControl = require('console-control-strings')
-var ThemeSet = require('./theme-set.js')
-
-var themes = module.exports = new ThemeSet()
-
-themes.addTheme('ASCII', {
- preProgressbar: '[',
- postProgressbar: ']',
- progressbarTheme: {
- complete: '#',
- remaining: '.'
- },
- activityIndicatorTheme: '-\\|/',
- preSubsection: '>'
-})
-
-themes.addTheme('colorASCII', themes.getTheme('ASCII'), {
- progressbarTheme: {
- preComplete: consoleControl.color('inverse'),
- complete: ' ',
- postComplete: consoleControl.color('stopInverse'),
- preRemaining: consoleControl.color('brightBlack'),
- remaining: '.',
- postRemaining: consoleControl.color('reset')
- }
-})
-
-themes.addTheme('brailleSpinner', {
- preProgressbar: '⸨',
- postProgressbar: '⸩',
- progressbarTheme: {
- complete: '░',
- remaining: '⠂'
- },
- activityIndicatorTheme: '⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏',
- preSubsection: '>'
-})
-
-themes.addTheme('colorBrailleSpinner', themes.getTheme('brailleSpinner'), {
- progressbarTheme: {
- preComplete: consoleControl.color('inverse'),
- complete: ' ',
- postComplete: consoleControl.color('stopInverse'),
- preRemaining: consoleControl.color('brightBlack'),
- remaining: '░',
- postRemaining: consoleControl.color('reset')
- }
-})
-
-themes.setDefault({}, 'ASCII')
-themes.setDefault({hasColor: true}, 'colorASCII')
-themes.setDefault({platform: 'darwin', hasUnicode: true}, 'brailleSpinner')
-themes.setDefault({platform: 'darwin', hasUnicode: true, hasColor: true}, 'colorBrailleSpinner')
diff --git a/deps/npm/node_modules/node-gyp/node_modules/gauge/wide-truncate.js b/deps/npm/node_modules/node-gyp/node_modules/gauge/wide-truncate.js
deleted file mode 100644
index c531bc491fbb58..00000000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/gauge/wide-truncate.js
+++ /dev/null
@@ -1,25 +0,0 @@
-'use strict'
-var stringWidth = require('string-width')
-var stripAnsi = require('strip-ansi')
-
-module.exports = wideTruncate
-
-function wideTruncate (str, target) {
- if (stringWidth(str) === 0) return str
- if (target <= 0) return ''
- if (stringWidth(str) <= target) return str
-
- // We compute the number of bytes of ansi sequences here and add
- // that to our initial truncation to ensure that we don't slice one
- // that we want to keep in half.
- var noAnsi = stripAnsi(str)
- var ansiSize = str.length + noAnsi.length
- var truncated = str.slice(0, target + ansiSize)
-
- // we have to shrink the result to account for our ansi sequence buffer
- // (if an ansi sequence was truncated) and double width characters.
- while (stringWidth(truncated) > target) {
- truncated = truncated.slice(0, -1)
- }
- return truncated
-}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/is-fullwidth-code-point/index.js b/deps/npm/node_modules/node-gyp/node_modules/is-fullwidth-code-point/index.js
deleted file mode 100644
index a7d3e3855f1c24..00000000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/is-fullwidth-code-point/index.js
+++ /dev/null
@@ -1,46 +0,0 @@
-'use strict';
-var numberIsNan = require('number-is-nan');
-
-module.exports = function (x) {
- if (numberIsNan(x)) {
- return false;
- }
-
- // https://github.com/nodejs/io.js/blob/cff7300a578be1b10001f2d967aaedc88aee6402/lib/readline.js#L1369
-
- // code points are derived from:
- // http://www.unix.org/Public/UNIDATA/EastAsianWidth.txt
- if (x >= 0x1100 && (
- x <= 0x115f || // Hangul Jamo
- 0x2329 === x || // LEFT-POINTING ANGLE BRACKET
- 0x232a === x || // RIGHT-POINTING ANGLE BRACKET
- // CJK Radicals Supplement .. Enclosed CJK Letters and Months
- (0x2e80 <= x && x <= 0x3247 && x !== 0x303f) ||
- // Enclosed CJK Letters and Months .. CJK Unified Ideographs Extension A
- 0x3250 <= x && x <= 0x4dbf ||
- // CJK Unified Ideographs .. Yi Radicals
- 0x4e00 <= x && x <= 0xa4c6 ||
- // Hangul Jamo Extended-A
- 0xa960 <= x && x <= 0xa97c ||
- // Hangul Syllables
- 0xac00 <= x && x <= 0xd7a3 ||
- // CJK Compatibility Ideographs
- 0xf900 <= x && x <= 0xfaff ||
- // Vertical Forms
- 0xfe10 <= x && x <= 0xfe19 ||
- // CJK Compatibility Forms .. Small Form Variants
- 0xfe30 <= x && x <= 0xfe6b ||
- // Halfwidth and Fullwidth Forms
- 0xff01 <= x && x <= 0xff60 ||
- 0xffe0 <= x && x <= 0xffe6 ||
- // Kana Supplement
- 0x1b000 <= x && x <= 0x1b001 ||
- // Enclosed Ideographic Supplement
- 0x1f200 <= x && x <= 0x1f251 ||
- // CJK Unified Ideographs Extension B .. Tertiary Ideographic Plane
- 0x20000 <= x && x <= 0x3fffd)) {
- return true;
- }
-
- return false;
-}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/is-fullwidth-code-point/license b/deps/npm/node_modules/node-gyp/node_modules/is-fullwidth-code-point/license
deleted file mode 100644
index 654d0bfe943437..00000000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/is-fullwidth-code-point/license
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) Sindre Sorhus (sindresorhus.com)
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/deps/npm/node_modules/node-gyp/node_modules/is-fullwidth-code-point/package.json b/deps/npm/node_modules/node-gyp/node_modules/is-fullwidth-code-point/package.json
deleted file mode 100644
index b678d40de728c9..00000000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/is-fullwidth-code-point/package.json
+++ /dev/null
@@ -1,45 +0,0 @@
-{
- "name": "is-fullwidth-code-point",
- "version": "1.0.0",
- "description": "Check if the character represented by a given Unicode code point is fullwidth",
- "license": "MIT",
- "repository": "sindresorhus/is-fullwidth-code-point",
- "author": {
- "name": "Sindre Sorhus",
- "email": "sindresorhus@gmail.com",
- "url": "sindresorhus.com"
- },
- "engines": {
- "node": ">=0.10.0"
- },
- "scripts": {
- "test": "node test.js"
- },
- "files": [
- "index.js"
- ],
- "keywords": [
- "fullwidth",
- "full-width",
- "full",
- "width",
- "unicode",
- "character",
- "char",
- "string",
- "str",
- "codepoint",
- "code",
- "point",
- "is",
- "detect",
- "check"
- ],
- "dependencies": {
- "number-is-nan": "^1.0.0"
- },
- "devDependencies": {
- "ava": "0.0.4",
- "code-point-at": "^1.0.0"
- }
-}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/npmlog/LICENSE b/deps/npm/node_modules/node-gyp/node_modules/npmlog/LICENSE
deleted file mode 100644
index 19129e315fe593..00000000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/npmlog/LICENSE
+++ /dev/null
@@ -1,15 +0,0 @@
-The ISC License
-
-Copyright (c) Isaac Z. Schlueter and Contributors
-
-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/deps/npm/node_modules/node-gyp/node_modules/npmlog/log.js b/deps/npm/node_modules/node-gyp/node_modules/npmlog/log.js
deleted file mode 100644
index 341f3313ab354c..00000000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/npmlog/log.js
+++ /dev/null
@@ -1,309 +0,0 @@
-'use strict'
-var Progress = require('are-we-there-yet')
-var Gauge = require('gauge')
-var EE = require('events').EventEmitter
-var log = exports = module.exports = new EE()
-var util = require('util')
-
-var setBlocking = require('set-blocking')
-var consoleControl = require('console-control-strings')
-
-setBlocking(true)
-var stream = process.stderr
-Object.defineProperty(log, 'stream', {
- set: function (newStream) {
- stream = newStream
- if (this.gauge) this.gauge.setWriteTo(stream, stream)
- },
- get: function () {
- return stream
- }
-})
-
-// by default, decide based on tty-ness.
-var colorEnabled
-log.useColor = function () {
- return colorEnabled != null ? colorEnabled : stream.isTTY
-}
-
-log.enableColor = function () {
- colorEnabled = true
- this.gauge.setTheme({hasColor: colorEnabled, hasUnicode: unicodeEnabled})
-}
-log.disableColor = function () {
- colorEnabled = false
- this.gauge.setTheme({hasColor: colorEnabled, hasUnicode: unicodeEnabled})
-}
-
-// default level
-log.level = 'info'
-
-log.gauge = new Gauge(stream, {
- enabled: false, // no progress bars unless asked
- theme: {hasColor: log.useColor()},
- template: [
- {type: 'progressbar', length: 20},
- {type: 'activityIndicator', kerning: 1, length: 1},
- {type: 'section', default: ''},
- ':',
- {type: 'logline', kerning: 1, default: ''}
- ]
-})
-
-log.tracker = new Progress.TrackerGroup()
-
-// we track this separately as we may need to temporarily disable the
-// display of the status bar for our own loggy purposes.
-log.progressEnabled = log.gauge.isEnabled()
-
-var unicodeEnabled
-
-log.enableUnicode = function () {
- unicodeEnabled = true
- this.gauge.setTheme({hasColor: this.useColor(), hasUnicode: unicodeEnabled})
-}
-
-log.disableUnicode = function () {
- unicodeEnabled = false
- this.gauge.setTheme({hasColor: this.useColor(), hasUnicode: unicodeEnabled})
-}
-
-log.setGaugeThemeset = function (themes) {
- this.gauge.setThemeset(themes)
-}
-
-log.setGaugeTemplate = function (template) {
- this.gauge.setTemplate(template)
-}
-
-log.enableProgress = function () {
- if (this.progressEnabled) return
- this.progressEnabled = true
- this.tracker.on('change', this.showProgress)
- if (this._pause) return
- this.gauge.enable()
-}
-
-log.disableProgress = function () {
- if (!this.progressEnabled) return
- this.progressEnabled = false
- this.tracker.removeListener('change', this.showProgress)
- this.gauge.disable()
-}
-
-var trackerConstructors = ['newGroup', 'newItem', 'newStream']
-
-var mixinLog = function (tracker) {
- // mixin the public methods from log into the tracker
- // (except: conflicts and one's we handle specially)
- Object.keys(log).forEach(function (P) {
- if (P[0] === '_') return
- if (trackerConstructors.filter(function (C) { return C === P }).length) return
- if (tracker[P]) return
- if (typeof log[P] !== 'function') return
- var func = log[P]
- tracker[P] = function () {
- return func.apply(log, arguments)
- }
- })
- // if the new tracker is a group, make sure any subtrackers get
- // mixed in too
- if (tracker instanceof Progress.TrackerGroup) {
- trackerConstructors.forEach(function (C) {
- var func = tracker[C]
- tracker[C] = function () { return mixinLog(func.apply(tracker, arguments)) }
- })
- }
- return tracker
-}
-
-// Add tracker constructors to the top level log object
-trackerConstructors.forEach(function (C) {
- log[C] = function () { return mixinLog(this.tracker[C].apply(this.tracker, arguments)) }
-})
-
-log.clearProgress = function (cb) {
- if (!this.progressEnabled) return cb && process.nextTick(cb)
- this.gauge.hide(cb)
-}
-
-log.showProgress = function (name, completed) {
- if (!this.progressEnabled) return
- var values = {}
- if (name) values.section = name
- var last = log.record[log.record.length - 1]
- if (last) {
- values.subsection = last.prefix
- var disp = log.disp[last.level] || last.level
- var logline = this._format(disp, log.style[last.level])
- if (last.prefix) logline += ' ' + this._format(last.prefix, this.prefixStyle)
- logline += ' ' + last.message.split(/\r?\n/)[0]
- values.logline = logline
- }
- values.completed = completed || this.tracker.completed()
- this.gauge.show(values)
-}.bind(log) // bind for use in tracker's on-change listener
-
-// temporarily stop emitting, but don't drop
-log.pause = function () {
- this._paused = true
- if (this.progressEnabled) this.gauge.disable()
-}
-
-log.resume = function () {
- if (!this._paused) return
- this._paused = false
-
- var b = this._buffer
- this._buffer = []
- b.forEach(function (m) {
- this.emitLog(m)
- }, this)
- if (this.progressEnabled) this.gauge.enable()
-}
-
-log._buffer = []
-
-var id = 0
-log.record = []
-log.maxRecordSize = 10000
-log.log = function (lvl, prefix, message) {
- var l = this.levels[lvl]
- if (l === undefined) {
- return this.emit('error', new Error(util.format(
- 'Undefined log level: %j', lvl)))
- }
-
- var a = new Array(arguments.length - 2)
- var stack = null
- for (var i = 2; i < arguments.length; i++) {
- var arg = a[i - 2] = arguments[i]
-
- // resolve stack traces to a plain string.
- if (typeof arg === 'object' && arg &&
- (arg instanceof Error) && arg.stack) {
-
- Object.defineProperty(arg, 'stack', {
- value: stack = arg.stack + '',
- enumerable: true,
- writable: true
- })
- }
- }
- if (stack) a.unshift(stack + '\n')
- message = util.format.apply(util, a)
-
- var m = { id: id++,
- level: lvl,
- prefix: String(prefix || ''),
- message: message,
- messageRaw: a }
-
- this.emit('log', m)
- this.emit('log.' + lvl, m)
- if (m.prefix) this.emit(m.prefix, m)
-
- this.record.push(m)
- var mrs = this.maxRecordSize
- var n = this.record.length - mrs
- if (n > mrs / 10) {
- var newSize = Math.floor(mrs * 0.9)
- this.record = this.record.slice(-1 * newSize)
- }
-
- this.emitLog(m)
-}.bind(log)
-
-log.emitLog = function (m) {
- if (this._paused) {
- this._buffer.push(m)
- return
- }
- if (this.progressEnabled) this.gauge.pulse(m.prefix)
- var l = this.levels[m.level]
- if (l === undefined) return
- if (l < this.levels[this.level]) return
- if (l > 0 && !isFinite(l)) return
-
- // If 'disp' is null or undefined, use the lvl as a default
- // Allows: '', 0 as valid disp
- var disp = log.disp[m.level] != null ? log.disp[m.level] : m.level
- this.clearProgress()
- m.message.split(/\r?\n/).forEach(function (line) {
- if (this.heading) {
- this.write(this.heading, this.headingStyle)
- this.write(' ')
- }
- this.write(disp, log.style[m.level])
- var p = m.prefix || ''
- if (p) this.write(' ')
- this.write(p, this.prefixStyle)
- this.write(' ' + line + '\n')
- }, this)
- this.showProgress()
-}
-
-log._format = function (msg, style) {
- if (!stream) return
-
- var output = ''
- if (this.useColor()) {
- style = style || {}
- var settings = []
- if (style.fg) settings.push(style.fg)
- if (style.bg) settings.push('bg' + style.bg[0].toUpperCase() + style.bg.slice(1))
- if (style.bold) settings.push('bold')
- if (style.underline) settings.push('underline')
- if (style.inverse) settings.push('inverse')
- if (settings.length) output += consoleControl.color(settings)
- if (style.beep) output += consoleControl.beep()
- }
- output += msg
- if (this.useColor()) {
- output += consoleControl.color('reset')
- }
- return output
-}
-
-log.write = function (msg, style) {
- if (!stream) return
-
- stream.write(this._format(msg, style))
-}
-
-log.addLevel = function (lvl, n, style, disp) {
- // If 'disp' is null or undefined, use the lvl as a default
- if (disp == null) disp = lvl
- this.levels[lvl] = n
- this.style[lvl] = style
- if (!this[lvl]) {
- this[lvl] = function () {
- var a = new Array(arguments.length + 1)
- a[0] = lvl
- for (var i = 0; i < arguments.length; i++) {
- a[i + 1] = arguments[i]
- }
- return this.log.apply(this, a)
- }.bind(this)
- }
- this.disp[lvl] = disp
-}
-
-log.prefixStyle = { fg: 'magenta' }
-log.headingStyle = { fg: 'white', bg: 'black' }
-
-log.style = {}
-log.levels = {}
-log.disp = {}
-log.addLevel('silly', -Infinity, { inverse: true }, 'sill')
-log.addLevel('verbose', 1000, { fg: 'blue', bg: 'black' }, 'verb')
-log.addLevel('info', 2000, { fg: 'green' })
-log.addLevel('timing', 2500, { fg: 'green', bg: 'black' })
-log.addLevel('http', 3000, { fg: 'green', bg: 'black' })
-log.addLevel('notice', 3500, { fg: 'blue', bg: 'black' })
-log.addLevel('warn', 4000, { fg: 'black', bg: 'yellow' }, 'WARN')
-log.addLevel('error', 5000, { fg: 'red', bg: 'black' }, 'ERR!')
-log.addLevel('silent', Infinity)
-
-// allow 'error' prefix
-log.on('error', function () {})
diff --git a/deps/npm/node_modules/node-gyp/node_modules/npmlog/package.json b/deps/npm/node_modules/node-gyp/node_modules/npmlog/package.json
deleted file mode 100644
index 7220f8e72a3c79..00000000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/npmlog/package.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "author": "Isaac Z. Schlueter (http://blog.izs.me/)",
- "name": "npmlog",
- "description": "logger for npm",
- "version": "4.1.2",
- "repository": {
- "type": "git",
- "url": "https://github.com/npm/npmlog.git"
- },
- "main": "log.js",
- "files": [
- "log.js"
- ],
- "scripts": {
- "test": "standard && tap test/*.js"
- },
- "dependencies": {
- "are-we-there-yet": "~1.1.2",
- "console-control-strings": "~1.1.0",
- "gauge": "~2.7.3",
- "set-blocking": "~2.0.0"
- },
- "devDependencies": {
- "standard": "~7.1.2",
- "tap": "~5.7.3"
- },
- "license": "ISC"
-}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/string-width/index.js b/deps/npm/node_modules/node-gyp/node_modules/string-width/index.js
deleted file mode 100644
index b9bec62440a468..00000000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/string-width/index.js
+++ /dev/null
@@ -1,37 +0,0 @@
-'use strict';
-var stripAnsi = require('strip-ansi');
-var codePointAt = require('code-point-at');
-var isFullwidthCodePoint = require('is-fullwidth-code-point');
-
-// https://github.com/nodejs/io.js/blob/cff7300a578be1b10001f2d967aaedc88aee6402/lib/readline.js#L1345
-module.exports = function (str) {
- if (typeof str !== 'string' || str.length === 0) {
- return 0;
- }
-
- var width = 0;
-
- str = stripAnsi(str);
-
- for (var i = 0; i < str.length; i++) {
- var code = codePointAt(str, i);
-
- // ignore control characters
- if (code <= 0x1f || (code >= 0x7f && code <= 0x9f)) {
- continue;
- }
-
- // surrogates
- if (code >= 0x10000) {
- i++;
- }
-
- if (isFullwidthCodePoint(code)) {
- width += 2;
- } else {
- width++;
- }
- }
-
- return width;
-};
diff --git a/deps/npm/node_modules/node-gyp/node_modules/string-width/license b/deps/npm/node_modules/node-gyp/node_modules/string-width/license
deleted file mode 100644
index 654d0bfe943437..00000000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/string-width/license
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) Sindre Sorhus (sindresorhus.com)
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/deps/npm/node_modules/node-gyp/node_modules/string-width/package.json b/deps/npm/node_modules/node-gyp/node_modules/string-width/package.json
deleted file mode 100644
index 5ba436166e9afa..00000000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/string-width/package.json
+++ /dev/null
@@ -1,56 +0,0 @@
-{
- "name": "string-width",
- "version": "1.0.2",
- "description": "Get the visual width of a string - the number of columns required to display it",
- "license": "MIT",
- "repository": "sindresorhus/string-width",
- "author": {
- "name": "Sindre Sorhus",
- "email": "sindresorhus@gmail.com",
- "url": "sindresorhus.com"
- },
- "engines": {
- "node": ">=0.10.0"
- },
- "scripts": {
- "test": "xo && ava"
- },
- "files": [
- "index.js"
- ],
- "keywords": [
- "string",
- "str",
- "character",
- "char",
- "unicode",
- "width",
- "visual",
- "column",
- "columns",
- "fullwidth",
- "full-width",
- "full",
- "ansi",
- "escape",
- "codes",
- "cli",
- "command-line",
- "terminal",
- "console",
- "cjk",
- "chinese",
- "japanese",
- "korean",
- "fixed-width"
- ],
- "dependencies": {
- "code-point-at": "^1.0.0",
- "is-fullwidth-code-point": "^1.0.0",
- "strip-ansi": "^3.0.0"
- },
- "devDependencies": {
- "ava": "*",
- "xo": "*"
- }
-}
diff --git a/deps/npm/node_modules/node-gyp/package.json b/deps/npm/node_modules/node-gyp/package.json
index ea065518171438..fbeae5e20dc2b1 100644
--- a/deps/npm/node_modules/node-gyp/package.json
+++ b/deps/npm/node_modules/node-gyp/package.json
@@ -11,7 +11,7 @@
"bindings",
"gyp"
],
- "version": "8.4.0",
+ "version": "8.4.1",
"installVersion": 9,
"author": "Nathan Rajlich (http://tootallnate.net)",
"repository": {
@@ -27,7 +27,7 @@
"graceful-fs": "^4.2.6",
"make-fetch-happen": "^9.1.0",
"nopt": "^5.0.0",
- "npmlog": "^4.1.2",
+ "npmlog": "^6.0.0",
"rimraf": "^3.0.2",
"semver": "^7.3.5",
"tar": "^6.1.2",
diff --git a/deps/npm/node_modules/npmlog/node_modules/are-we-there-yet/LICENSE.md b/deps/npm/node_modules/npmlog/node_modules/are-we-there-yet/LICENSE.md
deleted file mode 100644
index 845be76f64e789..00000000000000
--- a/deps/npm/node_modules/npmlog/node_modules/are-we-there-yet/LICENSE.md
+++ /dev/null
@@ -1,18 +0,0 @@
-ISC License
-
-Copyright npm, 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 NPM DISCLAIMS ALL
-WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
-EVENT SHALL NPM 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/deps/npm/node_modules/npmlog/node_modules/are-we-there-yet/lib/index.js b/deps/npm/node_modules/npmlog/node_modules/are-we-there-yet/lib/index.js
deleted file mode 100644
index 57d8743fdad177..00000000000000
--- a/deps/npm/node_modules/npmlog/node_modules/are-we-there-yet/lib/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-'use strict'
-exports.TrackerGroup = require('./tracker-group.js')
-exports.Tracker = require('./tracker.js')
-exports.TrackerStream = require('./tracker-stream.js')
diff --git a/deps/npm/node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker-base.js b/deps/npm/node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker-base.js
deleted file mode 100644
index 6f436875578a7a..00000000000000
--- a/deps/npm/node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker-base.js
+++ /dev/null
@@ -1,11 +0,0 @@
-'use strict'
-var EventEmitter = require('events').EventEmitter
-var util = require('util')
-
-var trackerId = 0
-var TrackerBase = module.exports = function (name) {
- EventEmitter.call(this)
- this.id = ++trackerId
- this.name = name
-}
-util.inherits(TrackerBase, EventEmitter)
diff --git a/deps/npm/node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker-group.js b/deps/npm/node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker-group.js
deleted file mode 100644
index 9da13f8a7e116a..00000000000000
--- a/deps/npm/node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker-group.js
+++ /dev/null
@@ -1,116 +0,0 @@
-'use strict'
-var util = require('util')
-var TrackerBase = require('./tracker-base.js')
-var Tracker = require('./tracker.js')
-var TrackerStream = require('./tracker-stream.js')
-
-var TrackerGroup = module.exports = function (name) {
- TrackerBase.call(this, name)
- this.parentGroup = null
- this.trackers = []
- this.completion = {}
- this.weight = {}
- this.totalWeight = 0
- this.finished = false
- this.bubbleChange = bubbleChange(this)
-}
-util.inherits(TrackerGroup, TrackerBase)
-
-function bubbleChange (trackerGroup) {
- return function (name, completed, tracker) {
- trackerGroup.completion[tracker.id] = completed
- if (trackerGroup.finished) {
- return
- }
- trackerGroup.emit('change', name || trackerGroup.name, trackerGroup.completed(), trackerGroup)
- }
-}
-
-TrackerGroup.prototype.nameInTree = function () {
- var names = []
- var from = this
- while (from) {
- names.unshift(from.name)
- from = from.parentGroup
- }
- return names.join('/')
-}
-
-TrackerGroup.prototype.addUnit = function (unit, weight) {
- if (unit.addUnit) {
- var toTest = this
- while (toTest) {
- if (unit === toTest) {
- throw new Error(
- 'Attempted to add tracker group ' +
- unit.name + ' to tree that already includes it ' +
- this.nameInTree(this))
- }
- toTest = toTest.parentGroup
- }
- unit.parentGroup = this
- }
- this.weight[unit.id] = weight || 1
- this.totalWeight += this.weight[unit.id]
- this.trackers.push(unit)
- this.completion[unit.id] = unit.completed()
- unit.on('change', this.bubbleChange)
- if (!this.finished) {
- this.emit('change', unit.name, this.completion[unit.id], unit)
- }
- return unit
-}
-
-TrackerGroup.prototype.completed = function () {
- if (this.trackers.length === 0) {
- return 0
- }
- var valPerWeight = 1 / this.totalWeight
- var completed = 0
- for (var ii = 0; ii < this.trackers.length; ii++) {
- var trackerId = this.trackers[ii].id
- completed +=
- valPerWeight * this.weight[trackerId] * this.completion[trackerId]
- }
- return completed
-}
-
-TrackerGroup.prototype.newGroup = function (name, weight) {
- return this.addUnit(new TrackerGroup(name), weight)
-}
-
-TrackerGroup.prototype.newItem = function (name, todo, weight) {
- return this.addUnit(new Tracker(name, todo), weight)
-}
-
-TrackerGroup.prototype.newStream = function (name, todo, weight) {
- return this.addUnit(new TrackerStream(name, todo), weight)
-}
-
-TrackerGroup.prototype.finish = function () {
- this.finished = true
- if (!this.trackers.length) {
- this.addUnit(new Tracker(), 1, true)
- }
- for (var ii = 0; ii < this.trackers.length; ii++) {
- var tracker = this.trackers[ii]
- tracker.finish()
- tracker.removeListener('change', this.bubbleChange)
- }
- this.emit('change', this.name, 1, this)
-}
-
-var buffer = ' '
-TrackerGroup.prototype.debug = function (depth) {
- depth = depth || 0
- var indent = depth ? buffer.substr(0, depth) : ''
- var output = indent + (this.name || 'top') + ': ' + this.completed() + '\n'
- this.trackers.forEach(function (tracker) {
- if (tracker instanceof TrackerGroup) {
- output += tracker.debug(depth + 1)
- } else {
- output += indent + ' ' + tracker.name + ': ' + tracker.completed() + '\n'
- }
- })
- return output
-}
diff --git a/deps/npm/node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker-stream.js b/deps/npm/node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker-stream.js
deleted file mode 100644
index e1cf85055702a7..00000000000000
--- a/deps/npm/node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker-stream.js
+++ /dev/null
@@ -1,36 +0,0 @@
-'use strict'
-var util = require('util')
-var stream = require('readable-stream')
-var delegate = require('delegates')
-var Tracker = require('./tracker.js')
-
-var TrackerStream = module.exports = function (name, size, options) {
- stream.Transform.call(this, options)
- this.tracker = new Tracker(name, size)
- this.name = name
- this.id = this.tracker.id
- this.tracker.on('change', delegateChange(this))
-}
-util.inherits(TrackerStream, stream.Transform)
-
-function delegateChange (trackerStream) {
- return function (name, completion, tracker) {
- trackerStream.emit('change', name, completion, trackerStream)
- }
-}
-
-TrackerStream.prototype._transform = function (data, encoding, cb) {
- this.tracker.completeWork(data.length ? data.length : 1)
- this.push(data)
- cb()
-}
-
-TrackerStream.prototype._flush = function (cb) {
- this.tracker.finish()
- cb()
-}
-
-delegate(TrackerStream.prototype, 'tracker')
- .method('completed')
- .method('addWork')
- .method('finish')
diff --git a/deps/npm/node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker.js b/deps/npm/node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker.js
deleted file mode 100644
index a8f8b3ba013915..00000000000000
--- a/deps/npm/node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker.js
+++ /dev/null
@@ -1,32 +0,0 @@
-'use strict'
-var util = require('util')
-var TrackerBase = require('./tracker-base.js')
-
-var Tracker = module.exports = function (name, todo) {
- TrackerBase.call(this, name)
- this.workDone = 0
- this.workTodo = todo || 0
-}
-util.inherits(Tracker, TrackerBase)
-
-Tracker.prototype.completed = function () {
- return this.workTodo === 0 ? 0 : this.workDone / this.workTodo
-}
-
-Tracker.prototype.addWork = function (work) {
- this.workTodo += work
- this.emit('change', this.name, this.completed(), this)
-}
-
-Tracker.prototype.completeWork = function (work) {
- this.workDone += work
- if (this.workDone > this.workTodo) {
- this.workDone = this.workTodo
- }
- this.emit('change', this.name, this.completed(), this)
-}
-
-Tracker.prototype.finish = function () {
- this.workTodo = this.workDone = 1
- this.emit('change', this.name, 1, this)
-}
diff --git a/deps/npm/node_modules/npmlog/node_modules/are-we-there-yet/package.json b/deps/npm/node_modules/npmlog/node_modules/are-we-there-yet/package.json
deleted file mode 100644
index 5714e09c3b3714..00000000000000
--- a/deps/npm/node_modules/npmlog/node_modules/are-we-there-yet/package.json
+++ /dev/null
@@ -1,53 +0,0 @@
-{
- "name": "are-we-there-yet",
- "version": "2.0.0",
- "description": "Keep track of the overall completion of many disparate processes",
- "main": "lib/index.js",
- "scripts": {
- "test": "tap",
- "npmclilint": "npmcli-lint",
- "lint": "eslint '**/*.js'",
- "lintfix": "npm run lint -- --fix",
- "posttest": "npm run lint",
- "postsnap": "npm run lintfix --",
- "preversion": "npm test",
- "postversion": "npm publish",
- "prepublishOnly": "git push origin --follow-tags",
- "snap": "tap"
- },
- "repository": {
- "type": "git",
- "url": "https://github.com/npm/are-we-there-yet.git"
- },
- "author": "GitHub Inc.",
- "license": "ISC",
- "bugs": {
- "url": "https://github.com/npm/are-we-there-yet/issues"
- },
- "homepage": "https://github.com/npm/are-we-there-yet",
- "devDependencies": {
- "@npmcli/eslint-config": "^1.0.0",
- "@npmcli/template-oss": "^1.0.2",
- "eslint": "^7.32.0",
- "eslint-plugin-node": "^11.1.0",
- "tap": "^15.0.9"
- },
- "dependencies": {
- "delegates": "^1.0.0",
- "readable-stream": "^3.6.0"
- },
- "files": [
- "bin",
- "lib"
- ],
- "engines": {
- "node": ">=10"
- },
- "tap": {
- "branches": 68,
- "statements": 92,
- "functions": 86,
- "lines": 92
- },
- "templateVersion": "1.0.2"
-}
diff --git a/deps/npm/node_modules/number-is-nan/index.js b/deps/npm/node_modules/number-is-nan/index.js
deleted file mode 100644
index 79be4b9cb8c3bc..00000000000000
--- a/deps/npm/node_modules/number-is-nan/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-'use strict';
-module.exports = Number.isNaN || function (x) {
- return x !== x;
-};
diff --git a/deps/npm/node_modules/number-is-nan/license b/deps/npm/node_modules/number-is-nan/license
deleted file mode 100644
index 654d0bfe943437..00000000000000
--- a/deps/npm/node_modules/number-is-nan/license
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) Sindre Sorhus (sindresorhus.com)
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/deps/npm/node_modules/number-is-nan/package.json b/deps/npm/node_modules/number-is-nan/package.json
deleted file mode 100644
index d2f51d4b1d621d..00000000000000
--- a/deps/npm/node_modules/number-is-nan/package.json
+++ /dev/null
@@ -1,35 +0,0 @@
-{
- "name": "number-is-nan",
- "version": "1.0.1",
- "description": "ES2015 Number.isNaN() ponyfill",
- "license": "MIT",
- "repository": "sindresorhus/number-is-nan",
- "author": {
- "name": "Sindre Sorhus",
- "email": "sindresorhus@gmail.com",
- "url": "sindresorhus.com"
- },
- "engines": {
- "node": ">=0.10.0"
- },
- "scripts": {
- "test": "ava"
- },
- "files": [
- "index.js"
- ],
- "keywords": [
- "es2015",
- "ecmascript",
- "ponyfill",
- "polyfill",
- "shim",
- "number",
- "is",
- "nan",
- "not"
- ],
- "devDependencies": {
- "ava": "*"
- }
-}
diff --git a/deps/npm/node_modules/number-is-nan/readme.md b/deps/npm/node_modules/number-is-nan/readme.md
deleted file mode 100644
index 24635087120128..00000000000000
--- a/deps/npm/node_modules/number-is-nan/readme.md
+++ /dev/null
@@ -1,28 +0,0 @@
-# number-is-nan [![Build Status](https://travis-ci.org/sindresorhus/number-is-nan.svg?branch=master)](https://travis-ci.org/sindresorhus/number-is-nan)
-
-> ES2015 [`Number.isNaN()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN) [ponyfill](https://ponyfill.com)
-
-
-## Install
-
-```
-$ npm install --save number-is-nan
-```
-
-
-## Usage
-
-```js
-var numberIsNan = require('number-is-nan');
-
-numberIsNan(NaN);
-//=> true
-
-numberIsNan('unicorn');
-//=> false
-```
-
-
-## License
-
-MIT © [Sindre Sorhus](http://sindresorhus.com)
diff --git a/deps/npm/package.json b/deps/npm/package.json
index 43456fef9a2ac2..f9ba8cd3c801b6 100644
--- a/deps/npm/package.json
+++ b/deps/npm/package.json
@@ -1,5 +1,5 @@
{
- "version": "8.1.4",
+ "version": "8.2.0",
"name": "npm",
"description": "a package manager for JavaScript",
"workspaces": [
@@ -57,7 +57,7 @@
"@isaacs/string-locale-compare": "^1.1.0",
"@npmcli/arborist": "^4.0.5",
"@npmcli/ci-detect": "^1.4.0",
- "@npmcli/config": "^2.3.0",
+ "@npmcli/config": "^2.3.2",
"@npmcli/map-workspaces": "^2.0.0",
"@npmcli/package-json": "^1.0.1",
"@npmcli/run-script": "^2.0.0",
@@ -96,7 +96,7 @@
"mkdirp": "^1.0.4",
"mkdirp-infer-owner": "^2.0.0",
"ms": "^2.1.2",
- "node-gyp": "^8.4.0",
+ "node-gyp": "^8.4.1",
"nopt": "^5.0.0",
"npm-audit-report": "^2.1.5",
"npm-install-checks": "^4.0.0",
@@ -109,6 +109,7 @@
"opener": "^1.5.2",
"pacote": "^12.0.2",
"parse-conflict-json": "^1.1.1",
+ "proc-log": "^1.0.0",
"qrcode-terminal": "^0.12.0",
"read": "~1.0.7",
"read-package-json": "^4.1.1",
@@ -181,6 +182,7 @@
"opener",
"pacote",
"parse-conflict-json",
+ "proc-log",
"qrcode-terminal",
"read",
"read-package-json",
@@ -199,10 +201,10 @@
],
"devDependencies": {
"@npmcli/eslint-config": "^2.0.0",
- "eslint": "^8.2.0",
+ "eslint": "^8.3.0",
"licensee": "^8.2.0",
"spawk": "^1.7.1",
- "tap": "^15.1.2"
+ "tap": "^15.1.5"
},
"scripts": {
"dumpconf": "env | grep npm | sort | uniq",
diff --git a/deps/npm/tap-snapshots/test/lib/commands/config.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/config.js.test.cjs
index c7be15f0c75eb6..12cd631045a869 100644
--- a/deps/npm/tap-snapshots/test/lib/commands/config.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/commands/config.js.test.cjs
@@ -9,6 +9,7 @@ exports[`test/lib/commands/config.js TAP config list --json > output matches sna
{
"prefix": "{LOCALPREFIX}",
"userconfig": "{HOME}/.npmrc",
+ "cache": "{NPMDIR}/test/lib/commands/tap-testdir-config-config-list---json-sandbox/cache",
"json": true,
"projectloaded": "yes",
"userloaded": "yes",
@@ -24,7 +25,6 @@ exports[`test/lib/commands/config.js TAP config list --json > output matches sna
"bin-links": true,
"browser": null,
"ca": null,
- "cache": "{CACHE}",
"cache-max": null,
"cache-min": 0,
"cafile": null,
@@ -175,7 +175,7 @@ before = null
bin-links = true
browser = null
ca = null
-cache = "{CACHE}"
+; cache = "{CACHE}" ; overridden by cli
cache-max = null
cache-min = 0
cafile = null
@@ -324,6 +324,7 @@ projectloaded = "yes"
; "cli" config from command line options
+cache = "{NPMDIR}/test/lib/commands/tap-testdir-config-config-list---long-sandbox/cache"
long = true
prefix = "{LOCALPREFIX}"
userconfig = "{HOME}/.npmrc"
@@ -332,6 +333,7 @@ userconfig = "{HOME}/.npmrc"
exports[`test/lib/commands/config.js TAP config list > output matches snapshot 1`] = `
; "cli" config from command line options
+cache = "{NPMDIR}/test/lib/commands/tap-testdir-config-config-list-sandbox/cache"
prefix = "{LOCALPREFIX}"
userconfig = "{HOME}/.npmrc"
diff --git a/deps/npm/tap-snapshots/test/lib/commands/shrinkwrap.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/shrinkwrap.js.test.cjs
index a0d5795776d6f1..ddc80a9350f0a6 100644
--- a/deps/npm/tap-snapshots/test/lib/commands/shrinkwrap.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/commands/shrinkwrap.js.test.cjs
@@ -16,7 +16,7 @@ exports[`test/lib/commands/shrinkwrap.js TAP with hidden lockfile ancient > must
},
"config": {},
"shrinkwrap": {
- "name": "tap-testdir-shrinkwrap-with-hidden-lockfile-ancient",
+ "name": "root",
"lockfileVersion": 1,
"requires": true
},
@@ -36,10 +36,10 @@ exports[`test/lib/commands/shrinkwrap.js TAP with hidden lockfile ancient upgrad
}
},
"config": {
- "lockfileVersion": 3
+ "lockfile-version": 3
},
"shrinkwrap": {
- "name": "tap-testdir-shrinkwrap-with-hidden-lockfile-ancient-upgrade",
+ "name": "root",
"lockfileVersion": 3,
"requires": true,
"packages": {}
@@ -61,7 +61,7 @@ exports[`test/lib/commands/shrinkwrap.js TAP with hidden lockfile existing > mus
},
"config": {},
"shrinkwrap": {
- "name": "tap-testdir-shrinkwrap-with-hidden-lockfile-existing",
+ "name": "root",
"lockfileVersion": 2,
"requires": true,
"packages": {}
@@ -82,10 +82,10 @@ exports[`test/lib/commands/shrinkwrap.js TAP with hidden lockfile existing downg
}
},
"config": {
- "lockfileVersion": 1
+ "lockfile-version": 1
},
"shrinkwrap": {
- "name": "tap-testdir-shrinkwrap-with-hidden-lockfile-existing-downgrade",
+ "name": "root",
"lockfileVersion": 1,
"requires": true
},
@@ -105,10 +105,10 @@ exports[`test/lib/commands/shrinkwrap.js TAP with hidden lockfile existing upgra
}
},
"config": {
- "lockfileVersion": 3
+ "lockfile-version": 3
},
"shrinkwrap": {
- "name": "tap-testdir-shrinkwrap-with-hidden-lockfile-existing-upgrade",
+ "name": "root",
"lockfileVersion": 3,
"requires": true,
"packages": {}
@@ -124,7 +124,7 @@ exports[`test/lib/commands/shrinkwrap.js TAP with nothing ancient > must match s
"localPrefix": {},
"config": {},
"shrinkwrap": {
- "name": "tap-testdir-shrinkwrap-with-nothing-ancient",
+ "name": "root",
"lockfileVersion": 2,
"requires": true,
"packages": {}
@@ -139,10 +139,10 @@ exports[`test/lib/commands/shrinkwrap.js TAP with nothing ancient upgrade > must
{
"localPrefix": {},
"config": {
- "lockfileVersion": 3
+ "lockfile-version": 3
},
"shrinkwrap": {
- "name": "tap-testdir-shrinkwrap-with-nothing-ancient-upgrade",
+ "name": "root",
"lockfileVersion": 3,
"requires": true,
"packages": {}
@@ -162,12 +162,12 @@ exports[`test/lib/commands/shrinkwrap.js TAP with npm-shrinkwrap.json ancient >
},
"config": {},
"shrinkwrap": {
- "name": "tap-testdir-shrinkwrap-with-npm-shrinkwrap.json-ancient",
+ "name": "root",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
- "name": "tap-testdir-shrinkwrap-with-npm-shrinkwrap.json-ancient"
+ "name": "root"
}
}
},
@@ -185,15 +185,15 @@ exports[`test/lib/commands/shrinkwrap.js TAP with npm-shrinkwrap.json ancient up
}
},
"config": {
- "lockfileVersion": 3
+ "lockfile-version": 3
},
"shrinkwrap": {
- "name": "tap-testdir-shrinkwrap-with-npm-shrinkwrap.json-ancient-upgrade",
+ "name": "root",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
- "name": "tap-testdir-shrinkwrap-with-npm-shrinkwrap.json-ancient-upgrade"
+ "name": "root"
}
}
},
@@ -212,12 +212,12 @@ exports[`test/lib/commands/shrinkwrap.js TAP with npm-shrinkwrap.json existing >
},
"config": {},
"shrinkwrap": {
- "name": "tap-testdir-shrinkwrap-with-npm-shrinkwrap.json-existing",
+ "name": "root",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
- "name": "tap-testdir-shrinkwrap-with-npm-shrinkwrap.json-existing"
+ "name": "root"
}
}
},
@@ -235,10 +235,10 @@ exports[`test/lib/commands/shrinkwrap.js TAP with npm-shrinkwrap.json existing d
}
},
"config": {
- "lockfileVersion": 1
+ "lockfile-version": 1
},
"shrinkwrap": {
- "name": "tap-testdir-shrinkwrap-with-npm-shrinkwrap.json-existing-downgrade",
+ "name": "root",
"lockfileVersion": 1,
"requires": true
},
@@ -256,15 +256,15 @@ exports[`test/lib/commands/shrinkwrap.js TAP with npm-shrinkwrap.json existing u
}
},
"config": {
- "lockfileVersion": 3
+ "lockfile-version": 3
},
"shrinkwrap": {
- "name": "tap-testdir-shrinkwrap-with-npm-shrinkwrap.json-existing-upgrade",
+ "name": "root",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
- "name": "tap-testdir-shrinkwrap-with-npm-shrinkwrap.json-existing-upgrade"
+ "name": "root"
}
}
},
@@ -283,12 +283,12 @@ exports[`test/lib/commands/shrinkwrap.js TAP with package-lock.json ancient > mu
},
"config": {},
"shrinkwrap": {
- "name": "tap-testdir-shrinkwrap-with-package-lock.json-ancient",
+ "name": "root",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
- "name": "tap-testdir-shrinkwrap-with-package-lock.json-ancient"
+ "name": "root"
}
}
},
@@ -306,15 +306,15 @@ exports[`test/lib/commands/shrinkwrap.js TAP with package-lock.json ancient upgr
}
},
"config": {
- "lockfileVersion": 3
+ "lockfile-version": 3
},
"shrinkwrap": {
- "name": "tap-testdir-shrinkwrap-with-package-lock.json-ancient-upgrade",
+ "name": "root",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
- "name": "tap-testdir-shrinkwrap-with-package-lock.json-ancient-upgrade"
+ "name": "root"
}
}
},
@@ -333,12 +333,12 @@ exports[`test/lib/commands/shrinkwrap.js TAP with package-lock.json existing > m
},
"config": {},
"shrinkwrap": {
- "name": "tap-testdir-shrinkwrap-with-package-lock.json-existing",
+ "name": "root",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
- "name": "tap-testdir-shrinkwrap-with-package-lock.json-existing"
+ "name": "root"
}
}
},
@@ -356,10 +356,10 @@ exports[`test/lib/commands/shrinkwrap.js TAP with package-lock.json existing dow
}
},
"config": {
- "lockfileVersion": 1
+ "lockfile-version": 1
},
"shrinkwrap": {
- "name": "tap-testdir-shrinkwrap-with-package-lock.json-existing-downgrade",
+ "name": "root",
"lockfileVersion": 1,
"requires": true
},
@@ -377,15 +377,15 @@ exports[`test/lib/commands/shrinkwrap.js TAP with package-lock.json existing upg
}
},
"config": {
- "lockfileVersion": 3
+ "lockfile-version": 3
},
"shrinkwrap": {
- "name": "tap-testdir-shrinkwrap-with-package-lock.json-existing-upgrade",
+ "name": "root",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
- "name": "tap-testdir-shrinkwrap-with-package-lock.json-existing-upgrade"
+ "name": "root"
}
}
},
diff --git a/deps/npm/tap-snapshots/test/lib/commands/view.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/view.js.test.cjs
index 10d38cb3f8c061..72d09b44e2620f 100644
--- a/deps/npm/tap-snapshots/test/lib/commands/view.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/commands/view.js.test.cjs
@@ -82,7 +82,7 @@ dist
dist-tags:
[1m[32mlatest[39m[22m: 1.0.0
-published [33myesterday[39m
+published {TIME} ago[39m
`
exports[`test/lib/commands/view.js TAP should log info of package in current working dir specific version > must match snapshot 1`] = `
@@ -99,7 +99,7 @@ dist
dist-tags:
[1m[32mlatest[39m[22m: 1.0.0
-published [33myesterday[39m
+published {TIME} ago[39m
`
exports[`test/lib/commands/view.js TAP should log package info package from git > must match snapshot 1`] = `
@@ -302,7 +302,7 @@ dist
dist-tags:
[1m[32mlatest[39m[22m: 1.0.0
-published [33myesterday[39m
+published {TIME} ago[39m
`
exports[`test/lib/commands/view.js TAP should log package info package with semver range > must match snapshot 1`] = `
@@ -319,7 +319,7 @@ dist
dist-tags:
[1m[32mlatest[39m[22m: 1.0.0
-published [33myesterday[39m
+published {TIME} ago[39m
[4m[1m[32mblue[39m@[32m1.0.1[39m[22m[24m | [1m[31mProprietary[39m[22m | deps: [32mnone[39m | versions: [33m2[39m
diff --git a/deps/npm/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs
index 8c85225f2f998f..84bb22ff0ef59e 100644
--- a/deps/npm/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs
@@ -1087,8 +1087,8 @@ exports[`test/lib/utils/config/definitions.js TAP > config description for logle
* Type: "silent", "error", "warn", "notice", "http", "timing", "info",
"verbose", or "silly"
-What level of logs to report. On failure, *all* logs are written to
-\`npm-debug.log\` in the current working directory.
+What level of logs to report. All logs are written to a debug log, with the
+path to that file printed if the execution of a command fails.
Any logs of a higher level than the setting are shown. The default is
"notice".
@@ -1462,7 +1462,7 @@ exports[`test/lib/utils/config/definitions.js TAP > config description for save-
* Default: false
* Type: Boolean
-Save installed packages. to a package.json file as \`peerDependencies\`
+Save installed packages to a package.json file as \`peerDependencies\`
`
exports[`test/lib/utils/config/definitions.js TAP > config description for save-prefix 1`] = `
diff --git a/deps/npm/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs
index 1ebb336092e390..3db90f7679d4ed 100644
--- a/deps/npm/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs
@@ -888,8 +888,8 @@ Ideal if all users are on npm version 7 and higher.
* Type: "silent", "error", "warn", "notice", "http", "timing", "info",
"verbose", or "silly"
-What level of logs to report. On failure, *all* logs are written to
-\`npm-debug.log\` in the current working directory.
+What level of logs to report. All logs are written to a debug log, with the
+path to that file printed if the execution of a command fails.
Any logs of a higher level than the setting are shown. The default is
"notice".
@@ -1261,7 +1261,7 @@ Save installed packages to a package.json file as \`optionalDependencies\`.
* Default: false
* Type: Boolean
-Save installed packages. to a package.json file as \`peerDependencies\`
+Save installed packages to a package.json file as \`peerDependencies\`
diff --git a/deps/npm/tap-snapshots/test/lib/utils/error-message.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/error-message.js.test.cjs
index f035285d7031a7..069212cec32367 100644
--- a/deps/npm/tap-snapshots/test/lib/utils/error-message.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/utils/error-message.js.test.cjs
@@ -255,7 +255,7 @@ Object {
"summary": Array [
Array [
"notsup",
- "Unsupported platform for lodash@1.0.0: wanted {\\"os\\":\\"!yours,mine\\",\\"arch\\":\\"x867,x5309\\"} (current: {\\"os\\":\\"posix\\",\\"arch\\":\\"x64\\"})",
+ "Unsupported platform for lodash@1.0.0: wanted {/"os/":/"!yours,mine/",/"arch/":/"x867,x5309/"} (current: {/"os/":/"posix/",/"arch/":/"x64/"})",
],
],
}
@@ -277,7 +277,7 @@ Object {
"summary": Array [
Array [
"notsup",
- "Unsupported platform for lodash@1.0.0: wanted {\\"os\\":\\"!yours\\",\\"arch\\":\\"x420\\"} (current: {\\"os\\":\\"posix\\",\\"arch\\":\\"x64\\"})",
+ "Unsupported platform for lodash@1.0.0: wanted {/"os/":/"!yours/",/"arch/":/"x420/"} (current: {/"os/":/"posix/",/"arch/":/"x64/"})",
],
],
}
@@ -394,7 +394,7 @@ Object {
"",
Error: whoopsie {
"code": "EACCES",
- "dest": "/some/cache/dir/dest",
+ "dest": "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-false-loaded-false-cachePath-false-cacheDest-true-/cache/dest",
"path": "/not/cache/dir/path",
},
],
@@ -428,7 +428,7 @@ Object {
Error: whoopsie {
"code": "EACCES",
"dest": "/not/cache/dir/dest",
- "path": "/some/cache/dir/path",
+ "path": "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-false-loaded-false-cachePath-true-cacheDest-false-/cache/path",
},
],
],
@@ -460,8 +460,8 @@ Object {
"",
Error: whoopsie {
"code": "EACCES",
- "dest": "/some/cache/dir/dest",
- "path": "/some/cache/dir/path",
+ "dest": "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-false-loaded-false-cachePath-true-cacheDest-true-/cache/dest",
+ "path": "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-false-loaded-false-cachePath-true-cacheDest-true-/cache/path",
},
],
],
@@ -502,7 +502,12 @@ Object {
`
exports[`test/lib/utils/error-message.js TAP eacces/eperm {"windows":false,"loaded":true,"cachePath":false,"cacheDest":false} > must match snapshot 2`] = `
-Array []
+Array [
+ Array [
+ "logfile",
+ "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-false-loaded-true-cachePath-false-cacheDest-false-/cache/_logs/{DATE}-debug-0.log",
+ ],
+]
`
exports[`test/lib/utils/error-message.js TAP eacces/eperm {"windows":false,"loaded":true,"cachePath":false,"cacheDest":true} > must match snapshot 1`] = `
@@ -517,7 +522,7 @@ Object {
previous versions of npm which has since been addressed.
To permanently fix this problem, please run:
- sudo chown -R 867:5309 "/some/cache/dir"
+ sudo chown -R 867:5309 "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-false-loaded-true-cachePath-false-cacheDest-true-/cache"
),
],
],
@@ -526,6 +531,10 @@ Object {
exports[`test/lib/utils/error-message.js TAP eacces/eperm {"windows":false,"loaded":true,"cachePath":false,"cacheDest":true} > must match snapshot 2`] = `
Array [
+ Array [
+ "logfile",
+ "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-false-loaded-true-cachePath-false-cacheDest-true-/cache/_logs/{DATE}-debug-0.log",
+ ],
Array [
"dummy stack trace",
],
@@ -544,7 +553,7 @@ Object {
previous versions of npm which has since been addressed.
To permanently fix this problem, please run:
- sudo chown -R 867:5309 "/some/cache/dir"
+ sudo chown -R 867:5309 "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-false-loaded-true-cachePath-true-cacheDest-false-/cache"
),
],
],
@@ -553,6 +562,10 @@ Object {
exports[`test/lib/utils/error-message.js TAP eacces/eperm {"windows":false,"loaded":true,"cachePath":true,"cacheDest":false} > must match snapshot 2`] = `
Array [
+ Array [
+ "logfile",
+ "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-false-loaded-true-cachePath-true-cacheDest-false-/cache/_logs/{DATE}-debug-0.log",
+ ],
Array [
"dummy stack trace",
],
@@ -571,7 +584,7 @@ Object {
previous versions of npm which has since been addressed.
To permanently fix this problem, please run:
- sudo chown -R 867:5309 "/some/cache/dir"
+ sudo chown -R 867:5309 "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-false-loaded-true-cachePath-true-cacheDest-true-/cache"
),
],
],
@@ -580,6 +593,10 @@ Object {
exports[`test/lib/utils/error-message.js TAP eacces/eperm {"windows":false,"loaded":true,"cachePath":true,"cacheDest":true} > must match snapshot 2`] = `
Array [
+ Array [
+ "logfile",
+ "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-false-loaded-true-cachePath-true-cacheDest-true-/cache/_logs/{DATE}-debug-0.log",
+ ],
Array [
"dummy stack trace",
],
@@ -642,7 +659,7 @@ Object {
"",
Error: whoopsie {
"code": "EACCES",
- "dest": "/some/cache/dir/dest",
+ "dest": "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-true-loaded-false-cachePath-false-cacheDest-true-/cache/dest",
"path": "/not/cache/dir/path",
},
],
@@ -677,7 +694,7 @@ Object {
Error: whoopsie {
"code": "EACCES",
"dest": "/not/cache/dir/dest",
- "path": "/some/cache/dir/path",
+ "path": "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-true-loaded-false-cachePath-true-cacheDest-false-/cache/path",
},
],
],
@@ -710,8 +727,8 @@ Object {
"",
Error: whoopsie {
"code": "EACCES",
- "dest": "/some/cache/dir/dest",
- "path": "/some/cache/dir/path",
+ "dest": "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-true-loaded-false-cachePath-true-cacheDest-true-/cache/dest",
+ "path": "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-true-loaded-false-cachePath-true-cacheDest-true-/cache/path",
},
],
],
@@ -753,7 +770,12 @@ Object {
`
exports[`test/lib/utils/error-message.js TAP eacces/eperm {"windows":true,"loaded":true,"cachePath":false,"cacheDest":false} > must match snapshot 2`] = `
-Array []
+Array [
+ Array [
+ "logfile",
+ "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-true-loaded-true-cachePath-false-cacheDest-false-/cache/_logs/{DATE}-debug-0.log",
+ ],
+]
`
exports[`test/lib/utils/error-message.js TAP eacces/eperm {"windows":true,"loaded":true,"cachePath":false,"cacheDest":true} > must match snapshot 1`] = `
@@ -778,7 +800,7 @@ Object {
"",
Error: whoopsie {
"code": "EACCES",
- "dest": "/some/cache/dir/dest",
+ "dest": "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-true-loaded-true-cachePath-false-cacheDest-true-/cache/dest",
"path": "/not/cache/dir/path",
},
],
@@ -787,7 +809,12 @@ Object {
`
exports[`test/lib/utils/error-message.js TAP eacces/eperm {"windows":true,"loaded":true,"cachePath":false,"cacheDest":true} > must match snapshot 2`] = `
-Array []
+Array [
+ Array [
+ "logfile",
+ "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-true-loaded-true-cachePath-false-cacheDest-true-/cache/_logs/{DATE}-debug-0.log",
+ ],
+]
`
exports[`test/lib/utils/error-message.js TAP eacces/eperm {"windows":true,"loaded":true,"cachePath":true,"cacheDest":false} > must match snapshot 1`] = `
@@ -813,7 +840,7 @@ Object {
Error: whoopsie {
"code": "EACCES",
"dest": "/not/cache/dir/dest",
- "path": "/some/cache/dir/path",
+ "path": "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-true-loaded-true-cachePath-true-cacheDest-false-/cache/path",
},
],
],
@@ -821,7 +848,12 @@ Object {
`
exports[`test/lib/utils/error-message.js TAP eacces/eperm {"windows":true,"loaded":true,"cachePath":true,"cacheDest":false} > must match snapshot 2`] = `
-Array []
+Array [
+ Array [
+ "logfile",
+ "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-true-loaded-true-cachePath-true-cacheDest-false-/cache/_logs/{DATE}-debug-0.log",
+ ],
+]
`
exports[`test/lib/utils/error-message.js TAP eacces/eperm {"windows":true,"loaded":true,"cachePath":true,"cacheDest":true} > must match snapshot 1`] = `
@@ -846,8 +878,8 @@ Object {
"",
Error: whoopsie {
"code": "EACCES",
- "dest": "/some/cache/dir/dest",
- "path": "/some/cache/dir/path",
+ "dest": "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-true-loaded-true-cachePath-true-cacheDest-true-/cache/dest",
+ "path": "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-true-loaded-true-cachePath-true-cacheDest-true-/cache/path",
},
],
],
@@ -855,7 +887,12 @@ Object {
`
exports[`test/lib/utils/error-message.js TAP eacces/eperm {"windows":true,"loaded":true,"cachePath":true,"cacheDest":true} > must match snapshot 2`] = `
-Array []
+Array [
+ Array [
+ "logfile",
+ "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-true-loaded-true-cachePath-true-cacheDest-true-/cache/_logs/{DATE}-debug-0.log",
+ ],
+]
`
exports[`test/lib/utils/error-message.js TAP enoent without a file > must match snapshot 1`] = `
@@ -863,7 +900,7 @@ Object {
"detail": Array [
Array [
"enoent",
- "This is related to npm not being able to find a file.\\n",
+ "This is related to npm not being able to find a file./n",
],
],
"summary": Array [
diff --git a/deps/npm/tap-snapshots/test/lib/utils/exit-handler.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/exit-handler.js.test.cjs
index eb383c104a6744..523aabca29b50f 100644
--- a/deps/npm/tap-snapshots/test/lib/utils/exit-handler.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/utils/exit-handler.js.test.cjs
@@ -5,16 +5,56 @@
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
-exports[`test/lib/utils/exit-handler.js TAP handles unknown error > should have expected log contents for unknown error 1`] = `
-24 verbose stack Error: ERROR
-25 verbose cwd {CWD}
-26 verbose Foo 1.0.0
-27 verbose argv "/node" "{CWD}/test/lib/utils/exit-handler.js"
-28 verbose node v1.0.0
-29 verbose npm v1.0.0
-30 error code ERROR
-31 error ERR ERROR
-32 error ERR ERROR
-33 verbose exit 1
+exports[`test/lib/utils/exit-handler.js TAP handles unknown error with logs and debug file > debug file contents 1`] = `
+0 timing npm:load:whichnode Completed in {TIME}ms
+15 timing config:load Completed in {TIME}ms
+16 timing npm:load:configload Completed in {TIME}ms
+17 timing npm:load:setTitle Completed in {TIME}ms
+19 timing npm:load:display Completed in {TIME}ms
+20 verbose logfile {CWD}/test/lib/utils/tap-testdir-exit-handler-handles-unknown-error-with-logs-and-debug-file/cache/_logs/{DATE}-debug-0.log
+21 timing npm:load:logFile Completed in {TIME}ms
+22 timing npm:load:timers Completed in {TIME}ms
+23 timing npm:load:configScope Completed in {TIME}ms
+24 timing npm:load Completed in {TIME}ms
+25 verbose stack Error: Unknown error
+26 verbose cwd {CWD}
+27 verbose Foo 1.0.0
+28 verbose argv "/node" "{CWD}/test/lib/utils/exit-handler.js"
+29 verbose node v1.0.0
+30 verbose npm v1.0.0
+31 error code ECODE
+32 error ERR SUMMARY Unknown error
+33 error ERR DETAIL Unknown error
+34 verbose exit 1
+35 timing npm Completed in {TIME}ms
+36 verbose code 1
+37 error A complete log of this run can be found in:
+37 error {CWD}/test/lib/utils/tap-testdir-exit-handler-handles-unknown-error-with-logs-and-debug-file/cache/_logs/{DATE}-debug-0.log
+`
+exports[`test/lib/utils/exit-handler.js TAP handles unknown error with logs and debug file > logs 1`] = `
+timing npm:load:whichnode Completed in {TIME}ms
+timing config:load Completed in {TIME}ms
+timing npm:load:configload Completed in {TIME}ms
+timing npm:load:setTitle Completed in {TIME}ms
+timing npm:load:display Completed in {TIME}ms
+verbose logfile {CWD}/test/lib/utils/tap-testdir-exit-handler-handles-unknown-error-with-logs-and-debug-file/cache/_logs/{DATE}-debug-0.log
+timing npm:load:logFile Completed in {TIME}ms
+timing npm:load:timers Completed in {TIME}ms
+timing npm:load:configScope Completed in {TIME}ms
+timing npm:load Completed in {TIME}ms
+verbose stack Error: Unknown error
+verbose cwd {CWD}
+verbose Foo 1.0.0
+verbose argv "/node" "{CWD}/test/lib/utils/exit-handler.js"
+verbose node v1.0.0
+verbose npm v1.0.0
+error code ECODE
+error ERR SUMMARY Unknown error
+error ERR DETAIL Unknown error
+verbose exit 1
+timing npm Completed in {TIME}ms
+verbose code 1
+error A complete log of this run can be found in:
+ {CWD}/test/lib/utils/tap-testdir-exit-handler-handles-unknown-error-with-logs-and-debug-file/cache/_logs/{DATE}-debug-0.log
`
diff --git a/deps/npm/tap-snapshots/test/lib/utils/log-file.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/log-file.js.test.cjs
new file mode 100644
index 00000000000000..ecce9eafcc925b
--- /dev/null
+++ b/deps/npm/tap-snapshots/test/lib/utils/log-file.js.test.cjs
@@ -0,0 +1,68 @@
+/* IMPORTANT
+ * This snapshot file is auto-generated, but designed for humans.
+ * It should be checked into source control and tracked carefully.
+ * Re-generate by setting TAP_SNAPSHOT=1 and running tests.
+ * Make sure to inspect the output below. Do not ignore changes!
+ */
+'use strict'
+exports[`test/lib/utils/log-file.js TAP snapshot > must match snapshot 1`] = `
+0 error no prefix
+1 error prefix with prefix
+2 error prefix 1 2 3
+3 verbose { obj: { with: { many: [Object] } } }
+4 verbose {"obj":{"with":{"many":{"props":1}}}}
+5 verbose {
+5 verbose "obj": {
+5 verbose "with": {
+5 verbose "many": {
+5 verbose "props": 1
+5 verbose }
+5 verbose }
+5 verbose }
+5 verbose }
+6 verbose [ 'test', 'with', 'an', 'array' ]
+7 verbose ["test","with","an","array"]
+8 verbose [
+8 verbose "test",
+8 verbose "with",
+8 verbose "an",
+8 verbose "array"
+8 verbose ]
+9 verbose [ 'test', [ 'with', [ 'an', [Array] ] ] ]
+10 verbose ["test",["with",["an",["array"]]]]
+11 verbose [
+11 verbose "test",
+11 verbose [
+11 verbose "with",
+11 verbose [
+11 verbose "an",
+11 verbose [
+11 verbose "array"
+11 verbose ]
+11 verbose ]
+11 verbose ]
+11 verbose ]
+12 error pre has many errors Error: message
+12 error pre at stack trace line 0
+12 error pre at stack trace line 1
+12 error pre at stack trace line 2
+12 error pre at stack trace line 3
+12 error pre at stack trace line 4
+12 error pre at stack trace line 5
+12 error pre at stack trace line 6
+12 error pre at stack trace line 7
+12 error pre at stack trace line 8
+12 error pre at stack trace line 9 Error: message2
+12 error pre at stack trace line 0
+12 error pre at stack trace line 1
+12 error pre at stack trace line 2
+12 error pre at stack trace line 3
+12 error pre at stack trace line 4
+12 error pre at stack trace line 5
+12 error pre at stack trace line 6
+12 error pre at stack trace line 7
+12 error pre at stack trace line 8
+12 error pre at stack trace line 9
+13 error nostack [Error: message]
+
+`
diff --git a/deps/npm/test/fixtures/clean-snapshot.js b/deps/npm/test/fixtures/clean-snapshot.js
new file mode 100644
index 00000000000000..037155eea186d6
--- /dev/null
+++ b/deps/npm/test/fixtures/clean-snapshot.js
@@ -0,0 +1,19 @@
+// XXX: this also cleans quoted " in json snapshots
+// ideally this could be avoided but its easier to just
+// run this command inside cleanSnapshot
+const normalizePath = (str) => str
+ .replace(/\r\n/g, '\n') // normalize line endings (for ini)
+ .replace(/[A-z]:\\/g, '\\') // turn windows roots to posix ones
+ .replace(/\\+/g, '/') // replace \ with /
+
+const cleanCwd = (path) => normalizePath(path)
+ .replace(new RegExp(normalizePath(process.cwd()), 'g'), '{CWD}')
+
+const cleanDate = (str) =>
+ str.replace(/\d{4}-\d{2}-\d{2}T\d{2}[_:]\d{2}[_:]\d{2}[_:]\d{3}Z/g, '{DATE}')
+
+module.exports = {
+ normalizePath,
+ cleanCwd,
+ cleanDate,
+}
diff --git a/deps/npm/test/fixtures/mock-globals.js b/deps/npm/test/fixtures/mock-globals.js
new file mode 100644
index 00000000000000..29da2a48b092d2
--- /dev/null
+++ b/deps/npm/test/fixtures/mock-globals.js
@@ -0,0 +1,210 @@
+// An initial implementation for a feature that will hopefully exist in tap
+// https://github.com/tapjs/node-tap/issues/789
+// This file is only used in tests but it is still tested itself.
+// Hopefully it can be removed for a feature in tap in the future
+
+const sep = '.'
+const has = (o, k) => Object.prototype.hasOwnProperty.call(o, k)
+const opd = (o, k) => Object.getOwnPropertyDescriptor(o, k)
+const po = (o) => Object.getPrototypeOf(o)
+const pojo = (o) => Object.prototype.toString.call(o) === '[object Object]'
+const last = (arr) => arr[arr.length - 1]
+const splitLast = (str) => str.split(new RegExp(`\\${sep}(?=[^${sep}]+$)`))
+const dupes = (arr) => arr.filter((k, i) => arr.indexOf(k) !== i)
+const dupesStartsWith = (arr) => arr.filter((k1) => arr.some((k2) => k2.startsWith(k1 + sep)))
+
+// A weird getter that can look up keys on nested objects but also
+// match keys with dots in their names, eg { 'process.env': { TERM: 'a' } }
+// can be looked up with the key 'process.env.TERM'
+const get = (obj, key, childKey = '') => {
+ if (has(obj, key)) {
+ return childKey ? get(obj[key], childKey) : obj[key]
+ } else if (key.includes(sep)) {
+ const [parentKey, prefix] = splitLast(key)
+ return get(
+ obj,
+ parentKey,
+ prefix + (childKey && sep + childKey)
+ )
+ }
+}
+
+// Map an object to an array of nested keys separated by dots
+// { a: 1, b: { c: 2, d: [1] } } => ['a', 'b.c', 'b.d']
+const getKeys = (values, p = '', acc = []) =>
+ Object.entries(values).reduce((memo, [k, value]) => {
+ const key = p ? [p, k].join(sep) : k
+ return pojo(value) ? getKeys(value, key, memo) : memo.concat(key)
+ }, acc)
+
+// Walk prototype chain to get first available descriptor. This is necessary
+// to get the current property descriptor for things like `process.on`.
+// Since `opd(process, 'on') === undefined` but if you
+// walk up the prototype chain you get the original descriptor
+// `opd(po(po(process)), 'on') === { value, ... }`
+const protoDescriptor = (obj, key) => {
+ let descriptor
+ // i always wanted to assign variables in a while loop's condition
+ // i thought it would feel better than this
+ while (!(descriptor = opd(obj, key))) {
+ if (!(obj = po(obj))) {
+ break
+ }
+ }
+ return descriptor
+}
+
+// Path can be different cases across platform so get the original case
+// of the path before anything is changed
+// XXX: other special cases to handle?
+const specialCaseKeys = (() => {
+ const originalKeys = {
+ PATH: process.env.PATH ? 'PATH' : process.env.Path ? 'Path' : 'path',
+ }
+ return (key) => {
+ switch (key.toLowerCase()) {
+ case 'process.env.path':
+ return originalKeys.PATH
+ }
+ }
+})()
+
+const _setGlobal = Symbol('setGlobal')
+const _nextDescriptor = Symbol('nextDescriptor')
+
+class DescriptorStack {
+ #stack = []
+ #global = null
+ #valueKey = null
+ #defaultDescriptor = { configurable: true, writable: true, enumerable: true }
+ #delete = () => ({ DELETE: true })
+ #isDelete = (o) => o && o.DELETE === true
+
+ constructor (key) {
+ const keys = splitLast(key)
+ this.#global = keys.length === 1 ? global : get(global, keys[0])
+ this.#valueKey = specialCaseKeys(key) || last(keys)
+ // If the global object doesnt return a descriptor for the key
+ // then we mark it for deletion on teardown
+ this.#stack = [
+ protoDescriptor(this.#global, this.#valueKey) || this.#delete(),
+ ]
+ }
+
+ add (value) {
+ // This must be a unique object so we can find it later via indexOf
+ // That's why delete/nextDescriptor create new objects
+ const nextDescriptor = this[_nextDescriptor](value)
+ this.#stack.push(this[_setGlobal](nextDescriptor))
+
+ return () => {
+ const index = this.#stack.indexOf(nextDescriptor)
+ // If the stack doesnt contain the descriptor anymore
+ // than do nothing. This keeps the reset function indempotent
+ if (index > -1) {
+ // Resetting removes a descriptor from the stack
+ this.#stack.splice(index, 1)
+ // But we always reset to what is now the most recent in case
+ // resets are being called manually out of order
+ this[_setGlobal](last(this.#stack))
+ }
+ }
+ }
+
+ reset () {
+ // Everything could be reset manually so only
+ // teardown if we have an initial descriptor left
+ // and then delete the rest of the stack
+ if (this.#stack.length) {
+ this[_setGlobal](this.#stack[0])
+ this.#stack.length = 0
+ }
+ }
+
+ [_setGlobal] (d) {
+ if (this.#isDelete(d)) {
+ delete this.#global[this.#valueKey]
+ } else {
+ Object.defineProperty(this.#global, this.#valueKey, d)
+ }
+ return d
+ }
+
+ [_nextDescriptor] (value) {
+ if (value === undefined) {
+ return this.#delete()
+ }
+ const d = last(this.#stack)
+ return {
+ // If the previous descriptor was one to delete the property
+ // then use the default descriptor as the base
+ ...(this.#isDelete(d) ? this.#defaultDescriptor : d),
+ ...(d && d.get ? { get: () => value } : { value }),
+ }
+ }
+}
+
+class MockGlobals {
+ #descriptors = {}
+
+ register (globals, { replace = false } = {}) {
+ // Replace means dont merge in object values but replace them instead
+ // so we only get top level keys instead of walking the obj
+ const keys = replace ? Object.keys(globals) : getKeys(globals)
+
+ // An error state where due to object mode there are multiple global
+ // values to be set with the same key
+ const duplicates = dupes(keys)
+ if (duplicates.length) {
+ throw new Error(`mockGlobals was called with duplicate keys: ${duplicates}`)
+ }
+
+ // Another error where when in replace mode overlapping keys are set like
+ // process and process.stdout which would cause unexpected behavior
+ const overlapping = dupesStartsWith(keys)
+ if (overlapping.length) {
+ const message = overlapping
+ .map((k) => `${k} -> ${keys.filter((kk) => kk.startsWith(k + sep))}`)
+ throw new Error(`mockGlobals was called with overlapping keys: ${message}`)
+ }
+
+ // Set each property passed in and return fns to reset them
+ // Return an object with each path as a key for manually resetting in each test
+ return keys.reduce((acc, key) => {
+ const desc = this.#descriptors[key] || (this.#descriptors[key] = new DescriptorStack(key))
+ acc[key] = desc.add(get(globals, key))
+ return acc
+ }, {})
+ }
+
+ teardown (key) {
+ if (!key) {
+ Object.values(this.#descriptors).forEach((d) => d.reset())
+ return
+ }
+ this.#descriptors[key].reset()
+ }
+}
+
+// Each test has one instance of MockGlobals so it can be called multiple times per test
+// Its a weak map so that it can be garbage collected along with the tap tests without
+// needing to explicitly call cache.delete
+const cache = new WeakMap()
+
+module.exports = (t, globals, options) => {
+ let instance = cache.get(t)
+ if (!instance) {
+ instance = cache.set(t, new MockGlobals()).get(t)
+ // Teardown only needs to be initialized once. The instance
+ // will keep track of its own state during the test
+ t.teardown(() => instance.teardown())
+ }
+
+ return {
+ // Reset contains only the functions to reset the globals
+ // set by this function call
+ reset: instance.register(globals, options),
+ // Teardown will reset across all calls tied to this test
+ teardown: () => instance.teardown(),
+ }
+}
diff --git a/deps/npm/test/fixtures/mock-logs.js b/deps/npm/test/fixtures/mock-logs.js
new file mode 100644
index 00000000000000..80037c6ffa88d9
--- /dev/null
+++ b/deps/npm/test/fixtures/mock-logs.js
@@ -0,0 +1,71 @@
+
+const NPMLOG = require('npmlog')
+const { LEVELS } = require('proc-log')
+
+const merge = (...objs) => objs.reduce((acc, obj) => ({ ...acc, ...obj }))
+
+const mockLogs = (otherMocks = {}) => {
+ // Return mocks as an array with getters for each level
+ // that return an array of logged properties with the
+ // level removed. This is for convenience throughout tests
+ const logs = Object.defineProperties(
+ [],
+ ['timing', ...LEVELS].reduce((acc, level) => {
+ acc[level] = {
+ get () {
+ return this
+ .filter(([l]) => level === l)
+ .map(([l, ...args]) => args)
+ },
+ }
+ return acc
+ }, {})
+ )
+
+ // This returns an object with mocked versions of all necessary
+ // logging modules. It mocks them with methods that add logs
+ // to an array which it also returns. The reason it also returns
+ // the mocks is that in tests the same instance of these mocks
+ // should be passed to multiple calls to t.mock.
+ // XXX: this is messy and fragile and should be removed in favor
+ // of some other way to collect and filter logs across all tests
+ const logMocks = {
+ 'proc-log': merge(
+ { LEVELS },
+ LEVELS.reduce((acc, l) => {
+ acc[l] = (...args) => {
+ // Re-emit log item for since the log file listens on these
+ process.emit('log', l, ...args)
+ // Dont add pause/resume events to the logs. Those aren't displayed
+ // and emitting them is tested in the display layer
+ if (l !== 'pause' && l !== 'resume') {
+ logs.push([l, ...args])
+ }
+ }
+ return acc
+ }, {}),
+ otherMocks['proc-log']
+ ),
+ // Object.assign is important here because we need to assign
+ // mocked properties directly to npmlog and then mock with that
+ // object. This is necessary so tests can still directly set
+ // `log.level = 'silent'` anywhere in the test and have that
+ // that reflected in the npmlog singleton.
+ // XXX: remove with npmlog
+ npmlog: Object.assign(NPMLOG, merge(
+ // no-op all npmlog methods by default so tests
+ // dont output anything to the terminal
+ Object.keys(NPMLOG.levels).reduce((acc, k) => {
+ acc[k] = () => {}
+ return acc
+ }, {}),
+ // except collect timing logs
+ { timing: (...args) => logs.push(['timing', ...args]) },
+ otherMocks.npmlog
+ )),
+ }
+
+ return { logs, logMocks }
+}
+
+module.exports = mockLogs
diff --git a/deps/npm/test/fixtures/mock-npm.js b/deps/npm/test/fixtures/mock-npm.js
index a51ec3e5bb8796..7518855319b4ae 100644
--- a/deps/npm/test/fixtures/mock-npm.js
+++ b/deps/npm/test/fixtures/mock-npm.js
@@ -1,71 +1,126 @@
-const npmlog = require('npmlog')
-const procLog = require('../../lib/utils/proc-log-listener.js')
-procLog.reset()
-
-// In theory we shouldn't have to do this if all the tests were tearing down
-// their listeners properly, we're still getting warnings even though
-// perfStop() and procLog.reset() is in the teardown script. This silences the
-// warnings for now
-require('events').defaultMaxListeners = Infinity
-
-const realLog = {}
-for (const level in npmlog.levels) {
- realLog[level] = npmlog[level]
-}
-
-const { title, execPath } = process
+const os = require('os')
+const fs = require('fs').promises
+const path = require('path')
+const mockLogs = require('./mock-logs')
+const mockGlobals = require('./mock-globals')
+const log = require('../../lib/utils/log-shim')
-// Eventually this should default to having a prefix of an empty testdir, and
-// awaiting npm.load() unless told not to (for npm tests for example). Ideally
-// the prefix of an empty dir is inferred rather than explicitly set
const RealMockNpm = (t, otherMocks = {}) => {
- const mock = {}
- mock.logs = []
- mock.outputs = []
- mock.joinedOutput = () => {
- return mock.outputs.map(o => o.join(' ')).join('\n')
+ const mock = {
+ ...mockLogs(otherMocks),
+ outputs: [],
+ joinedOutput: () => mock.outputs.map(o => o.join(' ')).join('\n'),
}
- mock.filteredLogs = title => mock.logs.filter(([t]) => t === title).map(([, , msg]) => msg)
- const Npm = t.mock('../../lib/npm.js', otherMocks)
- class MockNpm extends Npm {
- constructor () {
- super()
- for (const level in npmlog.levels) {
- npmlog[level] = (...msg) => {
- mock.logs.push([level, ...msg])
-
- const l = npmlog.level
- npmlog.level = 'silent'
- realLog[level](...msg)
- npmlog.level = l
- }
- }
- // npm.js tests need this restored to actually test this function!
- mock.npmOutput = this.output
- this.output = (...msg) => mock.outputs.push(msg)
+
+ const Npm = t.mock('../../lib/npm.js', {
+ ...otherMocks,
+ ...mock.logMocks,
+ })
+
+ mock.Npm = class MockNpm extends Npm {
+ // lib/npm.js tests needs this to actually test the function!
+ originalOutput (...args) {
+ super.output(...args)
+ }
+
+ output (...args) {
+ mock.outputs.push(args)
}
}
- mock.Npm = MockNpm
- t.afterEach(() => {
- mock.outputs.length = 0
- mock.logs.length = 0
+
+ return mock
+}
+
+// Resolve some options to a function call with supplied args
+const result = (fn, ...args) => typeof fn === 'function' ? fn(...args) : fn
+
+const LoadMockNpm = async (t, {
+ init = true,
+ load = init,
+ testdir = {},
+ config = {},
+ mocks = {},
+ globals = null,
+} = {}) => {
+ // Mock some globals with their original values so they get torn down
+ // back to the original at the end of the test since they are manipulated
+ // by npm itself
+ mockGlobals(t, {
+ process: {
+ title: process.title,
+ execPath: process.execPath,
+ env: {
+ npm_command: process.env.npm_command,
+ COLOR: process.env.COLOR,
+ },
+ },
})
- t.teardown(() => {
- process.removeAllListeners('time')
- process.removeAllListeners('timeEnd')
- npmlog.record.length = 0
- for (const level in npmlog.levels) {
- npmlog[level] = realLog[level]
- }
- procLog.reset()
- process.title = title
- process.execPath = execPath
- delete process.env.npm_command
- delete process.env.COLOR
+ const { Npm, ...rest } = RealMockNpm(t, mocks)
+
+ if (!init && load) {
+ throw new Error('cant `load` without `init`')
+ }
+
+ const _level = log.level
+ t.teardown(() => log.level = _level)
+
+ if (config.loglevel) {
+ // Set log level as early as possible since it is set
+ // on the npmlog singleton and shared across everything
+ log.level = config.loglevel
+ }
+
+ const dir = t.testdir({ root: testdir, cache: {} })
+ const prefix = path.join(dir, 'root')
+ const cache = path.join(dir, 'cache')
+
+ // Set cache to testdir via env var so it is available when load is run
+ // XXX: remove this for a solution where cache argv is passed in
+ mockGlobals(t, {
+ 'process.env.npm_config_cache': cache,
})
- return mock
+ if (globals) {
+ mockGlobals(t, result(globals, { prefix, cache }))
+ }
+
+ const npm = init ? new Npm() : null
+ t.teardown(() => npm && npm.unload())
+
+ if (load) {
+ await npm.load()
+ for (const [k, v] of Object.entries(result(config, { npm, prefix, cache }))) {
+ npm.config.set(k, v)
+ }
+ if (config.loglevel) {
+ // Set global loglevel *again* since it possibly got reset during load
+ // XXX: remove with npmlog
+ log.level = config.loglevel
+ }
+ npm.prefix = prefix
+ npm.cache = cache
+ }
+
+ return {
+ ...rest,
+ Npm,
+ npm,
+ prefix,
+ cache,
+ debugFile: async () => {
+ const readFiles = npm.logFiles.map(f => fs.readFile(f))
+ const logFiles = await Promise.all(readFiles)
+ return logFiles
+ .flatMap((d) => d.toString().trim().split(os.EOL))
+ .filter(Boolean)
+ .join('\n')
+ },
+ timingFile: async () => {
+ const data = await fs.readFile(path.resolve(cache, '_timing.json'), 'utf8')
+ return JSON.parse(data) // XXX: this fails if multiple timings are written
+ },
+ }
}
const realConfig = require('../../lib/utils/config')
@@ -96,21 +151,6 @@ class MockNpm {
set: (k, v) => config[k] = v,
list: [{ ...realConfig.defaults, ...config }],
}
- if (!this.log) {
- this.log = {
- clearProgress: () => {},
- disableProgress: () => {},
- enableProgress: () => {},
- http: () => {},
- info: () => {},
- levels: [],
- notice: () => {},
- pause: () => {},
- silly: () => {},
- verbose: () => {},
- warn: () => {},
- }
- }
}
output (...msg) {
@@ -127,5 +167,5 @@ const FakeMockNpm = (base = {}) => {
module.exports = {
fake: FakeMockNpm,
- real: RealMockNpm,
+ load: LoadMockNpm,
}
diff --git a/deps/npm/test/fixtures/sandbox.js b/deps/npm/test/fixtures/sandbox.js
index b012790fb535d1..701d9cea723977 100644
--- a/deps/npm/test/fixtures/sandbox.js
+++ b/deps/npm/test/fixtures/sandbox.js
@@ -4,15 +4,12 @@ const { homedir, tmpdir } = require('os')
const { dirname, join } = require('path')
const { promisify } = require('util')
const mkdirp = require('mkdirp-infer-owner')
-const npmlog = require('npmlog')
const rimraf = promisify(require('rimraf'))
+const mockLogs = require('./mock-logs')
const chain = new Map()
const sandboxes = new Map()
-// Disable lint errors for assigning to process global
-/* global process:writable */
-
// keep a reference to the real process
const _process = process
@@ -34,19 +31,6 @@ createHook({
},
}).enable()
-for (const level in npmlog.levels) {
- npmlog[`_${level}`] = npmlog[level]
- npmlog[level] = (...args) => {
- process._logs = process._logs || {}
- process._logs[level] = process._logs[level] || []
- process._logs[level].push(args)
- const _level = npmlog.level
- npmlog.level = 'silent'
- npmlog[`_${level}`](...args)
- npmlog.level = _level
- }
-}
-
const _data = Symbol('sandbox.data')
const _dirs = Symbol('sandbox.dirs')
const _test = Symbol('sandbox.test')
@@ -57,6 +41,7 @@ const _output = Symbol('sandbox.output')
const _proxy = Symbol('sandbox.proxy')
const _get = Symbol('sandbox.proxy.get')
const _set = Symbol('sandbox.proxy.set')
+const _logs = Symbol('sandbox.logs')
// these config keys can be redacted widely
const redactedDefaults = [
@@ -92,6 +77,7 @@ class Sandbox extends EventEmitter {
global: options.global || join(tempDir, 'global'),
home: options.home || join(tempDir, 'home'),
project: options.project || join(tempDir, 'project'),
+ cache: options.cache || join(tempDir, 'cache'),
}
this[_proxy] = new Proxy(_process, {
@@ -111,7 +97,7 @@ class Sandbox extends EventEmitter {
}
get logs () {
- return this[_proxy]._logs
+ return this[_logs]
}
get global () {
@@ -126,6 +112,10 @@ class Sandbox extends EventEmitter {
return this[_dirs].project
}
+ get cache () {
+ return this[_dirs].cache
+ }
+
get process () {
return this[_proxy]
}
@@ -205,7 +195,9 @@ class Sandbox extends EventEmitter {
if (this[_parent]) {
sandboxes.delete(this[_parent])
}
-
+ if (this[_npm]) {
+ this[_npm].unload()
+ }
return rimraf(this[_dirs].temp).catch(() => null)
}
@@ -275,11 +267,17 @@ class Sandbox extends EventEmitter {
'--prefix', this.project,
'--userconfig', join(this.home, '.npmrc'),
'--globalconfig', join(this.global, 'npmrc'),
+ '--cache', this.cache,
command,
...argv,
]
- const Npm = this[_test].mock('../../lib/npm.js', this[_mocks])
+ const mockedLogs = mockLogs(this[_mocks])
+ this[_logs] = mockedLogs.logs
+ const Npm = this[_test].mock('../../lib/npm.js', {
+ ...this[_mocks],
+ ...mockedLogs.logMocks,
+ })
this[_npm] = new Npm()
this[_npm].output = (...args) => this[_output].push(args)
await this[_npm].load()
@@ -321,11 +319,17 @@ class Sandbox extends EventEmitter {
'--prefix', this.project,
'--userconfig', join(this.home, '.npmrc'),
'--globalconfig', join(this.global, 'npmrc'),
+ '--cache', this.cache,
command,
...argv,
]
- const Npm = this[_test].mock('../../lib/npm.js', this[_mocks])
+ const mockedLogs = mockLogs(this[_mocks])
+ this[_logs] = mockedLogs.logs
+ const Npm = this[_test].mock('../../lib/npm.js', {
+ ...this[_mocks],
+ ...mockedLogs.logMocks,
+ })
this[_npm] = new Npm()
this[_npm].output = (...args) => this[_output].push(args)
await this[_npm].load()
diff --git a/deps/npm/test/index.js b/deps/npm/test/index.js
index 26db16e1f78baf..081c89cee9c70d 100644
--- a/deps/npm/test/index.js
+++ b/deps/npm/test/index.js
@@ -1,16 +1,18 @@
const t = require('tap')
const index = require.resolve('../index.js')
const packageIndex = require.resolve('../')
+
t.equal(index, packageIndex, 'index is main package require() export')
t.throws(() => require(index), {
message: 'The programmatic API was removed in npm v8.0.0',
})
t.test('loading as main module will load the cli', t => {
+ const cwd = t.testdir()
const { spawn } = require('child_process')
const LS = require('../lib/commands/ls.js')
const ls = new LS({})
- const p = spawn(process.execPath, [index, 'ls', '-h'])
+ const p = spawn(process.execPath, [index, 'ls', '-h', '--cache', cwd])
const out = []
p.stdout.on('data', c => out.push(c))
p.on('close', (code, signal) => {
diff --git a/deps/npm/test/lib/auth/legacy.js b/deps/npm/test/lib/auth/legacy.js
index 7b61e9f6e946e5..0c23f8ba6b3356 100644
--- a/deps/npm/test/lib/auth/legacy.js
+++ b/deps/npm/test/lib/auth/legacy.js
@@ -6,7 +6,7 @@ const token = '24528a24f240'
const profile = {}
const read = {}
const legacy = t.mock('../../../lib/auth/legacy.js', {
- npmlog: {
+ 'proc-log': {
info: (...msgs) => {
log += msgs.join(' ')
},
diff --git a/deps/npm/test/lib/auth/sso.js b/deps/npm/test/lib/auth/sso.js
index d5922055931e17..473c8cc2414676 100644
--- a/deps/npm/test/lib/auth/sso.js
+++ b/deps/npm/test/lib/auth/sso.js
@@ -11,7 +11,7 @@ const SSO_URL = 'https://registry.npmjs.org/{SSO_URL}'
const profile = {}
const npmFetch = {}
const sso = t.mock('../../../lib/auth/sso.js', {
- npmlog: {
+ 'proc-log': {
info: (...msgs) => {
log += msgs.join(' ') + '\n'
},
diff --git a/deps/npm/test/lib/cli.js b/deps/npm/test/lib/cli.js
index d762943b470087..f02c57d8cf7303 100644
--- a/deps/npm/test/lib/cli.js
+++ b/deps/npm/test/lib/cli.js
@@ -1,176 +1,153 @@
const t = require('tap')
-const { real: mockNpm } = require('../fixtures/mock-npm.js')
-
-const unsupportedMock = {
- checkForBrokenNode: () => {},
- checkForUnsupportedNode: () => {},
-}
-
-let exitHandlerCalled = null
-let exitHandlerNpm = null
-let exitHandlerCb
-const exitHandlerMock = (...args) => {
- exitHandlerCalled = args
- if (exitHandlerCb) {
- exitHandlerCb()
+const mockGlobals = require('../fixtures/mock-globals.js')
+const { load: loadMockNpm } = require('../fixtures/mock-npm.js')
+
+const cliMock = async (t, mocks) => {
+ let exitHandlerArgs = null
+ let npm = null
+ const exitHandlerMock = (...args) => {
+ exitHandlerArgs = args
+ npm.unload()
}
-}
-exitHandlerMock.setNpm = npm => {
- exitHandlerNpm = npm
-}
-
-const logs = []
-const npmlogMock = {
- pause: () => logs.push('pause'),
- verbose: (...msg) => logs.push(['verbose', ...msg]),
- info: (...msg) => logs.push(['info', ...msg]),
-}
+ exitHandlerMock.setNpm = _npm => npm = _npm
-const cliMock = Npm =>
- t.mock('../../lib/cli.js', {
+ const { Npm, outputs, logMocks, logs } = await loadMockNpm(t, { mocks, init: false })
+ const cli = t.mock('../../lib/cli.js', {
'../../lib/npm.js': Npm,
'../../lib/utils/update-notifier.js': async () => null,
- '../../lib/utils/unsupported.js': unsupportedMock,
+ '../../lib/utils/unsupported.js': {
+ checkForBrokenNode: () => {},
+ checkForUnsupportedNode: () => {},
+ },
'../../lib/utils/exit-handler.js': exitHandlerMock,
- npmlog: npmlogMock,
+ ...logMocks,
})
-const processMock = proc => {
- const mocked = {
- ...process,
- on: () => {},
- ...proc,
+ return {
+ Npm,
+ cli,
+ outputs,
+ exitHandlerCalled: () => exitHandlerArgs,
+ exitHandlerNpm: () => npm,
+ logs,
}
- // nopt looks at process directly
- process.argv = mocked.argv
- return mocked
}
-const { argv } = process
-
t.afterEach(() => {
- logs.length = 0
- process.argv = argv
- exitHandlerCalled = null
- exitHandlerNpm = null
+ delete process.exitCode
})
t.test('print the version, and treat npm_g as npm -g', async t => {
- const proc = processMock({
- argv: ['node', 'npm_g', '-v'],
- version: process.version,
+ mockGlobals(t, {
+ 'process.argv': ['node', 'npm_g', '-v'],
})
- const { Npm, outputs } = mockNpm(t)
- const cli = cliMock(Npm)
- await cli(proc)
+ const { logs, cli, Npm, outputs, exitHandlerCalled } = await cliMock(t)
+ await cli(process)
- t.strictSame(proc.argv, ['node', 'npm', '-g', '-v'], 'npm process.argv was rewritten')
t.strictSame(process.argv, ['node', 'npm', '-g', '-v'], 'system process.argv was rewritten')
- t.strictSame(logs, [
- 'pause',
- ['verbose', 'cli', proc.argv],
- ['info', 'using', 'npm@%s', Npm.version],
- ['info', 'using', 'node@%s', process.version],
+ t.strictSame(logs.verbose.filter(([p]) => p !== 'logfile'), [
+ ['cli', process.argv],
+ ])
+ t.strictSame(logs.info, [
+ ['using', 'npm@%s', Npm.version],
+ ['using', 'node@%s', process.version],
])
t.strictSame(outputs, [[Npm.version]])
- t.strictSame(exitHandlerCalled, [])
+ t.strictSame(exitHandlerCalled(), [])
})
t.test('calling with --versions calls npm version with no args', async t => {
- t.plan(5)
- const proc = processMock({
- argv: ['node', 'npm', 'install', 'or', 'whatever', '--versions'],
+ t.plan(6)
+ mockGlobals(t, {
+ 'process.argv': ['node', 'npm', 'install', 'or', 'whatever', '--versions'],
})
- const { Npm, outputs } = mockNpm(t, {
+ const { logs, cli, Npm, outputs, exitHandlerCalled } = await cliMock(t, {
'../../lib/commands/version.js': class Version {
async exec (args) {
t.strictSame(args, [])
}
},
})
- const cli = cliMock(Npm)
- await cli(proc)
- t.equal(proc.title, 'npm')
- t.strictSame(logs, [
- 'pause',
- ['verbose', 'cli', proc.argv],
- ['info', 'using', 'npm@%s', Npm.version],
- ['info', 'using', 'node@%s', process.version],
+
+ await cli(process)
+ t.equal(process.title, 'npm install or whatever')
+ t.strictSame(logs.verbose.filter(([p]) => p !== 'logfile'), [
+ ['cli', process.argv],
+ ])
+ t.strictSame(logs.info, [
+ ['using', 'npm@%s', Npm.version],
+ ['using', 'node@%s', process.version],
])
t.strictSame(outputs, [])
- t.strictSame(exitHandlerCalled, [])
+ t.strictSame(exitHandlerCalled(), [])
})
t.test('logged argv is sanitized', async t => {
- const proc = processMock({
- argv: [
+ mockGlobals(t, {
+ 'process.argv': [
'node',
'npm',
'version',
'https://username:password@npmjs.org/test_url_with_a_password',
],
})
- const { Npm } = mockNpm(t, {
+ const { logs, cli, Npm } = await cliMock(t, {
'../../lib/commands/version.js': class Version {
async exec (args) {}
},
})
- const cli = cliMock(Npm)
-
- await cli(proc)
- t.equal(proc.title, 'npm')
- t.strictSame(logs, [
- 'pause',
+ await cli(process)
+ t.ok(process.title.startsWith('npm version https://username:***@npmjs.org'))
+ t.strictSame(logs.verbose.filter(([p]) => p !== 'logfile'), [
[
- 'verbose',
'cli',
['node', 'npm', 'version', 'https://username:***@npmjs.org/test_url_with_a_password'],
],
- ['info', 'using', 'npm@%s', Npm.version],
- ['info', 'using', 'node@%s', process.version],
+ ])
+ t.strictSame(logs.info, [
+ ['using', 'npm@%s', Npm.version],
+ ['using', 'node@%s', process.version],
])
})
t.test('print usage if no params provided', async t => {
- const proc = processMock({
- argv: ['node', 'npm'],
+ mockGlobals(t, {
+ 'process.argv': ['node', 'npm'],
})
- const { Npm, outputs } = mockNpm(t)
- const cli = cliMock(Npm)
- await cli(proc)
+ const { cli, outputs, exitHandlerCalled, exitHandlerNpm } = await cliMock(t)
+ await cli(process)
t.match(outputs[0][0], 'Usage:', 'outputs npm usage')
- t.match(exitHandlerCalled, [], 'should call exitHandler with no args')
- t.ok(exitHandlerNpm, 'exitHandler npm is set')
- t.match(proc.exitCode, 1)
+ t.match(exitHandlerCalled(), [], 'should call exitHandler with no args')
+ t.ok(exitHandlerNpm(), 'exitHandler npm is set')
+ t.match(process.exitCode, 1)
})
t.test('print usage if non-command param provided', async t => {
- const proc = processMock({
- argv: ['node', 'npm', 'tset'],
+ mockGlobals(t, {
+ 'process.argv': ['node', 'npm', 'tset'],
})
- const { Npm, outputs } = mockNpm(t)
- const cli = cliMock(Npm)
- await cli(proc)
+ const { cli, outputs, exitHandlerCalled, exitHandlerNpm } = await cliMock(t)
+ await cli(process)
t.match(outputs[0][0], 'Unknown command: "tset"')
t.match(outputs[0][0], 'Did you mean this?')
- t.match(exitHandlerCalled, [], 'should call exitHandler with no args')
- t.ok(exitHandlerNpm, 'exitHandler npm is set')
- t.match(proc.exitCode, 1)
+ t.match(exitHandlerCalled(), [], 'should call exitHandler with no args')
+ t.ok(exitHandlerNpm(), 'exitHandler npm is set')
+ t.match(process.exitCode, 1)
})
t.test('load error calls error handler', async t => {
- const proc = processMock({
- argv: ['node', 'npm', 'asdf'],
+ mockGlobals(t, {
+ 'process.argv': ['node', 'npm', 'asdf'],
})
const err = new Error('test load error')
- const { Npm } = mockNpm(t, {
+ const { cli, exitHandlerCalled } = await cliMock(t, {
'../../lib/utils/config/index.js': {
definitions: null,
flatten: null,
@@ -182,7 +159,6 @@ t.test('load error calls error handler', async t => {
}
},
})
- const cli = cliMock(Npm)
- await cli(proc)
- t.strictSame(exitHandlerCalled, [err])
+ await cli(process)
+ t.strictSame(exitHandlerCalled(), [err])
})
diff --git a/deps/npm/test/lib/commands/access.js b/deps/npm/test/lib/commands/access.js
index fdf132aff97f37..298897e4f5ffc6 100644
--- a/deps/npm/test/lib/commands/access.js
+++ b/deps/npm/test/lib/commands/access.js
@@ -1,18 +1,9 @@
const t = require('tap')
-const { real: mockNpm } = require('../../fixtures/mock-npm.js')
-
-const { Npm } = mockNpm(t)
-const npm = new Npm()
-
-const prefix = t.testdir({})
-
-t.before(async () => {
- await npm.load()
- npm.prefix = prefix
-})
+const { load: loadMockNpm } = require('../../fixtures/mock-npm.js')
t.test('completion', async t => {
+ const { npm } = await loadMockNpm(t)
const access = await npm.cmd('access')
const testComp = (argv, expect) => {
const res = access.completion({ conf: { argv: { remain: argv } } })
@@ -42,6 +33,7 @@ t.test('completion', async t => {
})
t.test('subcommand required', async t => {
+ const { npm } = await loadMockNpm(t)
const access = await npm.cmd('access')
await t.rejects(
npm.exec('access', []),
@@ -50,6 +42,7 @@ t.test('subcommand required', async t => {
})
t.test('unrecognized subcommand', async t => {
+ const { npm } = await loadMockNpm(t)
await t.rejects(
npm.exec('access', ['blerg']),
/Usage: blerg is not a recognized subcommand/,
@@ -58,6 +51,7 @@ t.test('unrecognized subcommand', async t => {
})
t.test('edit', async t => {
+ const { npm } = await loadMockNpm(t)
await t.rejects(
npm.exec('access', ['edit', '@scoped/another']),
/edit subcommand is not implemented yet/,
@@ -66,15 +60,13 @@ t.test('edit', async t => {
})
t.test('access public on unscoped package', async t => {
- t.teardown(() => {
- npm.prefix = prefix
- })
- const testdir = t.testdir({
- 'package.json': JSON.stringify({
- name: 'npm-access-public-pkg',
- }),
+ const { npm } = await loadMockNpm(t, {
+ testdir: {
+ 'package.json': JSON.stringify({
+ name: 'npm-access-public-pkg',
+ }),
+ },
})
- npm.prefix = testdir
await t.rejects(
npm.exec('access', ['public']),
/Usage: This command is only available for scoped packages/,
@@ -84,30 +76,30 @@ t.test('access public on unscoped package', async t => {
t.test('access public on scoped package', async t => {
t.plan(2)
- const { Npm } = mockNpm(t, {
- libnpmaccess: {
- public: (pkg, { registry }) => {
- t.equal(pkg, name, 'should use pkg name ref')
- t.equal(
- registry,
- 'https://registry.npmjs.org/',
- 'should forward correct options'
- )
- return true
+ const name = '@scoped/npm-access-public-pkg'
+ const { npm } = await loadMockNpm(t, {
+ mocks: {
+ libnpmaccess: {
+ public: (pkg, { registry }) => {
+ t.equal(pkg, name, 'should use pkg name ref')
+ t.equal(
+ registry,
+ 'https://registry.npmjs.org/',
+ 'should forward correct options'
+ )
+ return true
+ },
},
},
+ testdir: {
+ 'package.json': JSON.stringify({ name }),
+ },
})
- const npm = new Npm()
- await npm.load()
- const name = '@scoped/npm-access-public-pkg'
- const testdir = t.testdir({
- 'package.json': JSON.stringify({ name }),
- })
- npm.prefix = testdir
await npm.exec('access', ['public'])
})
t.test('access public on missing package.json', async t => {
+ const { npm } = await loadMockNpm(t)
await t.rejects(
npm.exec('access', ['public']),
/no package name passed to command and no package.json found/,
@@ -116,14 +108,12 @@ t.test('access public on missing package.json', async t => {
})
t.test('access public on invalid package.json', async t => {
- t.teardown(() => {
- npm.prefix = prefix
- })
- const testdir = t.testdir({
- 'package.json': '{\n',
- node_modules: {},
+ const { npm } = await loadMockNpm(t, {
+ testdir: {
+ 'package.json': '{\n',
+ node_modules: {},
+ },
})
- npm.prefix = testdir
await t.rejects(
npm.exec('access', ['public']),
{ code: 'EJSONPARSE' },
@@ -132,15 +122,13 @@ t.test('access public on invalid package.json', async t => {
})
t.test('access restricted on unscoped package', async t => {
- t.teardown(() => {
- npm.prefix = prefix
- })
- const testdir = t.testdir({
- 'package.json': JSON.stringify({
- name: 'npm-access-restricted-pkg',
- }),
+ const { npm } = await loadMockNpm(t, {
+ testdir: {
+ 'package.json': JSON.stringify({
+ name: 'npm-access-restricted-pkg',
+ }),
+ },
})
- npm.prefix = testdir
await t.rejects(
npm.exec('access', ['public']),
/Usage: This command is only available for scoped packages/,
@@ -150,30 +138,30 @@ t.test('access restricted on unscoped package', async t => {
t.test('access restricted on scoped package', async t => {
t.plan(2)
- const { Npm } = mockNpm(t, {
- libnpmaccess: {
- restricted: (pkg, { registry }) => {
- t.equal(pkg, name, 'should use pkg name ref')
- t.equal(
- registry,
- 'https://registry.npmjs.org/',
- 'should forward correct options'
- )
- return true
+ const name = '@scoped/npm-access-restricted-pkg'
+ const { npm } = await loadMockNpm(t, {
+ mocks: {
+ libnpmaccess: {
+ restricted: (pkg, { registry }) => {
+ t.equal(pkg, name, 'should use pkg name ref')
+ t.equal(
+ registry,
+ 'https://registry.npmjs.org/',
+ 'should forward correct options'
+ )
+ return true
+ },
},
},
+ testdir: {
+ 'package.json': JSON.stringify({ name }),
+ },
})
- const npm = new Npm()
- await npm.load()
- const name = '@scoped/npm-access-restricted-pkg'
- const testdir = t.testdir({
- 'package.json': JSON.stringify({ name }),
- })
- npm.prefix = testdir
await npm.exec('access', ['restricted'])
})
t.test('access restricted on missing package.json', async t => {
+ const { npm } = await loadMockNpm(t)
await t.rejects(
npm.exec('access', ['restricted']),
/no package name passed to command and no package.json found/,
@@ -182,14 +170,12 @@ t.test('access restricted on missing package.json', async t => {
})
t.test('access restricted on invalid package.json', async t => {
- t.teardown(() => {
- npm.prefix = prefix
- })
- const testdir = t.testdir({
- 'package.json': '{\n',
- node_modules: {},
+ const { npm } = await loadMockNpm(t, {
+ testdir: {
+ 'package.json': '{\n',
+ node_modules: {},
+ },
})
- npm.prefix = testdir
await t.rejects(
npm.exec('access', ['restricted']),
{ code: 'EJSONPARSE' },
@@ -199,17 +185,18 @@ t.test('access restricted on invalid package.json', async t => {
t.test('access grant read-only', async t => {
t.plan(3)
- const { Npm } = mockNpm(t, {
- libnpmaccess: {
- grant: (spec, team, permissions) => {
- t.equal(spec, '@scoped/another', 'should use expected spec')
- t.equal(team, 'myorg:myteam', 'should use expected team')
- t.equal(permissions, 'read-only', 'should forward permissions')
- return true
+ const { npm } = await loadMockNpm(t, {
+ mocks: {
+ libnpmaccess: {
+ grant: (spec, team, permissions) => {
+ t.equal(spec, '@scoped/another', 'should use expected spec')
+ t.equal(team, 'myorg:myteam', 'should use expected team')
+ t.equal(permissions, 'read-only', 'should forward permissions')
+ return true
+ },
},
},
})
- const npm = new Npm()
await npm.exec('access', [
'grant',
'read-only',
@@ -220,17 +207,18 @@ t.test('access grant read-only', async t => {
t.test('access grant read-write', async t => {
t.plan(3)
- const { Npm } = mockNpm(t, {
- libnpmaccess: {
- grant: (spec, team, permissions) => {
- t.equal(spec, '@scoped/another', 'should use expected spec')
- t.equal(team, 'myorg:myteam', 'should use expected team')
- t.equal(permissions, 'read-write', 'should forward permissions')
- return true
+ const { npm } = await loadMockNpm(t, {
+ mocks: {
+ libnpmaccess: {
+ grant: (spec, team, permissions) => {
+ t.equal(spec, '@scoped/another', 'should use expected spec')
+ t.equal(team, 'myorg:myteam', 'should use expected team')
+ t.equal(permissions, 'read-write', 'should forward permissions')
+ return true
+ },
},
},
})
- const npm = new Npm()
await npm.exec('access', [
'grant',
'read-write',
@@ -241,24 +229,23 @@ t.test('access grant read-write', async t => {
t.test('access grant current cwd', async t => {
t.plan(3)
- const testdir = t.testdir({
- 'package.json': JSON.stringify({
- name: 'yargs',
- }),
- })
- const { Npm } = mockNpm(t, {
- libnpmaccess: {
- grant: (spec, team, permissions) => {
- t.equal(spec, 'yargs', 'should use expected spec')
- t.equal(team, 'myorg:myteam', 'should use expected team')
- t.equal(permissions, 'read-write', 'should forward permissions')
- return true
+ const { npm } = await loadMockNpm(t, {
+ mocks: {
+ libnpmaccess: {
+ grant: (spec, team, permissions) => {
+ t.equal(spec, 'yargs', 'should use expected spec')
+ t.equal(team, 'myorg:myteam', 'should use expected team')
+ t.equal(permissions, 'read-write', 'should forward permissions')
+ return true
+ },
},
},
+ testdir: {
+ 'package.json': JSON.stringify({
+ name: 'yargs',
+ }),
+ },
})
- const npm = new Npm()
- await npm.load()
- npm.prefix = testdir
await npm.exec('access', [
'grant',
'read-write',
@@ -267,6 +254,7 @@ t.test('access grant current cwd', async t => {
})
t.test('access grant others', async t => {
+ const { npm } = await loadMockNpm(t)
await t.rejects(
npm.exec('access', [
'grant',
@@ -280,6 +268,7 @@ t.test('access grant others', async t => {
})
t.test('access grant missing team args', async t => {
+ const { npm } = await loadMockNpm(t)
await t.rejects(
npm.exec('access', [
'grant',
@@ -293,6 +282,7 @@ t.test('access grant missing team args', async t => {
})
t.test('access grant malformed team arg', async t => {
+ const { npm } = await loadMockNpm(t)
await t.rejects(
npm.exec('access', [
'grant',
@@ -307,36 +297,37 @@ t.test('access grant malformed team arg', async t => {
t.test('access 2fa-required/2fa-not-required', async t => {
t.plan(2)
- const { Npm } = mockNpm(t, {
- libnpmaccess: {
- tfaRequired: (spec) => {
- t.equal(spec, '@scope/pkg', 'should use expected spec')
- return true
- },
- tfaNotRequired: (spec) => {
- t.equal(spec, 'unscoped-pkg', 'should use expected spec')
- return true
+ const { npm } = await loadMockNpm(t, {
+ mocks: {
+ libnpmaccess: {
+ tfaRequired: (spec) => {
+ t.equal(spec, '@scope/pkg', 'should use expected spec')
+ return true
+ },
+ tfaNotRequired: (spec) => {
+ t.equal(spec, 'unscoped-pkg', 'should use expected spec')
+ return true
+ },
},
},
})
- const npm = new Npm()
-
await npm.exec('access', ['2fa-required', '@scope/pkg'])
await npm.exec('access', ['2fa-not-required', 'unscoped-pkg'])
})
t.test('access revoke', async t => {
t.plan(2)
- const { Npm } = mockNpm(t, {
- libnpmaccess: {
- revoke: (spec, team) => {
- t.equal(spec, '@scoped/another', 'should use expected spec')
- t.equal(team, 'myorg:myteam', 'should use expected team')
- return true
+ const { npm } = await loadMockNpm(t, {
+ mocks: {
+ libnpmaccess: {
+ revoke: (spec, team) => {
+ t.equal(spec, '@scoped/another', 'should use expected spec')
+ t.equal(team, 'myorg:myteam', 'should use expected team')
+ return true
+ },
},
},
})
- const npm = new Npm()
await npm.exec('access', [
'revoke',
'myorg:myteam',
@@ -345,6 +336,7 @@ t.test('access revoke', async t => {
})
t.test('access revoke missing team args', async t => {
+ const { npm } = await loadMockNpm(t)
await t.rejects(
npm.exec('access', [
'revoke',
@@ -357,6 +349,7 @@ t.test('access revoke missing team args', async t => {
})
t.test('access revoke malformed team arg', async t => {
+ const { npm } = await loadMockNpm(t)
await t.rejects(
npm.exec('access', [
'revoke',
@@ -370,30 +363,32 @@ t.test('access revoke malformed team arg', async t => {
t.test('npm access ls-packages with no team', async t => {
t.plan(1)
- const { Npm } = mockNpm(t, {
- libnpmaccess: {
- lsPackages: (entity) => {
- t.equal(entity, 'foo', 'should use expected entity')
- return {}
+ const { npm } = await loadMockNpm(t, {
+ mocks: {
+ libnpmaccess: {
+ lsPackages: (entity) => {
+ t.equal(entity, 'foo', 'should use expected entity')
+ return {}
+ },
},
+ '../../lib/utils/get-identity.js': () => Promise.resolve('foo'),
},
- '../../lib/utils/get-identity.js': () => Promise.resolve('foo'),
})
- const npm = new Npm()
await npm.exec('access', ['ls-packages'])
})
t.test('access ls-packages on team', async t => {
t.plan(1)
- const { Npm } = mockNpm(t, {
- libnpmaccess: {
- lsPackages: (entity) => {
- t.equal(entity, 'myorg:myteam', 'should use expected entity')
- return {}
+ const { npm } = await loadMockNpm(t, {
+ mocks: {
+ libnpmaccess: {
+ lsPackages: (entity) => {
+ t.equal(entity, 'myorg:myteam', 'should use expected entity')
+ return {}
+ },
},
},
})
- const npm = new Npm()
await npm.exec('access', [
'ls-packages',
'myorg:myteam',
@@ -402,36 +397,36 @@ t.test('access ls-packages on team', async t => {
t.test('access ls-collaborators on current', async t => {
t.plan(1)
- const testdir = t.testdir({
- 'package.json': JSON.stringify({
- name: 'yargs',
- }),
- })
- const { Npm } = mockNpm(t, {
- libnpmaccess: {
- lsCollaborators: (spec) => {
- t.equal(spec, 'yargs', 'should use expected spec')
- return {}
+ const { npm } = await loadMockNpm(t, {
+ mocks: {
+ libnpmaccess: {
+ lsCollaborators: (spec) => {
+ t.equal(spec, 'yargs', 'should use expected spec')
+ return {}
+ },
},
},
+ testdir: {
+ 'package.json': JSON.stringify({
+ name: 'yargs',
+ }),
+ },
})
- const npm = new Npm()
- await npm.load()
- npm.prefix = testdir
await npm.exec('access', ['ls-collaborators'])
})
t.test('access ls-collaborators on spec', async t => {
t.plan(1)
- const { Npm } = mockNpm(t, {
- libnpmaccess: {
- lsCollaborators: (spec) => {
- t.equal(spec, 'yargs', 'should use expected spec')
- return {}
+ const { npm } = await loadMockNpm(t, {
+ mocks: {
+ libnpmaccess: {
+ lsCollaborators: (spec) => {
+ t.equal(spec, 'yargs', 'should use expected spec')
+ return {}
+ },
},
},
})
- const npm = new Npm()
await npm.exec('access', [
'ls-collaborators',
'yargs',
diff --git a/deps/npm/test/lib/commands/adduser.js b/deps/npm/test/lib/commands/adduser.js
index 71d79ea9351b10..8a9358f9ab21ac 100644
--- a/deps/npm/test/lib/commands/adduser.js
+++ b/deps/npm/test/lib/commands/adduser.js
@@ -20,6 +20,13 @@ const authDummy = (npm, options) => {
throw new Error('did not pass full flatOptions to auth function')
}
+ if (!options.log) {
+ // A quick to test to make sure a log gets passed to auth
+ // XXX: should be refactored with change to real mock npm
+ // https://github.com/npm/statusboard/issues/411
+ throw new Error('pass log to auth')
+ }
+
return Promise.resolve({
message: 'success',
newCreds: {
@@ -71,6 +78,8 @@ const AddUser = t.mock('../../../lib/commands/adduser.js', {
npmlog: {
clearProgress: () => null,
disableProgress: () => null,
+ },
+ 'proc-log': {
notice: (_, msg) => {
registryOutput = msg
},
diff --git a/deps/npm/test/lib/commands/audit.js b/deps/npm/test/lib/commands/audit.js
index 3c87c76a8fe5fc..05f268d6bcd0e0 100644
--- a/deps/npm/test/lib/commands/audit.js
+++ b/deps/npm/test/lib/commands/audit.js
@@ -1,5 +1,5 @@
const t = require('tap')
-const { real: mockNpm } = require('../../fixtures/mock-npm')
+const { load: _loadMockNpm } = require('../../fixtures/mock-npm')
t.test('should audit using Arborist', async t => {
let ARB_ARGS = null
@@ -8,36 +8,35 @@ t.test('should audit using Arborist', async t => {
let AUDIT_REPORT_CALLED = false
let ARB_OBJ = null
- const { Npm, outputs } = mockNpm(t, {
- 'npm-audit-report': () => {
- AUDIT_REPORT_CALLED = true
- return {
- report: 'there are vulnerabilities',
- exitCode: 0,
- }
- },
- '@npmcli/arborist': function (args) {
- ARB_ARGS = args
- ARB_OBJ = this
- this.audit = () => {
- AUDIT_CALLED = true
- this.auditReport = {}
- }
- },
- '../../lib/utils/reify-finish.js': (npm, arb) => {
- if (arb !== ARB_OBJ) {
- throw new Error('got wrong object passed to reify-output')
- }
+ const loadMockNpm = (t) => _loadMockNpm(t, {
+ mocks: {
+ 'npm-audit-report': () => {
+ AUDIT_REPORT_CALLED = true
+ return {
+ report: 'there are vulnerabilities',
+ exitCode: 0,
+ }
+ },
+ '@npmcli/arborist': function (args) {
+ ARB_ARGS = args
+ ARB_OBJ = this
+ this.audit = () => {
+ AUDIT_CALLED = true
+ this.auditReport = {}
+ }
+ },
+ '../../lib/utils/reify-finish.js': (npm, arb) => {
+ if (arb !== ARB_OBJ) {
+ throw new Error('got wrong object passed to reify-output')
+ }
- REIFY_FINISH_CALLED = true
+ REIFY_FINISH_CALLED = true
+ },
},
})
- const npm = new Npm()
- await npm.load()
- npm.prefix = t.testdir()
-
t.test('audit', async t => {
+ const { npm, outputs } = await loadMockNpm(t)
await npm.exec('audit', [])
t.match(ARB_ARGS, { audit: true, path: npm.prefix })
t.equal(AUDIT_CALLED, true, 'called audit')
@@ -46,6 +45,7 @@ t.test('should audit using Arborist', async t => {
})
t.test('audit fix', async t => {
+ const { npm } = await loadMockNpm(t)
await npm.exec('audit', ['fix'])
t.equal(REIFY_FINISH_CALLED, true, 'called reify output')
})
@@ -53,69 +53,67 @@ t.test('should audit using Arborist', async t => {
t.test('should audit - json', async t => {
t.plan(1)
- const { Npm } = mockNpm(t, {
- 'npm-audit-report': (_, opts) => {
- t.match(opts.reporter, 'json')
- return {
- report: 'there are vulnerabilities',
- exitCode: 0,
- }
+ const { npm } = await _loadMockNpm(t, {
+ mocks: {
+ 'npm-audit-report': (_, opts) => {
+ t.match(opts.reporter, 'json')
+ return {
+ report: 'there are vulnerabilities',
+ exitCode: 0,
+ }
+ },
+ '@npmcli/arborist': function () {
+ this.audit = () => {
+ this.auditReport = {}
+ }
+ },
+ '../../lib/utils/reify-output.js': () => {},
},
- '@npmcli/arborist': function () {
- this.audit = () => {
- this.auditReport = {}
- }
+ config: {
+ json: true,
},
- '../../lib/utils/reify-output.js': () => {},
})
- const npm = new Npm()
- await npm.load()
- npm.prefix = t.testdir()
- npm.config.set('json', true)
await npm.exec('audit', [])
})
t.test('report endpoint error', async t => {
- const { Npm, outputs, filteredLogs } = mockNpm(t, {
- 'npm-audit-report': () => {
- throw new Error('should not call audit report when there are errors')
- },
- '@npmcli/arborist': function () {
- this.audit = () => {
- this.auditReport = {
- error: {
- message: 'hello, this didnt work',
- method: 'POST',
- uri: 'https://example.com/',
- headers: {
- head: ['ers'],
+ const loadMockNpm = (t, options) => _loadMockNpm(t, {
+ mocks: {
+ 'npm-audit-report': () => {
+ throw new Error('should not call audit report when there are errors')
+ },
+ '@npmcli/arborist': function () {
+ this.audit = () => {
+ this.auditReport = {
+ error: {
+ message: 'hello, this didnt work',
+ method: 'POST',
+ uri: 'https://example.com/',
+ headers: {
+ head: ['ers'],
+ },
+ statusCode: 420,
+ body: 'this is a string',
},
- statusCode: 420,
- body: 'this is a string',
- // body: json ? { nope: 'lol' } : Buffer.from('i had a vuln but i eated it lol'),
- },
+ }
}
- }
+ },
+ '../../lib/utils/reify-output.js': () => {},
},
- '../../lib/utils/reify-output.js': () => {},
+ ...options,
})
- const npm = new Npm()
- await npm.load()
- npm.prefix = t.testdir()
- // npm.config.set('json', )
+
t.test('json=false', async t => {
+ const { npm, outputs, logs } = await loadMockNpm(t, { config: { json: false } })
await t.rejects(npm.exec('audit', []), 'audit endpoint returned an error')
- t.match(filteredLogs('warn'), ['hello, this didnt work'])
+ t.match(logs.warn, [['audit', 'hello, this didnt work']])
t.strictSame(outputs, [['this is a string']])
})
t.test('json=true', async t => {
- t.teardown(() => {
- npm.config.set('json', false)
- })
- npm.config.set('json', true)
+ const { npm, outputs, logs } = await loadMockNpm(t, { config: { json: true } })
await t.rejects(npm.exec('audit', []), 'audit endpoint returned an error')
- t.match(filteredLogs('warn'), ['hello, this didnt work'])
+ t.match(logs.warn, [['audit', 'hello, this didnt work']])
t.strictSame(outputs, [[
'{\n' +
' "message": "hello, this didnt work",\n' +
@@ -135,8 +133,7 @@ t.test('report endpoint error', async t => {
})
t.test('completion', async t => {
- const { Npm } = mockNpm(t)
- const npm = new Npm()
+ const { npm } = await _loadMockNpm(t)
const audit = await npm.cmd('audit')
t.test('fix', async t => {
await t.resolveMatch(
diff --git a/deps/npm/test/lib/commands/birthday.js b/deps/npm/test/lib/commands/birthday.js
index 8c95dd57b2e3aa..9156d3df09421a 100644
--- a/deps/npm/test/lib/commands/birthday.js
+++ b/deps/npm/test/lib/commands/birthday.js
@@ -1,14 +1,15 @@
const t = require('tap')
-const { real: mockNpm } = require('../../fixtures/mock-npm')
+const { load: loadMockNpm } = require('../../fixtures/mock-npm')
t.test('birthday', async t => {
t.plan(2)
- const { Npm } = mockNpm(t, {
- libnpmexec: ({ args, yes }) => {
- t.ok(yes)
- t.match(args, ['@npmcli/npm-birthday'])
+ const { npm } = await loadMockNpm(t, {
+ mocks: {
+ libnpmexec: ({ args, yes }) => {
+ t.ok(yes)
+ t.match(args, ['@npmcli/npm-birthday'])
+ },
},
})
- const npm = new Npm()
await npm.exec('birthday', [])
})
diff --git a/deps/npm/test/lib/commands/cache.js b/deps/npm/test/lib/commands/cache.js
index 70a8ba1b2022ff..fc92facff71874 100644
--- a/deps/npm/test/lib/commands/cache.js
+++ b/deps/npm/test/lib/commands/cache.js
@@ -12,11 +12,6 @@ const rimraf = (path, cb) => {
}
let logOutput = []
-const npmlog = {
- silly: (...args) => {
- logOutput.push(['silly', ...args])
- },
-}
let tarballStreamSpec = ''
let tarballStreamOpts = {}
@@ -141,9 +136,16 @@ const cacache = {
const Cache = t.mock('../../../lib/commands/cache.js', {
cacache,
- npmlog,
pacote,
rimraf,
+ 'proc-log': {
+ silly: (...args) => {
+ logOutput.push(['silly', ...args])
+ },
+ warn: (...args) => {
+ logOutput.push(['warn', ...args])
+ },
+ },
})
const npm = mockNpm({
@@ -153,11 +155,6 @@ const npm = mockNpm({
output: (msg) => {
outputOutput.push(msg)
},
- log: {
- warn: (...args) => {
- logOutput.push(['warn', ...args])
- },
- },
})
const cache = new Cache(npm)
diff --git a/deps/npm/test/lib/commands/ci.js b/deps/npm/test/lib/commands/ci.js
index 1091f9125b041b..537d0784f8963c 100644
--- a/deps/npm/test/lib/commands/ci.js
+++ b/deps/npm/test/lib/commands/ci.js
@@ -159,7 +159,7 @@ t.test('should throw if package-lock.json or npm-shrinkwrap missing', async t =>
const CI = t.mock('../../../lib/commands/ci.js', {
'@npmcli/run-script': opts => {},
'../../../lib/utils/reify-finish.js': async () => {},
- npmlog: {
+ 'proc-log': {
verbose: () => {
t.ok(true, 'log fn called')
},
diff --git a/deps/npm/test/lib/commands/completion.js b/deps/npm/test/lib/commands/completion.js
index 51212f06d888e9..dd571baf793a7f 100644
--- a/deps/npm/test/lib/commands/completion.js
+++ b/deps/npm/test/lib/commands/completion.js
@@ -6,189 +6,153 @@ const completionScript = fs
.readFileSync(path.resolve(__dirname, '../../../lib/utils/completion.sh'), { encoding: 'utf8' })
.replace(/^#!.*?\n/, '')
-const { real: mockNpm } = require('../../fixtures/mock-npm')
-
-const { Npm, outputs } = mockNpm(t, {
- '../../lib/utils/is-windows-shell.js': false,
-})
-const npm = new Npm()
+const { load: _loadMockNpm } = require('../../fixtures/mock-npm')
+const mockGlobals = require('../../fixtures/mock-globals')
+
+const loadMockCompletion = async (t, o = {}) => {
+ const { globals, windows, ...options } = o
+ let resetGlobals = {}
+ if (globals) {
+ resetGlobals = mockGlobals(t, globals).reset
+ }
+ const res = await _loadMockNpm(t, {
+ mocks: {
+ '../../lib/utils/is-windows-shell.js': !!windows,
+ ...options.mocks,
+ },
+ ...options,
+ })
+ const completion = await res.npm.cmd('completion')
+ return {
+ resetGlobals,
+ completion,
+ ...res,
+ }
+}
+
+const loadMockCompletionComp = async (t, word, line) =>
+ loadMockCompletion(t, {
+ globals: {
+ 'process.env.COMP_CWORD': word,
+ 'process.env.COMP_LINE': line,
+ 'process.env.COMP_POINT': line.length,
+ },
+ })
t.test('completion', async t => {
- const completion = await npm.cmd('completion')
t.test('completion completion', async t => {
- const home = process.env.HOME
- t.teardown(() => {
- process.env.HOME = home
- })
-
- process.env.HOME = t.testdir({
- '.bashrc': '',
- '.zshrc': '',
+ const { outputs, completion, prefix } = await loadMockCompletion(t, {
+ testdir: {
+ '.bashrc': 'aaa',
+ '.zshrc': 'aaa',
+ },
})
+ mockGlobals(t, { 'process.env.HOME': prefix })
await completion.completion({ w: 2 })
t.matchSnapshot(outputs, 'both shells')
})
t.test('completion completion no known shells', async t => {
- const home = process.env.HOME
- t.teardown(() => {
- process.env.HOME = home
- })
-
- process.env.HOME = t.testdir()
+ const { outputs, completion, prefix } = await loadMockCompletion(t)
+ mockGlobals(t, { 'process.env.HOME': prefix })
await completion.completion({ w: 2 })
t.matchSnapshot(outputs, 'no responses')
})
t.test('completion completion wrong word count', async t => {
+ const { outputs, completion } = await loadMockCompletion(t)
+
await completion.completion({ w: 3 })
t.matchSnapshot(outputs, 'no responses')
})
t.test('dump script when completion is not being attempted', async t => {
- const _write = process.stdout.write
- const _on = process.stdout.on
- t.teardown(() => {
- process.stdout.write = _write
- process.stdout.on = _on
+ let errorHandler, data
+ const { completion, resetGlobals } = await loadMockCompletion(t, {
+ globals: {
+ 'process.stdout.on': (event, handler) => {
+ errorHandler = handler
+ resetGlobals['process.stdout.on']()
+ },
+ 'process.stdout.write': (chunk, callback) => {
+ data = chunk
+ process.nextTick(() => {
+ callback()
+ errorHandler({ errno: 'EPIPE' })
+ })
+ resetGlobals['process.stdout.write']()
+ },
+ },
})
- let errorHandler
- process.stdout.on = (event, handler) => {
- errorHandler = handler
- process.stdout.on = _on
- }
-
- let data
- process.stdout.write = (chunk, callback) => {
- data = chunk
- process.stdout.write = _write
- process.nextTick(() => {
- callback()
- errorHandler({ errno: 'EPIPE' })
- })
- }
-
await completion.exec({})
-
t.equal(data, completionScript, 'wrote the completion script')
})
t.test('dump script exits correctly when EPIPE is emitted on stdout', async t => {
- const _write = process.stdout.write
- const _on = process.stdout.on
- t.teardown(() => {
- process.stdout.write = _write
- process.stdout.on = _on
+ let errorHandler, data
+ const { completion, resetGlobals } = await loadMockCompletion(t, {
+ globals: {
+ 'process.stdout.on': (event, handler) => {
+ if (event === 'error') {
+ errorHandler = handler
+ }
+ resetGlobals['process.stdout.on']()
+ },
+ 'process.stdout.write': (chunk, callback) => {
+ data = chunk
+ process.nextTick(() => {
+ errorHandler({ errno: 'EPIPE' })
+ callback()
+ })
+ resetGlobals['process.stdout.write']()
+ },
+ },
})
- let errorHandler
- process.stdout.on = (event, handler) => {
- errorHandler = handler
- process.stdout.on = _on
- }
-
- let data
- process.stdout.write = (chunk, callback) => {
- data = chunk
- process.stdout.write = _write
- process.nextTick(() => {
- errorHandler({ errno: 'EPIPE' })
- callback()
- })
- }
-
await completion.exec({})
t.equal(data, completionScript, 'wrote the completion script')
})
t.test('single command name', async t => {
- process.env.COMP_CWORD = 1
- process.env.COMP_LINE = 'npm conf'
- process.env.COMP_POINT = process.env.COMP_LINE.length
-
- t.teardown(() => {
- delete process.env.COMP_CWORD
- delete process.env.COMP_LINE
- delete process.env.COMP_POINT
- })
+ const { outputs, completion } = await loadMockCompletionComp(t, 1, 'npm conf')
await completion.exec(['npm', 'conf'])
t.matchSnapshot(outputs, 'single command name')
})
t.test('multiple command names', async t => {
- process.env.COMP_CWORD = 1
- process.env.COMP_LINE = 'npm a'
- process.env.COMP_POINT = process.env.COMP_LINE.length
-
- t.teardown(() => {
- delete process.env.COMP_CWORD
- delete process.env.COMP_LINE
- delete process.env.COMP_POINT
- })
+ const { outputs, completion } = await loadMockCompletionComp(t, 1, 'npm a')
await completion.exec(['npm', 'a'])
t.matchSnapshot(outputs, 'multiple command names')
})
t.test('completion of invalid command name does nothing', async t => {
- process.env.COMP_CWORD = 1
- process.env.COMP_LINE = 'npm compute'
- process.env.COMP_POINT = process.env.COMP_LINE.length
-
- t.teardown(() => {
- delete process.env.COMP_CWORD
- delete process.env.COMP_LINE
- delete process.env.COMP_POINT
- })
+ const { outputs, completion } = await loadMockCompletionComp(t, 1, 'npm compute')
await completion.exec(['npm', 'compute'])
t.matchSnapshot(outputs, 'no results')
})
t.test('subcommand completion', async t => {
- process.env.COMP_CWORD = 2
- process.env.COMP_LINE = 'npm access '
- process.env.COMP_POINT = process.env.COMP_LINE.length
-
- t.teardown(() => {
- delete process.env.COMP_CWORD
- delete process.env.COMP_LINE
- delete process.env.COMP_POINT
- })
+ const { outputs, completion } = await loadMockCompletionComp(t, 2, 'npm access ')
await completion.exec(['npm', 'access', ''])
t.matchSnapshot(outputs, 'subcommands')
})
t.test('filtered subcommands', async t => {
- process.env.COMP_CWORD = 2
- process.env.COMP_LINE = 'npm access p'
- process.env.COMP_POINT = process.env.COMP_LINE.length
-
- t.teardown(() => {
- delete process.env.COMP_CWORD
- delete process.env.COMP_LINE
- delete process.env.COMP_POINT
- })
+ const { outputs, completion } = await loadMockCompletionComp(t, 2, 'npm access p')
await completion.exec(['npm', 'access', 'p'])
t.matchSnapshot(outputs, 'filtered subcommands')
})
t.test('commands with no completion', async t => {
- process.env.COMP_CWORD = 2
- process.env.COMP_LINE = 'npm adduser '
- process.env.COMP_POINT = process.env.COMP_LINE.length
-
- t.teardown(() => {
- delete process.env.COMP_CWORD
- delete process.env.COMP_LINE
- delete process.env.COMP_POINT
- })
+ const { outputs, completion } = await loadMockCompletionComp(t, 2, 'npm adduser ')
// quotes around adduser are to ensure coverage when unescaping commands
await completion.exec(['npm', "'adduser'", ''])
@@ -196,63 +160,28 @@ t.test('completion', async t => {
})
t.test('flags', async t => {
- process.env.COMP_CWORD = 2
- process.env.COMP_LINE = 'npm install --v'
- process.env.COMP_POINT = process.env.COMP_LINE.length
-
- t.teardown(() => {
- delete process.env.COMP_CWORD
- delete process.env.COMP_LINE
- delete process.env.COMP_POINT
- })
+ const { outputs, completion } = await loadMockCompletionComp(t, 2, 'npm install --v')
await completion.exec(['npm', 'install', '--v'])
-
t.matchSnapshot(outputs, 'flags')
})
t.test('--no- flags', async t => {
- process.env.COMP_CWORD = 2
- process.env.COMP_LINE = 'npm install --no-v'
- process.env.COMP_POINT = process.env.COMP_LINE.length
-
- t.teardown(() => {
- delete process.env.COMP_CWORD
- delete process.env.COMP_LINE
- delete process.env.COMP_POINT
- })
+ const { outputs, completion } = await loadMockCompletionComp(t, 2, 'npm install --no-v')
await completion.exec(['npm', 'install', '--no-v'])
-
t.matchSnapshot(outputs, 'flags')
})
t.test('double dashes escape from flag completion', async t => {
- process.env.COMP_CWORD = 2
- process.env.COMP_LINE = 'npm -- install --'
- process.env.COMP_POINT = process.env.COMP_LINE.length
-
- t.teardown(() => {
- delete process.env.COMP_CWORD
- delete process.env.COMP_LINE
- delete process.env.COMP_POINT
- })
+ const { outputs, completion } = await loadMockCompletionComp(t, 2, 'npm -- install --')
await completion.exec(['npm', '--', 'install', '--'])
-
t.matchSnapshot(outputs, 'full command list')
})
t.test('completion cannot complete options that take a value in mid-command', async t => {
- process.env.COMP_CWORD = 2
- process.env.COMP_LINE = 'npm --registry install'
- process.env.COMP_POINT = process.env.COMP_LINE.length
-
- t.teardown(() => {
- delete process.env.COMP_CWORD
- delete process.env.COMP_LINE
- delete process.env.COMP_POINT
- })
+ const { outputs, completion } = await loadMockCompletionComp(t, 2, 'npm --registry install')
await completion.exec(['npm', '--registry', 'install'])
t.matchSnapshot(outputs, 'does not try to complete option arguments in the middle of a command')
@@ -260,11 +189,7 @@ t.test('completion', async t => {
})
t.test('windows without bash', async t => {
- const { Npm, outputs } = mockNpm(t, {
- '../../lib/utils/is-windows-shell.js': true,
- })
- const npm = new Npm()
- const completion = await npm.cmd('completion')
+ const { outputs, completion } = await loadMockCompletion(t, { windows: true })
await t.rejects(
completion.exec({}),
{ code: 'ENOTSUP', message: /completion supported only in MINGW/ },
diff --git a/deps/npm/test/lib/commands/dedupe.js b/deps/npm/test/lib/commands/dedupe.js
index 8fc0be06181e0b..2e2fae238103ff 100644
--- a/deps/npm/test/lib/commands/dedupe.js
+++ b/deps/npm/test/lib/commands/dedupe.js
@@ -1,11 +1,12 @@
const t = require('tap')
-const { real: mockNpm } = require('../../fixtures/mock-npm')
+const { load: loadMockNpm } = require('../../fixtures/mock-npm')
t.test('should throw in global mode', async (t) => {
- const { Npm } = mockNpm(t)
- const npm = new Npm()
- await npm.load()
- npm.config.set('global', true)
+ const { npm } = await loadMockNpm(t, {
+ config: {
+ global: true,
+ },
+ })
t.rejects(
npm.exec('dedupe', []),
{ code: 'EDEDUPEGLOBAL' },
@@ -15,39 +16,41 @@ t.test('should throw in global mode', async (t) => {
t.test('should remove dupes using Arborist', async (t) => {
t.plan(5)
- const { Npm } = mockNpm(t, {
- '@npmcli/arborist': function (args) {
- t.ok(args, 'gets options object')
- t.ok(args.path, 'gets path option')
- t.ok(args.dryRun, 'gets dryRun from user')
- this.dedupe = () => {
- t.ok(true, 'dedupe is called')
- }
+ const { npm } = await loadMockNpm(t, {
+ mocks: {
+ '@npmcli/arborist': function (args) {
+ t.ok(args, 'gets options object')
+ t.ok(args.path, 'gets path option')
+ t.ok(args.dryRun, 'gets dryRun from user')
+ this.dedupe = () => {
+ t.ok(true, 'dedupe is called')
+ }
+ },
+ '../../lib/utils/reify-finish.js': (npm, arb) => {
+ t.ok(arb, 'gets arborist tree')
+ },
},
- '../../lib/utils/reify-finish.js': (npm, arb) => {
- t.ok(arb, 'gets arborist tree')
+ config: {
+ 'dry-run': 'true',
},
})
- const npm = new Npm()
- await npm.load()
- npm.config.set('prefix', 'foo')
- npm.config.set('dry-run', 'true')
await npm.exec('dedupe', [])
})
t.test('should remove dupes using Arborist - no arguments', async (t) => {
t.plan(1)
- const { Npm } = mockNpm(t, {
- '@npmcli/arborist': function (args) {
- t.ok(args.dryRun, 'gets dryRun from config')
- this.dedupe = () => {}
+ const { npm } = await loadMockNpm(t, {
+ mocks: {
+ '@npmcli/arborist': function (args) {
+ t.ok(args.dryRun, 'gets dryRun from config')
+ this.dedupe = () => {}
+ },
+ '../../lib/utils/reify-output.js': () => {},
+ '../../lib/utils/reify-finish.js': () => {},
+ },
+ config: {
+ 'dry-run': true,
},
- '../../lib/utils/reify-output.js': () => {},
- '../../lib/utils/reify-finish.js': () => {},
})
- const npm = new Npm()
- await npm.load()
- npm.config.set('prefix', 'foo')
- npm.config.set('dry-run', true)
await npm.exec('dedupe', [])
})
diff --git a/deps/npm/test/lib/commands/diff.js b/deps/npm/test/lib/commands/diff.js
index 811936fe6d24c7..ed0702e3784a6b 100644
--- a/deps/npm/test/lib/commands/diff.js
+++ b/deps/npm/test/lib/commands/diff.js
@@ -31,7 +31,7 @@ const npm = mockNpm({
})
const mocks = {
- npmlog: { info: noop, verbose: noop },
+ 'proc-log': { info: noop, verbose: noop },
libnpmdiff: (...args) => libnpmdiff(...args),
'npm-registry-fetch': async () => ({}),
'../../../lib/utils/usage.js': () => 'usage instructions',
diff --git a/deps/npm/test/lib/commands/dist-tag.js b/deps/npm/test/lib/commands/dist-tag.js
index 6b45dc1167557a..756a09d7de002f 100644
--- a/deps/npm/test/lib/commands/dist-tag.js
+++ b/deps/npm/test/lib/commands/dist-tag.js
@@ -61,7 +61,7 @@ const logger = (...msgs) => {
}
const DistTag = t.mock('../../../lib/commands/dist-tag.js', {
- npmlog: {
+ 'proc-log': {
error: logger,
info: logger,
verbose: logger,
diff --git a/deps/npm/test/lib/commands/doctor.js b/deps/npm/test/lib/commands/doctor.js
index e3ad5cc72692f6..51b6111a0ae701 100644
--- a/deps/npm/test/lib/commands/doctor.js
+++ b/deps/npm/test/lib/commands/doctor.js
@@ -50,13 +50,13 @@ const logs = {
info: [],
}
-const clearLogs = (obj = logs) => {
+const clearLogs = () => {
output.length = 0
- for (const key in obj) {
- if (Array.isArray(obj[key])) {
- obj[key].length = 0
+ for (const key in logs) {
+ if (Array.isArray(logs[key])) {
+ logs[key].length = 0
} else {
- delete obj[key]
+ delete logs[key]
}
}
}
@@ -65,13 +65,41 @@ const npm = {
flatOptions: {
registry: 'https://registry.npmjs.org/',
},
- log: {
+ version: '7.1.0',
+ output: data => {
+ output.push(data)
+ },
+}
+
+let latestNpm = npm.version
+const pacote = {
+ manifest: async () => {
+ return { version: latestNpm }
+ },
+}
+
+let verifyResponse = { verifiedCount: 1, verifiedContent: 1 }
+const cacache = {
+ verify: async () => {
+ return verifyResponse
+ },
+}
+
+const mocks = {
+ '../../../lib/utils/is-windows.js': false,
+ '../../../lib/utils/ping.js': ping,
+ cacache,
+ pacote,
+ 'make-fetch-happen': fetch,
+ which,
+ 'proc-log': {
info: msg => {
logs.info.push(msg)
},
+ },
+ npmlog: {
newItem: name => {
logs[name] = {}
-
return {
info: (_, msg) => {
if (!logs[name].info) {
@@ -109,33 +137,11 @@ const npm = {
error: 0,
},
},
- version: '7.1.0',
- output: data => {
- output.push(data)
- },
-}
-let latestNpm = npm.version
-const pacote = {
- manifest: async () => {
- return { version: latestNpm }
- },
-}
-
-let verifyResponse = { verifiedCount: 1, verifiedContent: 1 }
-const cacache = {
- verify: async () => {
- return verifyResponse
- },
}
const Doctor = t.mock('../../../lib/commands/doctor.js', {
- '../../../lib/utils/is-windows.js': false,
- '../../../lib/utils/ping.js': ping,
- cacache,
- pacote,
- 'make-fetch-happen': fetch,
- which,
+ ...mocks,
})
const doctor = new Doctor(npm)
@@ -205,7 +211,7 @@ t.test('node versions', t => {
npm.globalDir = dir
npm.localBin = dir
npm.globalBin = dir
- npm.log.level = 'info'
+ mocks.npmlog.level = 'info'
st.teardown(() => {
delete npm.cache
@@ -214,7 +220,7 @@ t.test('node versions', t => {
delete npm.globalDir
delete npm.localBin
delete npm.globalBin
- npm.log.level = 'error'
+ mocks.npmlog.level = 'error'
clearLogs()
})
@@ -293,12 +299,8 @@ t.test('node versions', t => {
vt.test('npm doctor skips some tests in windows', async st => {
const WinDoctor = t.mock('../../../lib/commands/doctor.js', {
+ ...mocks,
'../../../lib/utils/is-windows.js': true,
- '../../../lib/utils/ping.js': ping,
- cacache,
- pacote,
- 'make-fetch-happen': fetch,
- which,
})
const winDoctor = new WinDoctor(npm)
@@ -592,12 +594,7 @@ t.test('node versions', t => {
}
const Doctor = t.mock('../../../lib/commands/doctor.js', {
- '../../../lib/utils/is-windows.js': false,
- '../../../lib/utils/ping.js': ping,
- cacache,
- pacote,
- 'make-fetch-happen': fetch,
- which,
+ ...mocks,
fs,
})
const doctor = new Doctor(npm)
diff --git a/deps/npm/test/lib/commands/exec.js b/deps/npm/test/lib/commands/exec.js
index 4ab26568f1091e..3c75c1d8d8273a 100644
--- a/deps/npm/test/lib/commands/exec.js
+++ b/deps/npm/test/lib/commands/exec.js
@@ -44,17 +44,6 @@ const npm = mockNpm({
localPrefix: 'local-prefix',
localBin: 'local-bin',
globalBin: 'global-bin',
- log: {
- disableProgress: () => {
- PROGRESS_ENABLED = false
- },
- enableProgress: () => {
- PROGRESS_ENABLED = true
- },
- warn: (...args) => {
- LOG_WARN.push(args)
- },
- },
})
const RUN_SCRIPTS = []
@@ -87,6 +76,23 @@ const PATH = require('../../../lib/utils/path.js')
let CI_NAME = 'travis-ci'
+const log = {
+ 'proc-log': {
+ warn: (...args) => {
+ LOG_WARN.push(args)
+ },
+ },
+ npmlog: {
+ disableProgress: () => {
+ PROGRESS_ENABLED = false
+ },
+ enableProgress: () => {
+ PROGRESS_ENABLED = true
+ },
+ clearProgress: () => {},
+ },
+}
+
const mocks = {
libnpmexec: t.mock('libnpmexec', {
'@npmcli/arborist': Arborist,
@@ -95,7 +101,9 @@ const mocks = {
pacote,
read,
'mkdirp-infer-owner': mkdirp,
+ ...log,
}),
+ ...log,
}
const Exec = t.mock('../../../lib/commands/exec.js', mocks)
const exec = new Exec(npm)
diff --git a/deps/npm/test/lib/commands/explore.js b/deps/npm/test/lib/commands/explore.js
index b2e7be2136b767..d1355d76712a6f 100644
--- a/deps/npm/test/lib/commands/explore.js
+++ b/deps/npm/test/lib/commands/explore.js
@@ -51,14 +51,17 @@ const getExplore = (windows) => {
path: require('path')[windows ? 'win32' : 'posix'],
'read-package-json-fast': mockRPJ,
'@npmcli/run-script': mockRunScript,
- })
- const npm = {
- dir: windows ? 'c:\\npm\\dir' : '/npm/dir',
- log: {
+ 'proc-log': {
error: (...msg) => logs.push(msg),
+ warn: () => {},
+ },
+ npmlog: {
disableProgress: () => {},
enableProgress: () => {},
},
+ })
+ const npm = {
+ dir: windows ? 'c:\\npm\\dir' : '/npm/dir',
flatOptions: {
shell: 'shell-command',
},
diff --git a/deps/npm/test/lib/commands/find-dupes.js b/deps/npm/test/lib/commands/find-dupes.js
index c1b9c71df5a79e..06bd097b6ca595 100644
--- a/deps/npm/test/lib/commands/find-dupes.js
+++ b/deps/npm/test/lib/commands/find-dupes.js
@@ -1,27 +1,28 @@
const t = require('tap')
-const { real: mockNpm } = require('../../fixtures/mock-npm')
+const { load: loadMockNpm } = require('../../fixtures/mock-npm')
t.test('should run dedupe in dryRun mode', async (t) => {
t.plan(5)
- const { Npm } = mockNpm(t, {
- '@npmcli/arborist': function (args) {
- t.ok(args, 'gets options object')
- t.ok(args.path, 'gets path option')
- t.ok(args.dryRun, 'is called in dryRun mode')
- this.dedupe = () => {
- t.ok(true, 'dedupe is called')
- }
+ const { npm } = await loadMockNpm(t, {
+ mocks: {
+ '@npmcli/arborist': function (args) {
+ t.ok(args, 'gets options object')
+ t.ok(args.path, 'gets path option')
+ t.ok(args.dryRun, 'is called in dryRun mode')
+ this.dedupe = () => {
+ t.ok(true, 'dedupe is called')
+ }
+ },
+ '../../lib/utils/reify-finish.js': (npm, arb) => {
+ t.ok(arb, 'gets arborist tree')
+ },
},
- '../../lib/utils/reify-finish.js': (npm, arb) => {
- t.ok(arb, 'gets arborist tree')
+ config: {
+ // explicitly set to false so we can be 100% sure it's always true when it
+ // hits arborist
+ 'dry-run': false,
},
})
- const npm = new Npm()
- await npm.load()
- // explicitly set to false so we can be 100% sure it's always true when it
- // hits arborist
- npm.config.set('dry-run', false)
- npm.config.set('prefix', 'foo')
await npm.exec('find-dupes', [])
})
diff --git a/deps/npm/test/lib/commands/get.js b/deps/npm/test/lib/commands/get.js
index ba9e770e3e0a12..597cccc3ff0ba4 100644
--- a/deps/npm/test/lib/commands/get.js
+++ b/deps/npm/test/lib/commands/get.js
@@ -1,12 +1,10 @@
const t = require('tap')
-const { real: mockNpm } = require('../../fixtures/mock-npm')
+const { load: loadMockNpm } = require('../../fixtures/mock-npm')
t.test('should retrieve values from config', async t => {
- const { joinedOutput, Npm } = mockNpm(t)
- const npm = new Npm()
+ const { joinedOutput, npm } = await loadMockNpm(t)
const name = 'editor'
const value = 'vigor'
- await npm.load()
npm.config.set(name, value)
await npm.exec('get', [name])
t.equal(
diff --git a/deps/npm/test/lib/commands/init.js b/deps/npm/test/lib/commands/init.js
index 74b33168ade582..215ebc58118e7b 100644
--- a/deps/npm/test/lib/commands/init.js
+++ b/deps/npm/test/lib/commands/init.js
@@ -3,14 +3,6 @@ const fs = require('fs')
const { resolve } = require('path')
const { fake: mockNpm } = require('../../fixtures/mock-npm')
-const npmLog = {
- disableProgress: () => null,
- enableProgress: () => null,
- info: () => null,
- pause: () => null,
- resume: () => null,
- silly: () => null,
-}
const config = {
cache: 'bad-cache-dir',
'init-module': '~/.npm-init.js',
@@ -23,10 +15,19 @@ const flatOptions = {
const npm = mockNpm({
flatOptions,
config,
- log: npmLog,
})
const mocks = {
'../../../lib/utils/usage.js': () => 'usage instructions',
+ npmlog: {
+ disableProgress: () => null,
+ enableProgress: () => null,
+ },
+ 'proc-log': {
+ info: () => null,
+ pause: () => null,
+ resume: () => null,
+ silly: () => null,
+ },
}
const Init = t.mock('../../../lib/commands/init.js', mocks)
const init = new Init(npm)
@@ -37,7 +38,6 @@ const noop = () => {}
t.afterEach(() => {
config.yes = true
config.package = undefined
- npm.log = npmLog
process.chdir(_cwd)
console.log = _consolelog
})
@@ -251,13 +251,15 @@ t.test('npm init cancel', async t => {
'init-package-json': (dir, initFile, config, cb) => cb(
new Error('canceled')
),
+ 'proc-log': {
+ ...mocks['proc-log'],
+ warn: (title, msg) => {
+ t.equal(title, 'init', 'should have init title')
+ t.equal(msg, 'canceled', 'should log canceled')
+ },
+ },
})
const init = new Init(npm)
- npm.log = { ...npm.log }
- npm.log.warn = (title, msg) => {
- t.equal(title, 'init', 'should have init title')
- t.equal(msg, 'canceled', 'should log canceled')
- }
process.chdir(npm.localPrefix)
await init.exec([])
diff --git a/deps/npm/test/lib/commands/install.js b/deps/npm/test/lib/commands/install.js
index 994684596aacf9..d5db3af673caa5 100644
--- a/deps/npm/test/lib/commands/install.js
+++ b/deps/npm/test/lib/commands/install.js
@@ -1,7 +1,10 @@
const t = require('tap')
const path = require('path')
-const { real: mockNpm } = require('../../fixtures/mock-npm')
+const { load: _loadMockNpm } = require('../../fixtures/mock-npm')
+
+// Make less churn in the test to pass in mocks only signature
+const loadMockNpm = (t, mocks) => _loadMockNpm(t, { mocks })
t.test('with args, dev=true', async t => {
const SCRIPTS = []
@@ -9,7 +12,7 @@ t.test('with args, dev=true', async t => {
let REIFY_CALLED = false
let ARB_OBJ = null
- const { Npm, filteredLogs } = mockNpm(t, {
+ const { npm, logs } = await loadMockNpm(t, {
'@npmcli/run-script': ({ event }) => {
SCRIPTS.push(event)
},
@@ -27,8 +30,6 @@ t.test('with args, dev=true', async t => {
},
})
- const npm = new Npm()
- await npm.load()
// This is here because CI calls tests with `--ignore-scripts`, which config
// picks up from argv
npm.config.set('ignore-scripts', false)
@@ -41,8 +42,8 @@ t.test('with args, dev=true', async t => {
await npm.exec('install', ['fizzbuzz'])
t.match(
- filteredLogs('warn'),
- ['Usage of the `--dev` option is deprecated. Use `--include=dev` instead.']
+ logs.warn,
+ [['install', 'Usage of the `--dev` option is deprecated. Use `--include=dev` instead.']]
)
t.match(
ARB_ARGS,
@@ -59,7 +60,7 @@ t.test('without args', async t => {
let REIFY_CALLED = false
let ARB_OBJ = null
- const { Npm } = mockNpm(t, {
+ const { npm } = await loadMockNpm(t, {
'@npmcli/run-script': ({ event }) => {
SCRIPTS.push(event)
},
@@ -77,8 +78,6 @@ t.test('without args', async t => {
},
})
- const npm = new Npm()
- await npm.load()
npm.prefix = path.resolve(t.testdir({}))
npm.config.set('ignore-scripts', false)
await npm.exec('install', [])
@@ -98,7 +97,7 @@ t.test('without args', async t => {
t.test('should ignore scripts with --ignore-scripts', async t => {
const SCRIPTS = []
let REIFY_CALLED = false
- const { Npm } = mockNpm(t, {
+ const { npm } = await loadMockNpm(t, {
'../../lib/utils/reify-finish.js': async () => {},
'@npmcli/run-script': ({ event }) => {
SCRIPTS.push(event)
@@ -109,8 +108,6 @@ t.test('should ignore scripts with --ignore-scripts', async t => {
}
},
})
- const npm = new Npm()
- await npm.load()
npm.config.set('ignore-scripts', true)
npm.prefix = path.resolve(t.testdir({}))
await npm.exec('install', [])
@@ -122,7 +119,7 @@ t.test('should install globally using Arborist', async t => {
const SCRIPTS = []
let ARB_ARGS = null
let REIFY_CALLED
- const { Npm } = mockNpm(t, {
+ const { npm } = await loadMockNpm(t, {
'@npmcli/run-script': ({ event }) => {
SCRIPTS.push(event)
},
@@ -134,8 +131,6 @@ t.test('should install globally using Arborist', async t => {
}
},
})
- const npm = new Npm()
- await npm.load()
npm.config.set('global', true)
npm.globalPrefix = path.resolve(t.testdir({}))
await npm.exec('install', [])
@@ -148,7 +143,7 @@ t.test('should install globally using Arborist', async t => {
})
t.test('npm i -g npm engines check success', async t => {
- const { Npm } = mockNpm(t, {
+ const { npm } = await loadMockNpm(t, {
'../../lib/utils/reify-finish.js': async () => {},
'@npmcli/arborist': function () {
this.reify = () => {}
@@ -164,8 +159,6 @@ t.test('npm i -g npm engines check success', async t => {
},
},
})
- const npm = new Npm()
- await npm.load()
npm.globalDir = t.testdir({})
npm.config.set('global', true)
await npm.exec('install', ['npm'])
@@ -173,7 +166,7 @@ t.test('npm i -g npm engines check success', async t => {
})
t.test('npm i -g npm engines check failure', async t => {
- const { Npm } = mockNpm(t, {
+ const { npm } = await loadMockNpm(t, {
pacote: {
manifest: () => {
return {
@@ -186,8 +179,6 @@ t.test('npm i -g npm engines check failure', async t => {
},
},
})
- const npm = new Npm()
- await npm.load()
npm.globalDir = t.testdir({})
npm.config.set('global', true)
await t.rejects(
@@ -208,7 +199,7 @@ t.test('npm i -g npm engines check failure', async t => {
})
t.test('npm i -g npm engines check failure forced override', async t => {
- const { Npm } = mockNpm(t, {
+ const { npm } = await loadMockNpm(t, {
'../../lib/utils/reify-finish.js': async () => {},
'@npmcli/arborist': function () {
this.reify = () => {}
@@ -225,8 +216,6 @@ t.test('npm i -g npm engines check failure forced override', async t => {
},
},
})
- const npm = new Npm()
- await npm.load()
npm.globalDir = t.testdir({})
npm.config.set('global', true)
npm.config.set('force', true)
@@ -235,7 +224,7 @@ t.test('npm i -g npm engines check failure forced override', async t => {
})
t.test('npm i -g npm@version engines check failure', async t => {
- const { Npm } = mockNpm(t, {
+ const { npm } = await loadMockNpm(t, {
pacote: {
manifest: () => {
return {
@@ -248,8 +237,6 @@ t.test('npm i -g npm@version engines check failure', async t => {
},
},
})
- const npm = new Npm()
- await npm.load()
npm.globalDir = t.testdir({})
npm.config.set('global', true)
await t.rejects(
@@ -283,8 +270,7 @@ t.test('completion', async t => {
})
t.test('completion to folder - has a match', async t => {
- const { Npm } = mockNpm(t)
- const npm = new Npm()
+ const { npm } = await _loadMockNpm(t, { load: false })
const install = await npm.cmd('install')
process.chdir(testdir)
const res = await install.completion({ partialWord: './ar' })
@@ -292,16 +278,14 @@ t.test('completion', async t => {
})
t.test('completion to folder - invalid dir', async t => {
- const { Npm } = mockNpm(t)
- const npm = new Npm()
+ const { npm } = await _loadMockNpm(t, { load: false })
const install = await npm.cmd('install')
const res = await install.completion({ partialWord: '/does/not/exist' })
t.strictSame(res, [], 'invalid dir: no matching')
})
t.test('completion to folder - no matches', async t => {
- const { Npm } = mockNpm(t)
- const npm = new Npm()
+ const { npm } = await _loadMockNpm(t, { load: false })
const install = await npm.cmd('install')
process.chdir(testdir)
const res = await install.completion({ partialWord: './pa' })
@@ -309,8 +293,7 @@ t.test('completion', async t => {
})
t.test('completion to folder - match is not a package', async t => {
- const { Npm } = mockNpm(t)
- const npm = new Npm()
+ const { npm } = await _loadMockNpm(t, { load: false })
const install = await npm.cmd('install')
process.chdir(testdir)
const res = await install.completion({ partialWord: './othe' })
@@ -318,8 +301,7 @@ t.test('completion', async t => {
})
t.test('completion to url', async t => {
- const { Npm } = mockNpm(t)
- const npm = new Npm()
+ const { npm } = await _loadMockNpm(t, { load: false })
const install = await npm.cmd('install')
process.chdir(testdir)
const res = await install.completion({ partialWord: 'http://path/to/url' })
@@ -327,8 +309,7 @@ t.test('completion', async t => {
})
t.test('no /', async t => {
- const { Npm } = mockNpm(t)
- const npm = new Npm()
+ const { npm } = await _loadMockNpm(t, { load: false })
const install = await npm.cmd('install')
process.chdir(testdir)
const res = await install.completion({ partialWord: 'toto' })
@@ -336,8 +317,7 @@ t.test('completion', async t => {
})
t.test('only /', async t => {
- const { Npm } = mockNpm(t)
- const npm = new Npm()
+ const { npm } = await _loadMockNpm(t, { load: false })
const install = await npm.cmd('install')
process.chdir(testdir)
const res = await install.completion({ partialWord: '/' })
diff --git a/deps/npm/test/lib/commands/logout.js b/deps/npm/test/lib/commands/logout.js
index 39ef86c843e2b8..ee01e7500d1412 100644
--- a/deps/npm/test/lib/commands/logout.js
+++ b/deps/npm/test/lib/commands/logout.js
@@ -10,45 +10,31 @@ const flatOptions = {
scope: '',
}
const npm = mockNpm({ config, flatOptions })
-
-const npmlog = {}
-
let result = null
-const npmFetch = (url, opts) => {
- result = { url, opts }
-}
-const mocks = {
- npmlog,
- 'npm-registry-fetch': npmFetch,
+const mockLogout = (otherMocks) => {
+ const Logout = t.mock('../../../lib/commands/logout.js', {
+ 'npm-registry-fetch': (url, opts) => {
+ result = { url, opts }
+ },
+ ...otherMocks,
+ })
+ return new Logout(npm)
}
-const Logout = t.mock('../../../lib/commands/logout.js', mocks)
-const logout = new Logout(npm)
+t.afterEach(() => {
+ delete flatOptions.token
+ result = null
+ config.clearCredentialsByURI = null
+ config.delete = null
+ config.save = null
+})
t.test('token logout', async t => {
- t.teardown(() => {
- delete flatOptions.token
- result = null
- mocks['npm-registry-fetch'] = null
- config.clearCredentialsByURI = null
- config.delete = null
- config.save = null
- npmlog.verbose = null
- })
t.plan(5)
flatOptions['//registry.npmjs.org/:_authToken'] = '@foo/'
- npmlog.verbose = (title, msg) => {
- t.equal(title, 'logout', 'should have correcct log prefix')
- t.equal(
- msg,
- 'clearing token for https://registry.npmjs.org/',
- 'should log message with correct registry'
- )
- }
-
npm.config.clearCredentialsByURI = registry => {
t.equal(
registry,
@@ -61,6 +47,19 @@ t.test('token logout', async t => {
t.equal(type, 'user', 'should save to user config')
}
+ const logout = mockLogout({
+ 'proc-log': {
+ verbose: (title, msg) => {
+ t.equal(title, 'logout', 'should have correcct log prefix')
+ t.equal(
+ msg,
+ 'clearing token for https://registry.npmjs.org/',
+ 'should log message with correct registry'
+ )
+ },
+ },
+ })
+
await logout.exec([])
t.same(
@@ -87,12 +86,11 @@ t.test('token scoped logout', async t => {
delete config['@myscope:registry']
delete flatOptions.scope
result = null
- mocks['npm-registry-fetch'] = null
config.clearCredentialsByURI = null
config.delete = null
config.save = null
- npmlog.verbose = null
})
+
t.plan(7)
flatOptions['//diff-registry.npmjs.com/:_authToken'] = '@bar/'
@@ -102,15 +100,6 @@ t.test('token scoped logout', async t => {
flatOptions.scope = '@myscope'
flatOptions['@myscope:registry'] = 'https://diff-registry.npmjs.com/'
- npmlog.verbose = (title, msg) => {
- t.equal(title, 'logout', 'should have correcct log prefix')
- t.equal(
- msg,
- 'clearing token for https://diff-registry.npmjs.com/',
- 'should log message with correct registry'
- )
- }
-
npm.config.clearCredentialsByURI = registry => {
t.equal(
registry,
@@ -128,6 +117,19 @@ t.test('token scoped logout', async t => {
t.equal(type, 'user', 'should save to user config')
}
+ const logout = mockLogout({
+ 'proc-log': {
+ verbose: (title, msg) => {
+ t.equal(title, 'logout', 'should have correcct log prefix')
+ t.equal(
+ msg,
+ 'clearing token for https://diff-registry.npmjs.com/',
+ 'should log message with correct registry'
+ )
+ },
+ },
+ })
+
await logout.exec([])
t.same(
@@ -154,29 +156,34 @@ t.test('user/pass logout', async t => {
delete flatOptions['//registry.npmjs.org/:_password']
npm.config.clearCredentialsByURI = null
npm.config.save = null
- npmlog.verbose = null
})
t.plan(2)
flatOptions['//registry.npmjs.org/:username'] = 'foo'
flatOptions['//registry.npmjs.org/:_password'] = 'bar'
- npmlog.verbose = (title, msg) => {
- t.equal(title, 'logout', 'should have correct log prefix')
- t.equal(
- msg,
- 'clearing user credentials for https://registry.npmjs.org/',
- 'should log message with correct registry'
- )
- }
-
npm.config.clearCredentialsByURI = () => null
npm.config.save = () => null
+ const logout = mockLogout({
+ 'proc-log': {
+ verbose: (title, msg) => {
+ t.equal(title, 'logout', 'should have correct log prefix')
+ t.equal(
+ msg,
+ 'clearing user credentials for https://registry.npmjs.org/',
+ 'should log message with correct registry'
+ )
+ },
+ },
+ })
+
await logout.exec([])
})
t.test('missing credentials', async t => {
+ const logout = mockLogout()
+
await t.rejects(
logout.exec([]),
{
@@ -191,11 +198,9 @@ t.test('ignore invalid scoped registry config', async t => {
t.teardown(() => {
delete flatOptions.token
result = null
- mocks['npm-registry-fetch'] = null
config.clearCredentialsByURI = null
config.delete = null
config.save = null
- npmlog.verbose = null
})
t.plan(4)
@@ -203,15 +208,6 @@ t.test('ignore invalid scoped registry config', async t => {
config.scope = '@myscope'
flatOptions['@myscope:registry'] = ''
- npmlog.verbose = (title, msg) => {
- t.equal(title, 'logout', 'should have correcct log prefix')
- t.equal(
- msg,
- 'clearing token for https://registry.npmjs.org/',
- 'should log message with correct registry'
- )
- }
-
npm.config.clearCredentialsByURI = registry => {
t.equal(
registry,
@@ -223,6 +219,19 @@ t.test('ignore invalid scoped registry config', async t => {
npm.config.delete = () => null
npm.config.save = () => null
+ const logout = mockLogout({
+ 'proc-log': {
+ verbose: (title, msg) => {
+ t.equal(title, 'logout', 'should have correcct log prefix')
+ t.equal(
+ msg,
+ 'clearing token for https://registry.npmjs.org/',
+ 'should log message with correct registry'
+ )
+ },
+ },
+ })
+
await logout.exec([])
t.same(
diff --git a/deps/npm/test/lib/commands/owner.js b/deps/npm/test/lib/commands/owner.js
index 8645b349f82fe3..b5d4d1584289d7 100644
--- a/deps/npm/test/lib/commands/owner.js
+++ b/deps/npm/test/lib/commands/owner.js
@@ -14,11 +14,11 @@ const npm = mockNpm({
})
const npmFetch = { json: noop }
-const npmlog = { error: noop, info: noop, verbose: noop }
+const log = { error: noop, info: noop, verbose: noop }
const pacote = { packument: noop }
const mocks = {
- npmlog,
+ 'proc-log': log,
'npm-registry-fetch': npmFetch,
pacote,
'../../../lib/utils/otplease.js': async (opts, fn) => fn({ otp: '123456', opts }),
@@ -97,7 +97,7 @@ t.test('owner ls no args no cwd package', async t => {
result = ''
t.teardown(() => {
result = ''
- npmlog.error = noop
+ log.error = noop
})
await t.rejects(
@@ -114,14 +114,14 @@ t.test('owner ls fails to retrieve packument', async t => {
pacote.packument = () => {
throw new Error('ERR')
}
- npmlog.error = (title, msg, pkgName) => {
+ log.error = (title, msg, pkgName) => {
t.equal(title, 'owner ls', 'should list npm owner ls title')
t.equal(msg, "Couldn't get owner data", 'should use expected msg')
t.equal(pkgName, '@npmcli/map-workspaces', 'should use pkg name')
}
t.teardown(() => {
result = ''
- npmlog.error = noop
+ log.error = noop
pacote.packument = noop
})
@@ -276,7 +276,7 @@ t.test('owner add already an owner', async t => {
t.plan(2)
result = ''
- npmlog.info = (title, msg) => {
+ log.info = (title, msg) => {
t.equal(title, 'owner add', 'should use expected title')
t.equal(
msg,
@@ -304,7 +304,7 @@ t.test('owner add already an owner', async t => {
}
t.teardown(() => {
result = ''
- npmlog.info = noop
+ log.info = noop
npmFetch.json = noop
pacote.packument = noop
})
@@ -385,7 +385,7 @@ t.test('owner add fails to retrieve user info', async t => {
t.plan(3)
result = ''
- npmlog.error = (title, msg) => {
+ log.error = (title, msg) => {
t.equal(title, 'owner mutate', 'should use expected title')
t.equal(msg, 'Error getting user data for foo')
}
@@ -406,7 +406,7 @@ t.test('owner add fails to retrieve user info', async t => {
})
t.teardown(() => {
result = ''
- npmlog.error = noop
+ log.error = noop
npmFetch.json = noop
pacote.packument = noop
})
@@ -552,7 +552,7 @@ t.test('owner rm not a current owner', async t => {
t.plan(2)
result = ''
- npmlog.info = (title, msg) => {
+ log.info = (title, msg) => {
t.equal(title, 'owner rm', 'should log expected title')
t.equal(msg, 'Not a package owner: foo', 'should log.info not a package owner msg')
}
@@ -578,7 +578,7 @@ t.test('owner rm not a current owner', async t => {
}
t.teardown(() => {
result = ''
- npmlog.info = noop
+ log.info = noop
npmFetch.json = noop
pacote.packument = noop
})
diff --git a/deps/npm/test/lib/commands/pack.js b/deps/npm/test/lib/commands/pack.js
index bc887720863226..21057e207953e2 100644
--- a/deps/npm/test/lib/commands/pack.js
+++ b/deps/npm/test/lib/commands/pack.js
@@ -1,5 +1,5 @@
const t = require('tap')
-const { real: mockNpm } = require('../../fixtures/mock-npm')
+const { load: loadMockNpm } = require('../../fixtures/mock-npm')
const path = require('path')
const fs = require('fs')
@@ -9,33 +9,31 @@ t.afterEach(t => {
})
t.test('should pack current directory with no arguments', async t => {
- const { Npm, outputs, filteredLogs } = mockNpm(t)
- const npm = new Npm()
- await npm.load()
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-package',
- version: '1.0.0',
- }),
+ const { npm, outputs, logs } = await loadMockNpm(t, {
+ testdir: {
+ 'package.json': JSON.stringify({
+ name: 'test-package',
+ version: '1.0.0',
+ }),
+ },
})
process.chdir(npm.prefix)
await npm.exec('pack', [])
const filename = 'test-package-1.0.0.tgz'
t.strictSame(outputs, [[filename]])
- t.matchSnapshot(filteredLogs('notice'), 'logs pack contents')
+ t.matchSnapshot(logs.notice.map(([, m]) => m), 'logs pack contents')
t.ok(fs.statSync(path.resolve(npm.prefix, filename)))
})
t.test('follows pack-destination config', async t => {
- const { Npm, outputs } = mockNpm(t)
- const npm = new Npm()
- await npm.load()
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-package',
- version: '1.0.0',
- }),
- 'tar-destination': {},
+ const { npm, outputs } = await loadMockNpm(t, {
+ testdir: {
+ 'package.json': JSON.stringify({
+ name: 'test-package',
+ version: '1.0.0',
+ }),
+ 'tar-destination': {},
+ },
})
process.chdir(npm.prefix)
npm.config.set('pack-destination', path.join(npm.prefix, 'tar-destination'))
@@ -46,14 +44,13 @@ t.test('follows pack-destination config', async t => {
})
t.test('should pack given directory for scoped package', async t => {
- const { Npm, outputs } = mockNpm(t)
- const npm = new Npm()
- await npm.load()
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: '@npm/test-package',
- version: '1.0.0',
- }),
+ const { npm, outputs } = await loadMockNpm(t, {
+ testdir: {
+ 'package.json': JSON.stringify({
+ name: '@npm/test-package',
+ version: '1.0.0',
+ }),
+ },
})
process.chdir(npm.prefix)
await npm.exec('pack', [])
@@ -63,49 +60,46 @@ t.test('should pack given directory for scoped package', async t => {
})
t.test('should log output as valid json', async t => {
- const { Npm, outputs, filteredLogs } = mockNpm(t)
- const npm = new Npm()
- await npm.load()
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-package',
- version: '1.0.0',
- }),
+ const { npm, outputs, logs } = await loadMockNpm(t, {
+ testdir: {
+ 'package.json': JSON.stringify({
+ name: 'test-package',
+ version: '1.0.0',
+ }),
+ },
})
process.chdir(npm.prefix)
npm.config.set('json', true)
await npm.exec('pack', [])
const filename = 'test-package-1.0.0.tgz'
t.matchSnapshot(outputs.map(JSON.parse), 'outputs as json')
- t.matchSnapshot(filteredLogs('notice'), 'logs pack contents')
+ t.matchSnapshot(logs.notice.map(([, m]) => m), 'logs pack contents')
t.ok(fs.statSync(path.resolve(npm.prefix, filename)))
})
t.test('dry run', async t => {
- const { Npm, outputs, filteredLogs } = mockNpm(t)
- const npm = new Npm()
- await npm.load()
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-package',
- version: '1.0.0',
- }),
+ const { npm, outputs, logs } = await loadMockNpm(t, {
+ testdir: {
+ 'package.json': JSON.stringify({
+ name: 'test-package',
+ version: '1.0.0',
+ }),
+ },
})
npm.config.set('dry-run', true)
process.chdir(npm.prefix)
await npm.exec('pack', [])
const filename = 'test-package-1.0.0.tgz'
t.strictSame(outputs, [[filename]])
- t.matchSnapshot(filteredLogs('notice'), 'logs pack contents')
+ t.matchSnapshot(logs.notice.map(([, m]) => m), 'logs pack contents')
t.throws(() => fs.statSync(path.resolve(npm.prefix, filename)))
})
t.test('invalid packument', async t => {
- const { Npm, outputs } = mockNpm(t)
- const npm = new Npm()
- await npm.load()
- npm.prefix = t.testdir({
- 'package.json': '{}',
+ const { npm, outputs } = await loadMockNpm(t, {
+ testdir: {
+ 'package.json': '{}',
+ },
})
process.chdir(npm.prefix)
await t.rejects(
@@ -116,52 +110,58 @@ t.test('invalid packument', async t => {
})
t.test('workspaces', async t => {
- const { Npm, outputs } = mockNpm(t)
- const npm = new Npm()
- await npm.load()
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify(
- {
- name: 'workspaces-test',
- version: '1.0.0',
- workspaces: ['workspace-a', 'workspace-b'],
+ const loadWorkspaces = (t) => loadMockNpm(t, {
+ testdir: {
+ 'package.json': JSON.stringify(
+ {
+ name: 'workspaces-test',
+ version: '1.0.0',
+ workspaces: ['workspace-a', 'workspace-b'],
+ },
+ null,
+ 2
+ ),
+ 'workspace-a': {
+ 'package.json': JSON.stringify({
+ name: 'workspace-a',
+ version: '1.0.0',
+ }),
+ },
+ 'workspace-b': {
+ 'package.json': JSON.stringify({
+ name: 'workspace-b',
+ version: '1.0.0',
+ }),
},
- null,
- 2
- ),
- 'workspace-a': {
- 'package.json': JSON.stringify({
- name: 'workspace-a',
- version: '1.0.0',
- }),
},
- 'workspace-b': {
- 'package.json': JSON.stringify({
- name: 'workspace-b',
- version: '1.0.0',
- }),
+ config: {
+ workspaces: true,
},
})
- npm.config.set('workspaces', true)
+
t.test('all workspaces', async t => {
+ const { npm, outputs } = await loadWorkspaces(t)
process.chdir(npm.prefix)
await npm.exec('pack', [])
t.strictSame(outputs, [['workspace-a-1.0.0.tgz'], ['workspace-b-1.0.0.tgz']])
})
t.test('all workspaces, `.` first arg', async t => {
+ const { npm, outputs } = await loadWorkspaces(t)
process.chdir(npm.prefix)
await npm.exec('pack', ['.'])
t.strictSame(outputs, [['workspace-a-1.0.0.tgz'], ['workspace-b-1.0.0.tgz']])
})
t.test('one workspace', async t => {
+ const { npm, outputs } = await loadWorkspaces(t)
process.chdir(npm.prefix)
await npm.exec('pack', ['workspace-a'])
t.strictSame(outputs, [['workspace-a-1.0.0.tgz']])
})
t.test('specific package', async t => {
+ const { npm, outputs } = await loadWorkspaces(t)
process.chdir(npm.prefix)
await npm.exec('pack', [npm.prefix])
t.strictSame(outputs, [['workspaces-test-1.0.0.tgz']])
diff --git a/deps/npm/test/lib/commands/ping.js b/deps/npm/test/lib/commands/ping.js
index 7011c709b0bacf..f808e0ac3ba2ad 100644
--- a/deps/npm/test/lib/commands/ping.js
+++ b/deps/npm/test/lib/commands/ping.js
@@ -11,7 +11,7 @@ t.test('pings', async t => {
t.equal(spec.registry, registry, 'passes flatOptions')
return {}
},
- npmlog: {
+ 'proc-log': {
notice: (type, spec) => {
++noticeCalls
if (noticeCalls === 1) {
@@ -45,7 +45,7 @@ t.test('pings and logs details', async t => {
t.equal(spec.registry, registry, 'passes flatOptions')
return details
},
- npmlog: {
+ 'proc-log': {
notice: (type, spec) => {
++noticeCalls
if (noticeCalls === 1) {
@@ -83,7 +83,7 @@ t.test('pings and returns json', async t => {
t.equal(spec.registry, registry, 'passes flatOptions')
return details
},
- npmlog: {
+ 'proc-log': {
notice: (type, spec) => {
++noticeCalls
if (noticeCalls === 1) {
diff --git a/deps/npm/test/lib/commands/prefix.js b/deps/npm/test/lib/commands/prefix.js
index 6f059e73a7ec5b..e8295cf6a5b3c3 100644
--- a/deps/npm/test/lib/commands/prefix.js
+++ b/deps/npm/test/lib/commands/prefix.js
@@ -1,9 +1,8 @@
const t = require('tap')
-const { real: mockNpm } = require('../../fixtures/mock-npm')
+const { load: loadMockNpm } = require('../../fixtures/mock-npm')
t.test('prefix', async t => {
- const { joinedOutput, Npm } = mockNpm(t)
- const npm = new Npm()
+ const { joinedOutput, npm } = await loadMockNpm(t, { load: false })
await npm.exec('prefix', [])
t.equal(
joinedOutput(),
diff --git a/deps/npm/test/lib/commands/profile.js b/deps/npm/test/lib/commands/profile.js
index 6554ca89e40f81..3d55a37ddb8cfc 100644
--- a/deps/npm/test/lib/commands/profile.js
+++ b/deps/npm/test/lib/commands/profile.js
@@ -22,6 +22,8 @@ const mocks = {
ansistyles: { bright: a => a },
npmlog: {
gauge: { show () {} },
+ },
+ 'proc-log': {
info () {},
notice () {},
warn () {},
@@ -489,23 +491,23 @@ t.test('profile set ', t => {
},
}
- const npmlog = {
- gauge: {
- show () {},
- },
- warn (title, msg) {
- t.equal(title, 'profile', 'should use expected profile')
- t.equal(
- msg,
- 'Passwords do not match, please try again.',
- 'should log password mismatch message'
- )
- },
- }
-
const Profile = t.mock('../../../lib/commands/profile.js', {
...mocks,
- npmlog,
+ npmlog: {
+ gauge: {
+ show () {},
+ },
+ },
+ 'proc-log': {
+ warn (title, msg) {
+ t.equal(title, 'profile', 'should use expected profile')
+ t.equal(
+ msg,
+ 'Passwords do not match, please try again.',
+ 'should log password mismatch message'
+ )
+ },
+ },
'npm-profile': npmProfile,
'../../../lib/utils/read-user-info.js': readUserInfo,
})
@@ -687,7 +689,7 @@ t.test('enable-2fa', t => {
async otp (label) {
t.equal(
label,
- 'Enter one-time password from your authenticator app: ',
+ 'Enter one-time password: ',
'should ask for otp confirmation'
)
return '123456'
@@ -1042,7 +1044,7 @@ t.test('disable-2fa', t => {
async otp (label) {
t.equal(
label,
- 'Enter one-time password from your authenticator app: ',
+ 'Enter one-time password: ',
'should ask for otp confirmation'
)
return '1234'
diff --git a/deps/npm/test/lib/commands/prune.js b/deps/npm/test/lib/commands/prune.js
index 49d5ab9be35145..a7f56547b105db 100644
--- a/deps/npm/test/lib/commands/prune.js
+++ b/deps/npm/test/lib/commands/prune.js
@@ -1,20 +1,22 @@
const t = require('tap')
-const { real: mockNpm } = require('../../fixtures/mock-npm')
+const { load: loadMockNpm } = require('../../fixtures/mock-npm')
t.test('should prune using Arborist', async (t) => {
t.plan(4)
- const { Npm } = mockNpm(t, {
- '@npmcli/arborist': function (args) {
- t.ok(args, 'gets options object')
- t.ok(args.path, 'gets path option')
- this.prune = () => {
- t.ok(true, 'prune is called')
- }
- },
- '../../lib/utils/reify-finish.js': (arb) => {
- t.ok(arb, 'gets arborist tree')
+ const { npm } = await loadMockNpm(t, {
+ load: false,
+ mocks: {
+ '@npmcli/arborist': function (args) {
+ t.ok(args, 'gets options object')
+ t.ok(args.path, 'gets path option')
+ this.prune = () => {
+ t.ok(true, 'prune is called')
+ }
+ },
+ '../../lib/utils/reify-finish.js': (arb) => {
+ t.ok(arb, 'gets arborist tree')
+ },
},
})
- const npm = new Npm()
await npm.exec('prune', [])
})
diff --git a/deps/npm/test/lib/commands/publish.js b/deps/npm/test/lib/commands/publish.js
index 5f4fb401064c27..1178cd6ee1edf4 100644
--- a/deps/npm/test/lib/commands/publish.js
+++ b/deps/npm/test/lib/commands/publish.js
@@ -1,13 +1,15 @@
const t = require('tap')
const { fake: mockNpm } = require('../../fixtures/mock-npm')
const fs = require('fs')
+const log = require('../../../lib/utils/log-shim')
// The way we set loglevel is kind of convoluted, and there is no way to affect
// it from these tests, which only interact with lib/publish.js, which assumes
// that the code that is requiring and calling lib/publish.js has already
// taken care of the loglevel
-const log = require('npmlog')
-log.level = 'silent'
+const _level = log.level
+t.beforeEach(() => (log.level = 'silent'))
+t.teardown(() => (log.level = _level))
t.cleanSnapshot = data => {
return data.replace(/^ *"gitHead": .*$\n/gm, '')
@@ -19,8 +21,6 @@ const defaults = Object.entries(definitions).reduce((defaults, [key, def]) => {
return defaults
}, {})
-t.afterEach(() => (log.level = 'silent'))
-
t.test(
/* eslint-disable-next-line max-len */
'should publish with libnpmpublish, passing through flatOptions and respecting publishConfig.registry',
@@ -147,7 +147,7 @@ t.test('if loglevel=info and json, should not output package contents', async t
id: 'someid',
}),
logTar: () => {
- t.pass('logTar is called')
+ t.fail('logTar is not called in json mode')
},
},
libnpmpublish: {
@@ -188,7 +188,6 @@ t.test(
),
})
- log.level = 'silent'
const Publish = t.mock('../../../lib/commands/publish.js', {
'../../../lib/utils/tar.js': {
getContents: () => ({
@@ -681,9 +680,12 @@ t.test('private workspaces', async t => {
}
t.test('with color', async t => {
+ t.plan(4)
+
+ log.level = 'info'
const Publish = t.mock('../../../lib/commands/publish.js', {
...mocks,
- npmlog: {
+ 'proc-log': {
notice () {},
verbose () {},
warn (title, msg) {
@@ -707,9 +709,12 @@ t.test('private workspaces', async t => {
})
t.test('colorless', async t => {
+ t.plan(4)
+
+ log.level = 'info'
const Publish = t.mock('../../../lib/commands/publish.js', {
...mocks,
- npmlog: {
+ 'proc-log': {
notice () {},
verbose () {},
warn (title, msg) {
@@ -730,6 +735,8 @@ t.test('private workspaces', async t => {
})
t.test('unexpected error', async t => {
+ t.plan(1)
+
const Publish = t.mock('../../../lib/commands/publish.js', {
...mocks,
libnpmpublish: {
@@ -741,7 +748,7 @@ t.test('private workspaces', async t => {
publishes.push(manifest)
},
},
- npmlog: {
+ 'proc-log': {
notice () {},
verbose () {},
},
@@ -755,6 +762,8 @@ t.test('private workspaces', async t => {
})
t.test('runs correct lifecycle scripts', async t => {
+ t.plan(5)
+
const testDir = t.testdir({
'package.json': JSON.stringify(
{
@@ -773,6 +782,7 @@ t.test('runs correct lifecycle scripts', async t => {
})
const scripts = []
+ log.level = 'info'
const Publish = t.mock('../../../lib/commands/publish.js', {
'@npmcli/run-script': args => {
scripts.push(args)
@@ -810,6 +820,8 @@ t.test('runs correct lifecycle scripts', async t => {
})
t.test('does not run scripts on --ignore-scripts', async t => {
+ t.plan(4)
+
const testDir = t.testdir({
'package.json': JSON.stringify(
{
@@ -821,6 +833,7 @@ t.test('does not run scripts on --ignore-scripts', async t => {
),
})
+ log.level = 'info'
const Publish = t.mock('../../../lib/commands/publish.js', {
'@npmcli/run-script': () => {
t.fail('should not call run-script')
diff --git a/deps/npm/test/lib/commands/repo.js b/deps/npm/test/lib/commands/repo.js
index 4e61047b4e7c72..93eb6d0311e1cf 100644
--- a/deps/npm/test/lib/commands/repo.js
+++ b/deps/npm/test/lib/commands/repo.js
@@ -1,8 +1,8 @@
const t = require('tap')
-const { real: mockNpm } = require('../../fixtures/mock-npm.js')
-const { join, sep } = require('path')
+const { load: _loadMockNpm } = require('../../fixtures/mock-npm.js')
+const { sep } = require('path')
-const pkgDirs = t.testdir({
+const fixture = {
'package.json': JSON.stringify({
name: 'thispkg',
version: '1.2.3',
@@ -149,35 +149,36 @@ const pkgDirs = t.testdir({
},
}),
},
- workspaces: {
+}
+
+const workspaceFixture = {
+ 'package.json': JSON.stringify({
+ name: 'workspaces-test',
+ version: '1.2.3-test',
+ workspaces: ['workspace-a', 'workspace-b', 'workspace-c'],
+ repository: 'https://github.com/npm/workspaces-test',
+ }),
+ 'workspace-a': {
'package.json': JSON.stringify({
- name: 'workspaces-test',
- version: '1.2.3-test',
- workspaces: ['workspace-a', 'workspace-b', 'workspace-c'],
- repository: 'https://github.com/npm/workspaces-test',
+ name: 'workspace-a',
+ version: '1.2.3-a',
+ repository: 'http://repo.workspace-a/',
}),
- 'workspace-a': {
- 'package.json': JSON.stringify({
- name: 'workspace-a',
- version: '1.2.3-a',
- repository: 'http://repo.workspace-a/',
- }),
- },
- 'workspace-b': {
- 'package.json': JSON.stringify({
- name: 'workspace-b',
- version: '1.2.3-n',
- repository: 'https://github.com/npm/workspace-b',
- }),
- },
- 'workspace-c': JSON.stringify({
- 'package.json': {
- name: 'workspace-n',
- version: '1.2.3-n',
- },
+ },
+ 'workspace-b': {
+ 'package.json': JSON.stringify({
+ name: 'workspace-b',
+ version: '1.2.3-n',
+ repository: 'https://github.com/npm/workspace-b',
}),
},
-})
+ 'workspace-c': JSON.stringify({
+ 'package.json': {
+ name: 'workspace-n',
+ version: '1.2.3-n',
+ },
+ }),
+}
// keep a tally of which urls got opened
let opened = {}
@@ -185,20 +186,18 @@ const openUrl = async (npm, url, errMsg) => {
opened[url] = opened[url] || 0
opened[url]++
}
-
-const { Npm } = mockNpm(t, {
- '../../lib/utils/open-url.js': openUrl,
-})
-const npm = new Npm()
-
-t.before(async () => {
- await npm.load()
-})
-
t.afterEach(() => opened = {})
-t.test('open repo urls', t => {
- npm.localPrefix = pkgDirs
+const loadMockNpm = async (t, prefix) => {
+ const res = await _loadMockNpm(t, {
+ mocks: { '../../lib/utils/open-url.js': openUrl },
+ testdir: prefix,
+ })
+ return res
+}
+
+t.test('open repo urls', async t => {
+ const { npm } = await loadMockNpm(t, fixture)
const expect = {
hostedgit: 'https://github.com/foo/hostedgit',
hostedgitat: 'https://github.com/foo/hostedgitat',
@@ -239,8 +238,9 @@ t.test('open repo urls', t => {
})
})
-t.test('fail if cannot figure out repo url', t => {
- npm.localPrefix = pkgDirs
+t.test('fail if cannot figure out repo url', async t => {
+ const { npm } = await loadMockNpm(t, fixture)
+
const cases = [
'norepo',
'repoobbj-nourl',
@@ -261,13 +261,13 @@ t.test('fail if cannot figure out repo url', t => {
})
t.test('open default package if none specified', async t => {
- npm.localPrefix = pkgDirs
+ const { npm } = await loadMockNpm(t, fixture)
await npm.exec('repo', [])
t.equal(opened['https://example.com/thispkg'], 1, 'opened expected url', { opened })
})
-t.test('workspaces', t => {
- npm.localPrefix = join(pkgDirs, 'workspaces')
+t.test('workspaces', async t => {
+ const { npm } = await loadMockNpm(t, workspaceFixture)
t.afterEach(() => {
npm.config.set('workspaces', null)
@@ -311,5 +311,4 @@ t.test('workspaces', t => {
)
t.match({}, opened, 'opened no repo urls')
})
- t.end()
})
diff --git a/deps/npm/test/lib/commands/restart.js b/deps/npm/test/lib/commands/restart.js
index 608de0331deefe..7730f1a3011f69 100644
--- a/deps/npm/test/lib/commands/restart.js
+++ b/deps/npm/test/lib/commands/restart.js
@@ -1,6 +1,6 @@
const t = require('tap')
const spawk = require('spawk')
-const { real: mockNpm } = require('../../fixtures/mock-npm')
+const { load: loadMockNpm } = require('../../fixtures/mock-npm')
spawk.preventUnmatched()
t.teardown(() => {
@@ -12,24 +12,24 @@ t.teardown(() => {
// pretty specific internals of runScript
const makeSpawnArgs = require('@npmcli/run-script/lib/make-spawn-args.js')
-t.test('should run stop script from package.json', async t => {
- const prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'x',
- version: '1.2.3',
- scripts: {
- restart: 'node ./test-restart.js',
- },
- }),
+t.test('should run restart script from package.json', async t => {
+ const { npm } = await loadMockNpm(t, {
+ testdir: {
+ 'package.json': JSON.stringify({
+ name: 'x',
+ version: '1.2.3',
+ scripts: {
+ restart: 'node ./test-restart.js',
+ },
+ }),
+ },
+ config: {
+ loglevel: 'silent',
+ },
})
- const { Npm } = mockNpm(t)
- const npm = new Npm()
- await npm.load()
- npm.log.level = 'silent'
- npm.localPrefix = prefix
- const [scriptShell] = makeSpawnArgs({ path: prefix })
+ const [scriptShell] = makeSpawnArgs({ path: npm.prefix })
const script = spawk.spawn(scriptShell, (args) => {
- t.ok(args.includes('node ./test-restart.js "foo"'), 'ran stop script with extra args')
+ t.ok(args.includes('node ./test-restart.js "foo"'), 'ran restart script with extra args')
return true
})
await npm.exec('restart', ['foo'])
diff --git a/deps/npm/test/lib/commands/root.js b/deps/npm/test/lib/commands/root.js
index 9871ddb25dc675..a886b30c3ee485 100644
--- a/deps/npm/test/lib/commands/root.js
+++ b/deps/npm/test/lib/commands/root.js
@@ -1,9 +1,8 @@
const t = require('tap')
-const { real: mockNpm } = require('../../fixtures/mock-npm')
+const { load: loadMockNpm } = require('../../fixtures/mock-npm')
t.test('prefix', async (t) => {
- const { joinedOutput, Npm } = mockNpm(t)
- const npm = new Npm()
+ const { joinedOutput, npm } = await loadMockNpm(t, { load: false })
await npm.exec('root', [])
t.equal(
joinedOutput(),
diff --git a/deps/npm/test/lib/commands/run-script.js b/deps/npm/test/lib/commands/run-script.js
index e421c655ef64f9..ea0227cda08cae 100644
--- a/deps/npm/test/lib/commands/run-script.js
+++ b/deps/npm/test/lib/commands/run-script.js
@@ -31,13 +31,16 @@ const output = []
const npmlog = {
disableProgress: () => null,
level: 'warn',
+}
+
+const log = {
error: () => null,
}
t.afterEach(() => {
npm.color = false
npmlog.level = 'warn'
- npmlog.error = () => null
+ log.error = () => null
output.length = 0
RUN_SCRIPTS.length = 0
config['if-present'] = false
@@ -56,6 +59,7 @@ const getRS = windows => {
}
),
npmlog,
+ 'proc-log': log,
'../../../lib/utils/is-windows-shell.js': windows,
})
return new RunScript(npm)
@@ -758,7 +762,7 @@ t.test('workspaces', t => {
t.test('missing scripts in all workspaces', async t => {
const LOG = []
- npmlog.error = err => {
+ log.error = err => {
LOG.push(String(err))
}
await t.rejects(
@@ -805,7 +809,7 @@ t.test('workspaces', t => {
t.test('missing scripts in some workspaces', async t => {
const LOG = []
- npmlog.error = err => {
+ log.error = err => {
LOG.push(String(err))
}
await runScript.execWorkspaces(['test'], ['a', 'b', 'c', 'd'])
@@ -857,6 +861,7 @@ t.test('workspaces', t => {
throw new Error('err')
},
npmlog,
+ 'proc-log': log,
'../../../lib/utils/is-windows-shell.js': false,
})
const runScript = new RunScript(npm)
@@ -875,6 +880,7 @@ t.test('workspaces', t => {
RUN_SCRIPTS.push(opts)
},
npmlog,
+ 'proc-log': log,
'../../../lib/utils/is-windows-shell.js': false,
})
const runScript = new RunScript(npm)
diff --git a/deps/npm/test/lib/commands/set-script.js b/deps/npm/test/lib/commands/set-script.js
index 592a2431c2e3e9..2c4fe57d685422 100644
--- a/deps/npm/test/lib/commands/set-script.js
+++ b/deps/npm/test/lib/commands/set-script.js
@@ -10,7 +10,7 @@ const npm = mockNpm(flatOptions)
const ERROR_OUTPUT = []
const WARN_OUTPUT = []
const SetScript = t.mock('../../../lib/commands/set-script.js', {
- npmlog: {
+ 'proc-log': {
error: (...args) => {
ERROR_OUTPUT.push(args)
},
diff --git a/deps/npm/test/lib/commands/set.js b/deps/npm/test/lib/commands/set.js
index a57ea1a5401dd3..feeb901571768b 100644
--- a/deps/npm/test/lib/commands/set.js
+++ b/deps/npm/test/lib/commands/set.js
@@ -2,6 +2,7 @@ const t = require('tap')
// can't run this until npm set can save to project level npmrc
t.skip('npm set', async t => {
+ // XXX: convert to loadMockNpm
const { real: mockNpm } = require('../../fixtures/mock-npm')
const { joinedOutput, Npm } = mockNpm(t)
const npm = new Npm()
diff --git a/deps/npm/test/lib/commands/shrinkwrap.js b/deps/npm/test/lib/commands/shrinkwrap.js
index db4021abd65606..2b9e46c70c98e0 100644
--- a/deps/npm/test/lib/commands/shrinkwrap.js
+++ b/deps/npm/test/lib/commands/shrinkwrap.js
@@ -1,7 +1,7 @@
const t = require('tap')
const fs = require('fs')
const { resolve } = require('path')
-const { real: mockNpm } = require('../../fixtures/mock-npm')
+const { load: loadMockNpm } = require('../../fixtures/mock-npm')
// Attempt to parse json values in snapshots before
// stringifying to remove escaped values like \\"
@@ -13,7 +13,7 @@ t.formatSnapshot = obj =>
(k, v) => {
try {
return JSON.parse(v)
- } catch (_) {}
+ } catch {}
return v
},
2
@@ -23,33 +23,25 @@ t.formatSnapshot = obj =>
// and make some assertions that should always be true. Sets
// the results on t.context for use in child tests
const shrinkwrap = async (t, testdir = {}, config = {}, mocks = {}) => {
- const { Npm, filteredLogs } = mockNpm(t, mocks)
- const npm = new Npm()
- await npm.load()
-
- npm.localPrefix = t.testdir(testdir)
- if (config.lockfileVersion) {
- npm.config.set('lockfile-version', config.lockfileVersion)
- }
- if (config.global) {
- npm.config.set('global', config.global)
- }
+ const { npm, logs } = await loadMockNpm(t, {
+ mocks,
+ config,
+ testdir,
+ })
await npm.exec('shrinkwrap', [])
- const newFile = resolve(npm.localPrefix, 'npm-shrinkwrap.json')
- const oldFile = resolve(npm.localPrefix, 'package-lock.json')
- const notices = filteredLogs('notice')
- const warnings = filteredLogs('warn')
+ const newFile = resolve(npm.prefix, 'npm-shrinkwrap.json')
+ const oldFile = resolve(npm.prefix, 'package-lock.json')
t.notOk(fs.existsSync(oldFile), 'package-lock is always deleted')
- t.same(warnings, [], 'no warnings')
+ t.same(logs.warn, [], 'no warnings')
t.teardown(() => delete t.context)
t.context = {
localPrefix: testdir,
config,
shrinkwrap: JSON.parse(fs.readFileSync(newFile)),
- logs: notices,
+ logs: logs.notice.map(([, m]) => m),
}
}
@@ -58,8 +50,8 @@ const shrinkwrap = async (t, testdir = {}, config = {}, mocks = {}) => {
const shrinkwrapMatrix = async (t, file, assertions) => {
const ancient = JSON.stringify({ lockfileVersion: 1 })
const existing = JSON.stringify({ lockfileVersion: 2 })
- const upgrade = { lockfileVersion: 3 }
- const downgrade = { lockfileVersion: 1 }
+ const upgrade = { 'lockfile-version': 3 }
+ const downgrade = { 'lockfile-version': 1 }
let ancientDir = {}
let existingDir = null
diff --git a/deps/npm/test/lib/commands/star.js b/deps/npm/test/lib/commands/star.js
index 13838bb105afce..9a49036422d5e2 100644
--- a/deps/npm/test/lib/commands/star.js
+++ b/deps/npm/test/lib/commands/star.js
@@ -15,9 +15,9 @@ const npm = mockNpm({
},
})
const npmFetch = { json: noop }
-const npmlog = { error: noop, info: noop, verbose: noop }
+const log = { error: noop, info: noop, verbose: noop }
const mocks = {
- npmlog,
+ 'proc-log': log,
'npm-registry-fetch': npmFetch,
'../../../lib/utils/get-identity.js': async () => 'foo',
'../../../lib/utils/usage.js': () => 'usage instructions',
@@ -29,7 +29,7 @@ const star = new Star(npm)
t.afterEach(() => {
config.unicode = false
config['star.unstar'] = false
- npmlog.info = noop
+ log.info = noop
result = ''
})
@@ -53,7 +53,7 @@ t.test('star a package', async t => {
: {}
),
})
- npmlog.info = (title, msg, id) => {
+ log.info = (title, msg, id) => {
t.equal(title, 'star', 'should use expected title')
t.equal(msg, 'starring', 'should use expected msg')
t.equal(id, pkgName, 'should use expected id')
@@ -78,7 +78,7 @@ t.test('unstar a package', async t => {
: { foo: true }
),
})
- npmlog.info = (title, msg, id) => {
+ log.info = (title, msg, id) => {
t.equal(title, 'unstar', 'should use expected title')
t.equal(msg, 'unstarring', 'should use expected msg')
t.equal(id, pkgName, 'should use expected id')
diff --git a/deps/npm/test/lib/commands/stars.js b/deps/npm/test/lib/commands/stars.js
index 4ed64385892fdf..959739653da7aa 100644
--- a/deps/npm/test/lib/commands/stars.js
+++ b/deps/npm/test/lib/commands/stars.js
@@ -11,9 +11,9 @@ const npm = {
},
}
const npmFetch = { json: noop }
-const npmlog = { warn: noop }
+const log = { warn: noop }
const mocks = {
- npmlog,
+ 'proc-log': log,
'npm-registry-fetch': npmFetch,
'../../../lib/utils/get-identity.js': async () => 'foo',
'../../../lib/utils/usage.js': () => 'usage instructions',
@@ -24,7 +24,7 @@ const stars = new Stars(npm)
t.afterEach(() => {
npm.config = { get () {} }
- npmlog.warn = noop
+ log.warn = noop
result = ''
})
@@ -81,7 +81,7 @@ t.test('unauthorized request', async t => {
)
}
- npmlog.warn = (title, msg) => {
+ log.warn = (title, msg) => {
t.equal(title, 'stars', 'should use expected title')
t.equal(
msg,
@@ -108,7 +108,7 @@ t.test('unexpected error', async t => {
throw new Error('ERROR')
}
- npmlog.warn = (title, msg) => {
+ log.warn = (title, msg) => {
throw new Error('Should not output extra warning msgs')
}
@@ -123,7 +123,7 @@ t.test('no pkg starred', async t => {
t.plan(2)
npmFetch.json = async (uri, opts) => ({ rows: [] })
- npmlog.warn = (title, msg) => {
+ log.warn = (title, msg) => {
t.equal(title, 'stars', 'should use expected title')
t.equal(
msg,
diff --git a/deps/npm/test/lib/commands/start.js b/deps/npm/test/lib/commands/start.js
index 1f26f38ead0de9..4f7dc366dbc196 100644
--- a/deps/npm/test/lib/commands/start.js
+++ b/deps/npm/test/lib/commands/start.js
@@ -1,6 +1,6 @@
const t = require('tap')
const spawk = require('spawk')
-const { real: mockNpm } = require('../../fixtures/mock-npm')
+const { load: loadMockNpm } = require('../../fixtures/mock-npm')
spawk.preventUnmatched()
t.teardown(() => {
@@ -12,22 +12,23 @@ t.teardown(() => {
// pretty specific internals of runScript
const makeSpawnArgs = require('@npmcli/run-script/lib/make-spawn-args.js')
-t.test('should run stop script from package.json', async t => {
- const prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'x',
- version: '1.2.3',
- scripts: {
- start: 'node ./test-start.js',
- },
- }),
+t.test('should run start script from package.json', async t => {
+ t.plan(2)
+ const { npm } = await loadMockNpm(t, {
+ testdir: {
+ 'package.json': JSON.stringify({
+ name: 'x',
+ version: '1.2.3',
+ scripts: {
+ start: 'node ./test-start.js',
+ },
+ }),
+ },
+ config: {
+ loglevel: 'silent',
+ },
})
- const { Npm } = mockNpm(t)
- const npm = new Npm()
- await npm.load()
- npm.log.level = 'silent'
- npm.localPrefix = prefix
- const [scriptShell] = makeSpawnArgs({ path: prefix })
+ const [scriptShell] = makeSpawnArgs({ path: npm.prefix })
const script = spawk.spawn(scriptShell, (args) => {
t.ok(args.includes('node ./test-start.js "foo"'), 'ran start script with extra args')
return true
diff --git a/deps/npm/test/lib/commands/stop.js b/deps/npm/test/lib/commands/stop.js
index 4f189449ba077b..53d057b711306e 100644
--- a/deps/npm/test/lib/commands/stop.js
+++ b/deps/npm/test/lib/commands/stop.js
@@ -1,6 +1,6 @@
const t = require('tap')
const spawk = require('spawk')
-const { real: mockNpm } = require('../../fixtures/mock-npm')
+const { load: loadMockNpm } = require('../../fixtures/mock-npm')
spawk.preventUnmatched()
t.teardown(() => {
@@ -13,21 +13,21 @@ t.teardown(() => {
const makeSpawnArgs = require('@npmcli/run-script/lib/make-spawn-args.js')
t.test('should run stop script from package.json', async t => {
- const prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'x',
- version: '1.2.3',
- scripts: {
- stop: 'node ./test-stop.js',
- },
- }),
+ const { npm } = await loadMockNpm(t, {
+ testdir: {
+ 'package.json': JSON.stringify({
+ name: 'x',
+ version: '1.2.3',
+ scripts: {
+ stop: 'node ./test-stop.js',
+ },
+ }),
+ },
+ config: {
+ loglevel: 'silent',
+ },
})
- const { Npm } = mockNpm(t)
- const npm = new Npm()
- await npm.load()
- npm.log.level = 'silent'
- npm.localPrefix = prefix
- const [scriptShell] = makeSpawnArgs({ path: prefix })
+ const [scriptShell] = makeSpawnArgs({ path: npm.prefix })
const script = spawk.spawn(scriptShell, (args) => {
t.ok(args.includes('node ./test-stop.js "foo"'), 'ran stop script with extra args')
return true
diff --git a/deps/npm/test/lib/commands/test.js b/deps/npm/test/lib/commands/test.js
index 4e5ce289bca9b1..a3dbd3ff4cffb7 100644
--- a/deps/npm/test/lib/commands/test.js
+++ b/deps/npm/test/lib/commands/test.js
@@ -1,6 +1,6 @@
const t = require('tap')
const spawk = require('spawk')
-const { real: mockNpm } = require('../../fixtures/mock-npm')
+const { load: loadMockNpm } = require('../../fixtures/mock-npm')
spawk.preventUnmatched()
t.teardown(() => {
@@ -12,22 +12,22 @@ t.teardown(() => {
// pretty specific internals of runScript
const makeSpawnArgs = require('@npmcli/run-script/lib/make-spawn-args.js')
-t.test('should run stop script from package.json', async t => {
- const prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'x',
- version: '1.2.3',
- scripts: {
- test: 'node ./test-test.js',
- },
- }),
+t.test('should run test script from package.json', async t => {
+ const { npm } = await loadMockNpm(t, {
+ testdir: {
+ 'package.json': JSON.stringify({
+ name: 'x',
+ version: '1.2.3',
+ scripts: {
+ test: 'node ./test-test.js',
+ },
+ }),
+ },
+ config: {
+ loglevel: 'silent',
+ },
})
- const { Npm } = mockNpm(t)
- const npm = new Npm()
- await npm.load()
- npm.log.level = 'silent'
- npm.localPrefix = prefix
- const [scriptShell] = makeSpawnArgs({ path: prefix })
+ const [scriptShell] = makeSpawnArgs({ path: npm.prefix })
const script = spawk.spawn(scriptShell, (args) => {
t.ok(args.includes('node ./test-test.js "foo"'), 'ran test script with extra args')
return true
diff --git a/deps/npm/test/lib/commands/token.js b/deps/npm/test/lib/commands/token.js
index 6d0dc9d7e0874a..65a094a0bca247 100644
--- a/deps/npm/test/lib/commands/token.js
+++ b/deps/npm/test/lib/commands/token.js
@@ -3,25 +3,24 @@ const t = require('tap')
const mocks = {
profile: {},
output: () => {},
- log: {},
readUserInfo: {},
}
const npm = {
output: (...args) => mocks.output(...args),
}
-const Token = t.mock('../../../lib/commands/token.js', {
+const mockToken = (otherMocks) => t.mock('../../../lib/commands/token.js', {
'../../../lib/utils/otplease.js': (opts, fn) => {
return Promise.resolve().then(() => fn(opts))
},
'../../../lib/utils/read-user-info.js': mocks.readUserInfo,
'npm-profile': mocks.profile,
- npmlog: mocks.log,
+ ...otherMocks,
})
-const token = new Token(npm)
+const tokenWithMocks = (options = {}) => {
+ const { log, ...mockRequests } = options
-const tokenWithMocks = mockRequests => {
for (const mod in mockRequests) {
if (mod === 'npm') {
mockRequests.npm = { ...npm, ...mockRequests.npm }
@@ -50,13 +49,24 @@ const tokenWithMocks = mockRequests => {
}
}
- const token = new Token(mockRequests.npm || npm)
+ const MockedToken = mockToken(log ? {
+ 'proc-log': {
+ info: log.info,
+ },
+ npmlog: {
+ gauge: log.gauge,
+ newItem: log.newItem,
+ },
+ } : {})
+ const token = new MockedToken(mockRequests.npm || npm)
return [token, reset]
}
t.test('completion', t => {
t.plan(5)
+ const [token] = tokenWithMocks()
+
const testComp = (argv, expect) => {
t.resolveMatch(token.completion({ conf: { argv: { remain: argv } } }), expect, argv.join(' '))
}
@@ -74,7 +84,7 @@ t.test('completion', t => {
t.test('token foobar', async t => {
t.plan(2)
- const [, reset] = tokenWithMocks({
+ const [token, reset] = tokenWithMocks({
log: {
gauge: {
show: name => {
diff --git a/deps/npm/test/lib/commands/unpublish.js b/deps/npm/test/lib/commands/unpublish.js
index 6ac2067531c802..1424adf5c98515 100644
--- a/deps/npm/test/lib/commands/unpublish.js
+++ b/deps/npm/test/lib/commands/unpublish.js
@@ -17,7 +17,6 @@ const testDir = t.testdir({
const npm = mockNpm({
localPrefix: testDir,
- log: { silly () {}, verbose () {} },
config,
output: (...msg) => {
result += msg.join('\n')
@@ -30,10 +29,10 @@ const mocks = {
'npm-registry-fetch': { json: noop },
'../../../lib/utils/otplease.js': async (opts, fn) => fn(opts),
'../../../lib/utils/get-identity.js': async () => 'foo',
+ 'proc-log': { silly () {}, verbose () {} },
}
t.afterEach(() => {
- npm.log = { silly () {}, verbose () {} }
npm.localPrefix = testDir
result = ''
config['dry-run'] = false
@@ -44,7 +43,7 @@ t.afterEach(() => {
t.test('no args --force', async t => {
config.force = true
- npm.log = {
+ const log = {
silly (title) {
t.equal(title, 'unpublish', 'should silly log args')
},
@@ -74,6 +73,7 @@ t.test('no args --force', async t => {
const Unpublish = t.mock('../../../lib/commands/unpublish.js', {
...mocks,
libnpmpublish,
+ 'proc-log': log,
})
const unpublish = new Unpublish(npm)
@@ -147,7 +147,7 @@ t.test('too many args', async t => {
})
t.test('unpublish @version', async t => {
- npm.log = {
+ const log = {
silly (title, key, value) {
t.equal(title, 'unpublish', 'should silly log args')
if (key === 'spec') {
@@ -172,6 +172,7 @@ t.test('unpublish @version', async t => {
const Unpublish = t.mock('../../../lib/commands/unpublish.js', {
...mocks,
libnpmpublish,
+ 'proc-log': log,
})
const unpublish = new Unpublish(npm)
diff --git a/deps/npm/test/lib/commands/update.js b/deps/npm/test/lib/commands/update.js
index 6ca6dbc87d9687..aecb2c32b5e3f1 100644
--- a/deps/npm/test/lib/commands/update.js
+++ b/deps/npm/test/lib/commands/update.js
@@ -9,12 +9,10 @@ const config = {
const noop = () => null
const npm = mockNpm({
globalDir: '',
- log: noop,
config,
prefix: '',
})
const mocks = {
- npmlog: { warn () {} },
'@npmcli/arborist': class {
reify () {}
},
@@ -29,22 +27,23 @@ t.afterEach(() => {
})
t.test('no args', async t => {
- t.plan(3)
+ t.plan(4)
npm.prefix = '/project/a'
class Arborist {
constructor (args) {
+ const { log, ...rest } = args
t.same(
- args,
+ rest,
{
...npm.flatOptions,
path: npm.prefix,
- log: noop,
workspaces: null,
},
'should call arborist contructor with expected args'
)
+ t.match(log, {}, 'log is passed in')
}
reify ({ update }) {
@@ -65,22 +64,23 @@ t.test('no args', async t => {
})
t.test('with args', async t => {
- t.plan(3)
+ t.plan(4)
npm.prefix = '/project/a'
class Arborist {
constructor (args) {
+ const { log, ...rest } = args
t.same(
- args,
+ rest,
{
...npm.flatOptions,
path: npm.prefix,
- log: noop,
workspaces: null,
},
'should call arborist contructor with expected args'
)
+ t.match(log, {}, 'log is passed in')
}
reify ({ update }) {
@@ -108,7 +108,7 @@ t.test('update --depth=', async t => {
const Update = t.mock('../../../lib/commands/update.js', {
...mocks,
- npmlog: {
+ 'proc-log': {
warn: (title, msg) => {
t.equal(title, 'update', 'should print expected title')
t.match(
@@ -125,7 +125,7 @@ t.test('update --depth=', async t => {
})
t.test('update --global', async t => {
- t.plan(2)
+ t.plan(3)
const normalizePath = p => p.replace(/\\+/g, '/')
const redactCwd = (path) => normalizePath(path)
@@ -137,13 +137,15 @@ t.test('update --global', async t => {
class Arborist {
constructor (args) {
- const { path, ...opts } = args
+ const { path, log, ...rest } = args
t.same(
- opts,
- { ...npm.flatOptions, log: noop, workspaces: undefined },
+ rest,
+ { ...npm.flatOptions, workspaces: undefined },
'should call arborist contructor with expected options'
)
+ t.match(log, {}, 'log is passed in')
+
t.equal(
redactCwd(path),
'{CWD}/global/lib',
diff --git a/deps/npm/test/lib/commands/version.js b/deps/npm/test/lib/commands/version.js
index 6603b581061a64..980353897c29ac 100644
--- a/deps/npm/test/lib/commands/version.js
+++ b/deps/npm/test/lib/commands/version.js
@@ -1,5 +1,6 @@
const t = require('tap')
const { fake: mockNpm } = require('../../fixtures/mock-npm')
+const mockGlobals = require('../../fixtures/mock-globals.js')
let result = []
@@ -26,294 +27,301 @@ const mocks = {
const Version = t.mock('../../../lib/commands/version.js', mocks)
const version = new Version(npm)
-const _processVersions = process.versions
t.afterEach(() => {
config.json = false
npm.prefix = ''
- process.versions = _processVersions
result = []
})
-t.test('no args', async t => {
- const prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-version-no-args',
- version: '3.2.1',
- }),
- })
- npm.prefix = prefix
- Object.defineProperty(process, 'versions', { value: { node: '1.0.0' } })
-
- await version.exec([])
-
- t.same(
- result,
- [
- {
- 'test-version-no-args': '3.2.1',
- node: '1.0.0',
- npm: '1.0.0',
- },
- ],
- 'should output expected values for various versions in npm'
- )
-})
-
-t.test('too many args', async t => {
- await t.rejects(
- version.exec(['foo', 'bar']),
- /npm version/,
- 'should throw usage instructions error'
- )
-})
-
-t.test('completion', async t => {
- const testComp = async (argv, expect) => {
- const res = await version.completion({ conf: { argv: { remain: argv } } })
- t.strictSame(res, expect, argv.join(' '))
- }
-
- await testComp(
- ['npm', 'version'],
- ['major', 'minor', 'patch', 'premajor', 'preminor', 'prepatch', 'prerelease', 'from-git']
- )
- await testComp(['npm', 'version', 'major'], [])
-
- t.end()
-})
-
-t.test('failure reading package.json', async t => {
- const prefix = t.testdir({})
- npm.prefix = prefix
-
- await version.exec([])
-
- t.same(
- result,
- [
- {
- npm: '1.0.0',
- node: '1.0.0',
- },
- ],
- 'should not have package name on returning object'
- )
-})
-
-t.test('--json option', async t => {
- const prefix = t.testdir({})
- config.json = true
- npm.prefix = prefix
- Object.defineProperty(process, 'versions', { value: {} })
-
- await version.exec([])
- t.same(result, ['{\n "npm": "1.0.0"\n}'], 'should return json stringified result')
-})
+t.test('node@1', t => {
+ mockGlobals(t, { 'process.versions': { node: '1.0.0' } }, { replace: true })
-t.test('with one arg', async t => {
- const Version = t.mock('../../../lib/commands/version.js', {
- ...mocks,
- libnpmversion: (arg, opts) => {
- t.equal(arg, 'major', 'should forward expected value')
- t.same(
- opts,
- {
- path: '',
- },
- 'should forward expected options'
- )
- return '4.0.0'
- },
- })
- const version = new Version(npm)
-
- await version.exec(['major'])
- t.same(result, ['v4.0.0'], 'outputs the new version prefixed by the tagVersionPrefix')
-})
+ t.test('no args', async t => {
+ const prefix = t.testdir({
+ 'package.json': JSON.stringify({
+ name: 'test-version-no-args',
+ version: '3.2.1',
+ }),
+ })
+ npm.prefix = prefix
-t.test('workspaces', async t => {
- t.teardown(() => {
- npm.localPrefix = ''
- npm.prefix = ''
- })
+ await version.exec([])
- t.test('no args, all workspaces', async t => {
- const testDir = t.testdir({
- 'package.json': JSON.stringify(
- {
- name: 'workspaces-test',
- version: '1.0.0',
- workspaces: ['workspace-a', 'workspace-b'],
- },
- null,
- 2
- ),
- 'workspace-a': {
- 'package.json': JSON.stringify({
- name: 'workspace-a',
- version: '1.0.0',
- }),
- },
- 'workspace-b': {
- 'package.json': JSON.stringify({
- name: 'workspace-b',
- version: '1.0.0',
- }),
- },
- })
- npm.localPrefix = testDir
- npm.prefix = testDir
- const version = new Version(npm)
- await version.execWorkspaces([], [])
t.same(
result,
[
{
- 'workspaces-test': '1.0.0',
- 'workspace-a': '1.0.0',
- 'workspace-b': '1.0.0',
+ 'test-version-no-args': '3.2.1',
+ node: '1.0.0',
npm: '1.0.0',
},
],
- 'outputs includes main package and workspace versions'
+ 'should output expected values for various versions in npm'
)
})
- t.test('no args, single workspaces', async t => {
- const testDir = t.testdir({
- 'package.json': JSON.stringify(
- {
- name: 'workspaces-test',
- version: '1.0.0',
- workspaces: ['workspace-a', 'workspace-b'],
- },
- null,
- 2
- ),
- 'workspace-a': {
- 'package.json': JSON.stringify({
- name: 'workspace-a',
- version: '1.0.0',
- }),
- },
- 'workspace-b': {
- 'package.json': JSON.stringify({
- name: 'workspace-b',
- version: '1.0.0',
- }),
- },
- })
- npm.localPrefix = testDir
- npm.prefix = testDir
- const version = new Version(npm)
- await version.execWorkspaces([], ['workspace-a'])
- t.same(
- result,
- [
- {
- 'workspaces-test': '1.0.0',
- 'workspace-a': '1.0.0',
- npm: '1.0.0',
- },
- ],
- 'outputs includes main package and requested workspace versions'
+ t.test('too many args', async t => {
+ await t.rejects(
+ version.exec(['foo', 'bar']),
+ /npm version/,
+ 'should throw usage instructions error'
)
})
- t.test('no args, all workspaces, workspace with missing name or version', async t => {
- const testDir = t.testdir({
- 'package.json': JSON.stringify(
- {
- name: 'workspaces-test',
- version: '1.0.0',
- workspaces: ['workspace-a', 'workspace-b', 'workspace-c'],
- },
- null,
- 2
- ),
- 'workspace-a': {
- 'package.json': JSON.stringify({
- name: 'workspace-a',
- version: '1.0.0',
- }),
- },
- 'workspace-b': {
- 'package.json': JSON.stringify({
- name: 'workspace-b',
- }),
- },
- 'workspace-c': {
- 'package.json': JSON.stringify({
- version: '1.0.0',
- }),
- },
- })
- npm.localPrefix = testDir
- npm.prefix = testDir
- const version = new Version(npm)
- await version.execWorkspaces([], [])
+ t.test('completion', async t => {
+ const testComp = async (argv, expect) => {
+ const res = await version.completion({ conf: { argv: { remain: argv } } })
+ t.strictSame(res, expect, argv.join(' '))
+ }
+
+ await testComp(
+ ['npm', 'version'],
+ ['major', 'minor', 'patch', 'premajor', 'preminor', 'prepatch', 'prerelease', 'from-git']
+ )
+ await testComp(['npm', 'version', 'major'], [])
+
+ t.end()
+ })
+
+ t.test('failure reading package.json', async t => {
+ const prefix = t.testdir({})
+ npm.prefix = prefix
+
+ await version.exec([])
+
t.same(
result,
[
{
- 'workspaces-test': '1.0.0',
- 'workspace-a': '1.0.0',
npm: '1.0.0',
+ node: '1.0.0',
},
],
- 'outputs includes main package and valid workspace versions'
+ 'should not have package name on returning object'
)
})
+ t.end()
+})
- t.test('with one arg, all workspaces', async t => {
- const libNpmVersionArgs = []
- const testDir = t.testdir({
- 'package.json': JSON.stringify(
- {
- name: 'workspaces-test',
- version: '1.0.0',
- workspaces: ['workspace-a', 'workspace-b'],
- },
- null,
- 2
- ),
- 'workspace-a': {
- 'package.json': JSON.stringify({
- name: 'workspace-a',
- version: '1.0.0',
- }),
- },
- 'workspace-b': {
- 'package.json': JSON.stringify({
- name: 'workspace-b',
- version: '1.0.0',
- }),
- },
- })
+t.test('empty versions', t => {
+ mockGlobals(t, { 'process.versions': {} }, { replace: true })
+
+ t.test('--json option', async t => {
+ const prefix = t.testdir({})
+ config.json = true
+ npm.prefix = prefix
+
+ await version.exec([])
+ t.same(result, ['{\n "npm": "1.0.0"\n}'], 'should return json stringified result')
+ })
+
+ t.test('with one arg', async t => {
const Version = t.mock('../../../lib/commands/version.js', {
...mocks,
libnpmversion: (arg, opts) => {
- libNpmVersionArgs.push([arg, opts])
- return '2.0.0'
+ t.equal(arg, 'major', 'should forward expected value')
+ t.same(
+ opts,
+ {
+ path: '',
+ },
+ 'should forward expected options'
+ )
+ return '4.0.0'
},
})
- npm.localPrefix = testDir
- npm.prefix = testDir
const version = new Version(npm)
- await version.execWorkspaces(['major'], [])
- t.same(
- result,
- ['workspace-a', 'v2.0.0', 'workspace-b', 'v2.0.0'],
- 'outputs the new version for only the workspaces prefixed by the tagVersionPrefix'
- )
+ await version.exec(['major'])
+ t.same(result, ['v4.0.0'], 'outputs the new version prefixed by the tagVersionPrefix')
})
- t.test('too many args', async t => {
- await t.rejects(
- version.execWorkspaces(['foo', 'bar'], []),
- /npm version/,
- 'should throw usage instructions error'
- )
+ t.test('workspaces', async t => {
+ t.teardown(() => {
+ npm.localPrefix = ''
+ npm.prefix = ''
+ })
+
+ t.test('no args, all workspaces', async t => {
+ const testDir = t.testdir({
+ 'package.json': JSON.stringify(
+ {
+ name: 'workspaces-test',
+ version: '1.0.0',
+ workspaces: ['workspace-a', 'workspace-b'],
+ },
+ null,
+ 2
+ ),
+ 'workspace-a': {
+ 'package.json': JSON.stringify({
+ name: 'workspace-a',
+ version: '1.0.0',
+ }),
+ },
+ 'workspace-b': {
+ 'package.json': JSON.stringify({
+ name: 'workspace-b',
+ version: '1.0.0',
+ }),
+ },
+ })
+ npm.localPrefix = testDir
+ npm.prefix = testDir
+ const version = new Version(npm)
+ await version.execWorkspaces([], [])
+ t.same(
+ result,
+ [
+ {
+ 'workspaces-test': '1.0.0',
+ 'workspace-a': '1.0.0',
+ 'workspace-b': '1.0.0',
+ npm: '1.0.0',
+ },
+ ],
+ 'outputs includes main package and workspace versions'
+ )
+ })
+
+ t.test('no args, single workspaces', async t => {
+ const testDir = t.testdir({
+ 'package.json': JSON.stringify(
+ {
+ name: 'workspaces-test',
+ version: '1.0.0',
+ workspaces: ['workspace-a', 'workspace-b'],
+ },
+ null,
+ 2
+ ),
+ 'workspace-a': {
+ 'package.json': JSON.stringify({
+ name: 'workspace-a',
+ version: '1.0.0',
+ }),
+ },
+ 'workspace-b': {
+ 'package.json': JSON.stringify({
+ name: 'workspace-b',
+ version: '1.0.0',
+ }),
+ },
+ })
+ npm.localPrefix = testDir
+ npm.prefix = testDir
+ const version = new Version(npm)
+ await version.execWorkspaces([], ['workspace-a'])
+ t.same(
+ result,
+ [
+ {
+ 'workspaces-test': '1.0.0',
+ 'workspace-a': '1.0.0',
+ npm: '1.0.0',
+ },
+ ],
+ 'outputs includes main package and requested workspace versions'
+ )
+ })
+
+ t.test('no args, all workspaces, workspace with missing name or version', async t => {
+ const testDir = t.testdir({
+ 'package.json': JSON.stringify(
+ {
+ name: 'workspaces-test',
+ version: '1.0.0',
+ workspaces: ['workspace-a', 'workspace-b', 'workspace-c'],
+ },
+ null,
+ 2
+ ),
+ 'workspace-a': {
+ 'package.json': JSON.stringify({
+ name: 'workspace-a',
+ version: '1.0.0',
+ }),
+ },
+ 'workspace-b': {
+ 'package.json': JSON.stringify({
+ name: 'workspace-b',
+ }),
+ },
+ 'workspace-c': {
+ 'package.json': JSON.stringify({
+ version: '1.0.0',
+ }),
+ },
+ })
+ npm.localPrefix = testDir
+ npm.prefix = testDir
+ const version = new Version(npm)
+ await version.execWorkspaces([], [])
+ t.same(
+ result,
+ [
+ {
+ 'workspaces-test': '1.0.0',
+ 'workspace-a': '1.0.0',
+ npm: '1.0.0',
+ },
+ ],
+ 'outputs includes main package and valid workspace versions'
+ )
+ })
+
+ t.test('with one arg, all workspaces', async t => {
+ const libNpmVersionArgs = []
+ const testDir = t.testdir({
+ 'package.json': JSON.stringify(
+ {
+ name: 'workspaces-test',
+ version: '1.0.0',
+ workspaces: ['workspace-a', 'workspace-b'],
+ },
+ null,
+ 2
+ ),
+ 'workspace-a': {
+ 'package.json': JSON.stringify({
+ name: 'workspace-a',
+ version: '1.0.0',
+ }),
+ },
+ 'workspace-b': {
+ 'package.json': JSON.stringify({
+ name: 'workspace-b',
+ version: '1.0.0',
+ }),
+ },
+ })
+ const Version = t.mock('../../../lib/commands/version.js', {
+ ...mocks,
+ libnpmversion: (arg, opts) => {
+ libNpmVersionArgs.push([arg, opts])
+ return '2.0.0'
+ },
+ })
+ npm.localPrefix = testDir
+ npm.prefix = testDir
+ const version = new Version(npm)
+
+ await version.execWorkspaces(['major'], [])
+ t.same(
+ result,
+ ['workspace-a', 'v2.0.0', 'workspace-b', 'v2.0.0'],
+ 'outputs the new version for only the workspaces prefixed by the tagVersionPrefix'
+ )
+ })
+
+ t.test('too many args', async t => {
+ await t.rejects(
+ version.execWorkspaces(['foo', 'bar'], []),
+ /npm version/,
+ 'should throw usage instructions error'
+ )
+ })
})
+
+ t.end()
})
diff --git a/deps/npm/test/lib/commands/view.js b/deps/npm/test/lib/commands/view.js
index 728787ec4aacc2..035490a79fbf7d 100644
--- a/deps/npm/test/lib/commands/view.js
+++ b/deps/npm/test/lib/commands/view.js
@@ -1,6 +1,7 @@
const t = require('tap')
-t.cleanSnapshot = str => str.replace(/published .*? ago/g, 'published {TIME} ago')
+t.cleanSnapshot = str => str
+ .replace(/(published ).*?( ago)/g, '$1{TIME}$2')
// run the same as tap does when running directly with node
process.stdout.columns = undefined
@@ -17,8 +18,8 @@ const cleanLogs = () => {
console.log = fn
}
-// 25 hours ago
-const yesterday = new Date(Date.now() - 1000 * 60 * 60 * 25)
+// 3 days. its never yesterday and never a week ago
+const yesterday = new Date(Date.now() - 1000 * 60 * 60 * 24 * 3)
const packument = (nv, opts) => {
if (!opts.fullMetadata) {
@@ -564,6 +565,12 @@ t.test('workspaces', async t => {
pacote: {
packument,
},
+ 'proc-log': {
+ warn: (msg) => {
+ warnMsg = msg
+ },
+ silly: () => {},
+ },
})
const config = {
unicode: false,
@@ -571,11 +578,6 @@ t.test('workspaces', async t => {
}
let warnMsg
const npm = mockNpm({
- log: {
- warn: (msg) => {
- warnMsg = msg
- },
- },
config,
localPrefix: testDir,
})
diff --git a/deps/npm/test/lib/commands/whoami.js b/deps/npm/test/lib/commands/whoami.js
index dc6144ec1dd284..66c3f0c6b30bf1 100644
--- a/deps/npm/test/lib/commands/whoami.js
+++ b/deps/npm/test/lib/commands/whoami.js
@@ -1,26 +1,24 @@
const t = require('tap')
-const { real: mockNpm } = require('../../fixtures/mock-npm')
+const { load: _loadMockNpm } = require('../../fixtures/mock-npm')
const username = 'foo'
-const { joinedOutput, Npm } = mockNpm(t, {
- '../../lib/utils/get-identity.js': () => Promise.resolve(username),
-})
-const npm = new Npm()
-
-t.before(async () => {
- await npm.load()
+const loadMockNpm = (t, options) => _loadMockNpm(t, {
+ mocks: {
+ '../../lib/utils/get-identity.js': () => Promise.resolve(username),
+ },
+ ...options,
})
t.test('npm whoami', async (t) => {
+ const { npm, joinedOutput } = await loadMockNpm(t)
await npm.exec('whoami', [])
t.equal(joinedOutput(), username, 'should print username')
})
t.test('npm whoami --json', async (t) => {
- t.teardown(() => {
- npm.config.set('json', false)
+ const { npm, joinedOutput } = await loadMockNpm(t, {
+ config: { json: true },
})
- npm.config.set('json', true)
await npm.exec('whoami', [])
t.equal(JSON.parse(joinedOutput()), username, 'should print username')
})
diff --git a/deps/npm/test/lib/fixtures/mock-globals.js b/deps/npm/test/lib/fixtures/mock-globals.js
new file mode 100644
index 00000000000000..02566e575af5ec
--- /dev/null
+++ b/deps/npm/test/lib/fixtures/mock-globals.js
@@ -0,0 +1,321 @@
+const t = require('tap')
+const mockGlobals = require('../../fixtures/mock-globals')
+
+const originals = {
+ platform: process.platform,
+ error: console.error,
+ stderrOn: process.stderr.on,
+ stderrWrite: process.stderr.write,
+ shell: process.env.SHELL,
+ home: process.env.HOME,
+ argv: process.argv,
+ env: process.env,
+ setInterval,
+}
+
+t.test('console', async t => {
+ await t.test('mocks', async (t) => {
+ const errors = []
+ mockGlobals(t, {
+ 'console.error': (...args) => errors.push(...args),
+ })
+
+ console.error(1)
+ console.error(2)
+ console.error(3)
+ t.strictSame(errors, [1, 2, 3], 'i got my errors')
+ })
+
+ t.equal(console.error, originals.error)
+})
+
+t.test('platform', async (t) => {
+ t.equal(process.platform, originals.platform)
+
+ await t.test('posix', async (t) => {
+ mockGlobals(t, { 'process.platform': 'posix' })
+ t.equal(process.platform, 'posix')
+
+ await t.test('win32 --> woo', async (t) => {
+ mockGlobals(t, { 'process.platform': 'win32' })
+ t.equal(process.platform, 'win32')
+
+ mockGlobals(t, { 'process.platform': 'woo' })
+ t.equal(process.platform, 'woo')
+ })
+
+ t.equal(process.platform, 'posix')
+ })
+
+ t.equal(process.platform, originals.platform)
+})
+
+t.test('manual reset', async t => {
+ let errorHandler, data
+
+ const { reset } = mockGlobals(t, {
+ 'process.stderr.on': (__, handler) => {
+ errorHandler = handler
+ reset['process.stderr.on']()
+ },
+ 'process.stderr.write': (chunk, callback) => {
+ data = chunk
+ process.nextTick(() => {
+ errorHandler({ errno: 'EPIPE' })
+ callback()
+ })
+ reset['process.stderr.write']()
+ },
+ })
+
+ await new Promise((res, rej) => {
+ process.stderr.on('error', er => er.errno === 'EPIPE' ? res() : rej(er))
+ process.stderr.write('hey', res)
+ })
+
+ t.equal(process.stderr.on, originals.stderrOn)
+ t.equal(process.stderr.write, originals.stderrWrite)
+ t.equal(data, 'hey', 'handles EPIPE errors')
+ t.ok(errorHandler)
+})
+
+t.test('reset called multiple times', async (t) => {
+ await t.test('single reset', async t => {
+ const { reset } = mockGlobals(t, { 'process.platform': 'z' })
+ t.equal(process.platform, 'z')
+
+ reset['process.platform']()
+ t.equal(process.platform, originals.platform)
+
+ reset['process.platform']()
+ reset['process.platform']()
+ reset['process.platform']()
+ t.equal(process.platform, originals.platform)
+ })
+
+ t.equal(process.platform, originals.platform)
+})
+
+t.test('object mode', async t => {
+ await t.test('mocks', async t => {
+ const home = t.testdir()
+
+ mockGlobals(t, {
+ process: {
+ stderr: {
+ on: '1',
+ },
+ env: {
+ HOME: home,
+ },
+ },
+ })
+
+ t.equal(process.stderr.on, '1')
+ t.equal(process.env.HOME, home)
+ })
+
+ t.equal(process.env.HOME, originals.home)
+ t.equal(process.stderr.write, originals.stderrWrite)
+})
+
+t.test('mixed object/string mode', async t => {
+ await t.test('mocks', async t => {
+ const home = t.testdir()
+
+ mockGlobals(t, {
+ 'process.env': {
+ HOME: home,
+ TEST: '1',
+ },
+ })
+
+ t.equal(process.env.HOME, home)
+ t.equal(process.env.TEST, '1')
+ })
+
+ t.equal(process.env.HOME, originals.home)
+ t.equal(process.env.TEST, undefined)
+})
+
+t.test('conflicting mixed object/string mode', async t => {
+ await t.test('same key', async t => {
+ t.throws(
+ () => mockGlobals(t, {
+ process: {
+ env: {
+ HOME: '1',
+ TEST: '1',
+ NODE_ENV: '1',
+ },
+ stderr: {
+ write: '1',
+ },
+ },
+ 'process.env.HOME': '1',
+ 'process.stderr.write': '1',
+ }),
+ /process.env.HOME,process.stderr.write/
+ )
+ })
+
+ await t.test('partial overwrite with replace', async t => {
+ t.throws(
+ () => mockGlobals(t, {
+ process: {
+ env: {
+ HOME: '1',
+ TEST: '1',
+ NODE_ENV: '1',
+ },
+ stderr: {
+ write: '1',
+ },
+ },
+ 'process.env.HOME': '1',
+ 'process.stderr.write': '1',
+ }, { replace: true }),
+ /process -> process.env.HOME,process.stderr.write/
+ )
+ })
+})
+
+t.test('falsy values', async t => {
+ await t.test('undefined deletes', async t => {
+ mockGlobals(t, { 'process.platform': undefined })
+ t.notOk(Object.prototype.hasOwnProperty.call(process, 'platform'))
+ t.equal(process.platform, undefined)
+ })
+
+ await t.test('null', async t => {
+ mockGlobals(t, { 'process.platform': null })
+ t.ok(Object.prototype.hasOwnProperty.call(process, 'platform'))
+ t.equal(process.platform, null)
+ })
+
+ t.equal(process.platform, originals.platform)
+})
+
+t.test('date', async t => {
+ await t.test('mocks', async t => {
+ mockGlobals(t, {
+ 'Date.now': () => 100,
+ 'Date.prototype.toISOString': () => 'DDD',
+ })
+ t.equal(Date.now(), 100)
+ t.equal(new Date().toISOString(), 'DDD')
+ })
+
+ t.ok(Date.now() > 100)
+ t.ok(new Date().toISOString().includes('T'))
+})
+
+t.test('argv', async t => {
+ await t.test('argv', async t => {
+ mockGlobals(t, { 'process.argv': ['node', 'woo'] })
+ t.strictSame(process.argv, ['node', 'woo'])
+ })
+
+ t.strictSame(process.argv, originals.argv)
+})
+
+t.test('replace', async (t) => {
+ await t.test('env', async t => {
+ mockGlobals(t, { 'process.env': { HOME: '1' } }, { replace: true })
+ t.strictSame(process.env, { HOME: '1' })
+ t.equal(Object.keys(process.env).length, 1)
+ })
+
+ await t.test('setInterval', async t => {
+ mockGlobals(t, { setInterval: 0 }, { replace: true })
+ t.strictSame(setInterval, 0)
+ })
+
+ t.strictSame(setInterval, originals.setInterval)
+ t.strictSame(process.env, originals.env)
+})
+
+t.test('multiple mocks and resets', async (t) => {
+ const initial = 'a'
+ const platforms = ['b', 'c', 'd', 'e', 'f', 'g']
+
+ await t.test('first in, first out', async t => {
+ mockGlobals(t, { 'process.platform': initial })
+ t.equal(process.platform, initial)
+
+ await t.test('platforms', async (t) => {
+ const resets = platforms.map((platform) => {
+ const { reset } = mockGlobals(t, { 'process.platform': platform })
+ t.equal(process.platform, platform)
+ return reset['process.platform']
+ }).reverse()
+
+ ;[...platforms.reverse()].forEach((platform, index) => {
+ const reset = resets[index]
+ const nextPlatform = index === platforms.length - 1 ? initial : platforms[index + 1]
+ t.equal(process.platform, platform)
+ reset()
+ t.equal(process.platform, nextPlatform, 'first reset')
+ reset()
+ reset()
+ t.equal(process.platform, nextPlatform, 'multiple resets are indempotent')
+ })
+ })
+
+ t.equal(process.platform, initial)
+ })
+
+ await t.test('last in,first out', async t => {
+ mockGlobals(t, { 'process.platform': initial })
+ t.equal(process.platform, initial)
+
+ await t.test('platforms', async (t) => {
+ const resets = platforms.map((platform) => {
+ const { reset } = mockGlobals(t, { 'process.platform': platform })
+ t.equal(process.platform, platform)
+ return reset['process.platform']
+ })
+
+ resets.forEach((reset, index) => {
+ // Calling a reset out of order removes it from the stack
+ // but does not change the descriptor so it should still be the
+ // last in descriptor until there are none left
+ const lastPlatform = platforms[platforms.length - 1]
+ const nextPlatform = index === platforms.length - 1 ? initial : lastPlatform
+ t.equal(process.platform, lastPlatform)
+ reset()
+ t.equal(process.platform, nextPlatform, 'multiple resets are indempotent')
+ reset()
+ reset()
+ t.equal(process.platform, nextPlatform, 'multiple resets are indempotent')
+ })
+ })
+
+ t.equal(process.platform, initial)
+ })
+
+ t.test('reset all', async (t) => {
+ const { teardown } = mockGlobals(t, { 'process.platform': initial })
+
+ await t.test('platforms', async (t) => {
+ const resets = platforms.map((p) => {
+ const { teardown, reset } = mockGlobals(t, { 'process.platform': p })
+ t.equal(process.platform, p)
+ return [
+ reset['process.platform'],
+ teardown,
+ ]
+ })
+
+ resets.forEach(r => r[1]())
+ t.equal(process.platform, initial, 'teardown goes to initial value')
+
+ resets.forEach((r) => r[0]())
+ t.equal(process.platform, initial, 'calling resets after teardown does nothing')
+ })
+
+ t.equal(process.platform, initial)
+ teardown()
+ t.equal(process.platform, originals.platform)
+ })
+})
diff --git a/deps/npm/test/lib/load-all-commands.js b/deps/npm/test/lib/load-all-commands.js
index f813e50b220e17..248c81a30ab4d4 100644
--- a/deps/npm/test/lib/load-all-commands.js
+++ b/deps/npm/test/lib/load-all-commands.js
@@ -4,21 +4,16 @@
// renders also ensures that any params we've defined in our commands work.
const t = require('tap')
const util = require('util')
-const { real: mockNpm } = require('../fixtures/mock-npm.js')
+const { load: loadMockNpm } = require('../fixtures/mock-npm.js')
const { cmdList } = require('../../lib/utils/cmd-list.js')
-const { Npm, outputs } = mockNpm(t)
-const npm = new Npm()
-
t.test('load each command', async t => {
- t.afterEach(() => {
- outputs.length = 0
- })
t.plan(cmdList.length)
- await npm.load()
- npm.config.set('usage', true) // This makes npm.exec output the usage
for (const cmd of cmdList.sort((a, b) => a.localeCompare(b, 'en'))) {
t.test(cmd, async t => {
+ const { npm, outputs } = await loadMockNpm(t, {
+ config: { usage: true },
+ })
const impl = await npm.cmd(cmd)
if (impl.completion) {
t.type(impl.completion, 'function', 'completion, if present, is a function')
diff --git a/deps/npm/test/lib/load-all.js b/deps/npm/test/lib/load-all.js
index fb45331ba92aa5..e5d7b558c2a5b2 100644
--- a/deps/npm/test/lib/load-all.js
+++ b/deps/npm/test/lib/load-all.js
@@ -1,34 +1,31 @@
const t = require('tap')
const glob = require('glob')
const { resolve } = require('path')
-const { real: mockNpm } = require('../fixtures/mock-npm')
+const { load: loadMockNpm } = require('../fixtures/mock-npm')
const full = process.env.npm_lifecycle_event === 'check-coverage'
if (!full) {
t.pass('nothing to do here, not checking for full coverage')
} else {
- const { Npm } = mockNpm(t)
- const npm = new Npm()
+ t.test('load all', async (t) => {
+ const { npm } = await loadMockNpm(t, { })
- t.teardown(() => {
- const exitHandler = require('../../lib/utils/exit-handler.js')
- exitHandler.setNpm(npm)
- exitHandler()
- })
-
- t.before(async t => {
- await npm.load()
- })
+ t.teardown(() => {
+ const exitHandler = require('../../lib/utils/exit-handler.js')
+ exitHandler.setNpm(npm)
+ exitHandler()
+ })
- t.test('load all the files', t => {
- // just load all the files so we measure coverage for the missing tests
- const dir = resolve(__dirname, '../../lib')
- for (const f of glob.sync(`${dir}/**/*.js`)) {
- require(f)
- t.pass('loaded ' + f)
- }
- t.pass('loaded all files')
- t.end()
+ t.test('load all the files', t => {
+ // just load all the files so we measure coverage for the missing tests
+ const dir = resolve(__dirname, '../../lib')
+ for (const f of glob.sync(`${dir}/**/*.js`)) {
+ require(f)
+ t.pass('loaded ' + f)
+ }
+ t.pass('loaded all files')
+ t.end()
+ })
})
}
diff --git a/deps/npm/test/lib/npm.js b/deps/npm/test/lib/npm.js
index 1ccd26e3758035..2a0c5a89d2d995 100644
--- a/deps/npm/test/lib/npm.js
+++ b/deps/npm/test/lib/npm.js
@@ -1,7 +1,8 @@
const t = require('tap')
+const { resolve, dirname } = require('path')
-const npmlog = require('npmlog')
-const { real: mockNpm } = require('../fixtures/mock-npm.js')
+const { load: loadMockNpm } = require('../fixtures/mock-npm.js')
+const mockGlobals = require('../fixtures/mock-globals')
// delete this so that we don't have configs from the fact that it
// is being run by 'npm test'
@@ -15,7 +16,7 @@ for (const env of Object.keys(process.env).filter(e => /^npm_/.test(e))) {
// if this test is just run directly, which is also acceptable.
if (event === 'test') {
t.ok(
- ['test', 'run-script'].some(i => i === event),
+ ['test', 'run-script'].some(i => i === process.env[env]),
'should match "npm test" or "npm run test"'
)
} else {
@@ -25,41 +26,14 @@ for (const env of Object.keys(process.env).filter(e => /^npm_/.test(e))) {
delete process.env[env]
}
-const { resolve, dirname } = require('path')
-
-const actualPlatform = process.platform
-const beWindows = () => {
- Object.defineProperty(process, 'platform', {
- value: 'win32',
- configurable: true,
- })
-}
-const bePosix = () => {
- Object.defineProperty(process, 'platform', {
- value: 'posix',
- configurable: true,
- })
-}
-const argv = [...process.argv]
-
-t.afterEach(() => {
+t.afterEach(async (t) => {
for (const env of Object.keys(process.env).filter(e => /^npm_/.test(e))) {
delete process.env[env]
}
- process.env.npm_config_cache = CACHE
- process.argv = argv
- Object.defineProperty(process, 'platform', {
- value: actualPlatform,
- configurable: true,
- })
})
-const CACHE = t.testdir()
-process.env.npm_config_cache = CACHE
-
t.test('not yet loaded', async t => {
- const { Npm, logs } = mockNpm(t)
- const npm = new Npm()
+ const { npm, logs } = await loadMockNpm(t, { load: false })
t.match(npm, {
started: Number,
command: null,
@@ -79,8 +53,7 @@ t.test('not yet loaded', async t => {
t.test('npm.load', async t => {
t.test('load error', async t => {
- const { Npm } = mockNpm(t)
- const npm = new Npm()
+ const { npm } = await loadMockNpm(t, { load: false })
const loadError = new Error('load error')
npm.config.load = async () => {
throw loadError
@@ -103,32 +76,28 @@ t.test('npm.load', async t => {
})
t.test('basic loading', async t => {
- const { Npm, logs } = mockNpm(t)
- const npm = new Npm()
- const dir = t.testdir({
- node_modules: {},
+ const { npm, logs, prefix: dir, cache } = await loadMockNpm(t, {
+ testdir: { node_modules: {} },
})
- await npm.load()
+
t.equal(npm.loaded, true)
t.equal(npm.config.loaded, true)
t.equal(npm.config.get('force'), false)
t.ok(npm.usage, 'has usage')
- npm.config.set('prefix', dir)
t.match(npm, {
flatOptions: {},
})
- t.match(logs, [
- ['timing', 'npm:load', /Completed in [0-9.]+ms/],
+ t.match(logs.timing.filter(([p]) => p === 'npm:load'), [
+ ['npm:load', /Completed in [0-9.]+ms/],
])
- bePosix()
- t.equal(resolve(npm.cache), resolve(CACHE), 'cache is cache')
+ mockGlobals(t, { process: { platform: 'posix' } })
+ t.equal(resolve(npm.cache), resolve(cache), 'cache is cache')
const newCache = t.testdir()
npm.cache = newCache
t.equal(npm.config.get('cache'), newCache, 'cache setter sets config')
t.equal(npm.cache, newCache, 'cache getter gets new config')
- t.equal(npm.log, npmlog, 'npmlog getter')
t.equal(npm.lockfileVersion, 2, 'lockfileVersion getter')
t.equal(npm.prefix, npm.localPrefix, 'prefix is local prefix')
t.not(npm.prefix, npm.globalPrefix, 'prefix is not global prefix')
@@ -160,10 +129,9 @@ t.test('npm.load', async t => {
t.equal(npm.bin, npm.globalBin, 'bin is global bin after prefix setter')
t.not(npm.bin, npm.localBin, 'bin is not local bin after prefix setter')
- beWindows()
+ mockGlobals(t, { process: { platform: 'win32' } })
t.equal(npm.bin, npm.globalBin, 'bin is global bin in windows mode')
t.equal(npm.dir, npm.globalDir, 'dir is global dir in windows mode')
- bePosix()
const tmp = npm.tmp
t.match(tmp, String, 'npm.tmp is a string')
@@ -171,13 +139,12 @@ t.test('npm.load', async t => {
})
t.test('forceful loading', async t => {
- process.argv = [...process.argv, '--force', '--color', 'always']
- const { Npm, logs } = mockNpm(t)
- const npm = new Npm()
- await npm.load()
- t.match(logs.filter(l => l[0] !== 'timing'), [
+ mockGlobals(t, {
+ 'process.argv': [...process.argv, '--force', '--color', 'always'],
+ })
+ const { logs } = await loadMockNpm(t)
+ t.match(logs.warn, [
[
- 'warn',
'using --force',
'Recommended protections disabled.',
],
@@ -185,54 +152,42 @@ t.test('npm.load', async t => {
})
t.test('node is a symlink', async t => {
- const node = actualPlatform === 'win32' ? 'node.exe' : 'node'
- const dir = t.testdir({
- '.npmrc': 'foo = bar',
- bin: t.fixture('symlink', dirname(process.execPath)),
+ const node = process.platform === 'win32' ? 'node.exe' : 'node'
+ mockGlobals(t, {
+ 'process.argv': [
+ node,
+ process.argv[1],
+ '--usage',
+ '--scope=foo',
+ 'token',
+ 'revoke',
+ 'blergggg',
+ ],
})
-
- const PATH = process.env.PATH || process.env.Path
- process.env.PATH = resolve(dir, 'bin')
- process.argv = [
- node,
- process.argv[1],
- '--prefix', dir,
- '--userconfig', `${dir}/.npmrc`,
- '--usage',
- '--scope=foo',
- 'token',
- 'revoke',
- 'blergggg',
- ]
-
- t.teardown(() => {
- process.env.PATH = PATH
+ const { npm, logs, outputs, prefix } = await loadMockNpm(t, {
+ testdir: {
+ bin: t.fixture('symlink', dirname(process.execPath)),
+ },
+ globals: ({ prefix }) => ({
+ 'process.env.PATH': resolve(prefix, 'bin'),
+ }),
})
- const { Npm, logs, outputs } = mockNpm(t)
- const npm = new Npm()
- await npm.load()
t.equal(npm.config.get('scope'), '@foo', 'added the @ sign to scope')
- t.match(logs.filter(l => l[0] !== 'timing' || !/^config:/.test(l[1])), [
- [
- 'timing',
- 'npm:load:whichnode',
- /Completed in [0-9.]+ms/,
- ],
- [
- 'verbose',
- 'node symlink',
- resolve(dir, 'bin', node),
- ],
- [
- 'timing',
- 'npm:load',
- /Completed in [0-9.]+ms/,
- ],
+ t.match([
+ ...logs.timing.filter(([p]) => p === 'npm:load:whichnode'),
+ ...logs.verbose,
+ ...logs.timing.filter(([p]) => p === 'npm:load'),
+ ], [
+ ['npm:load:whichnode', /Completed in [0-9.]+ms/],
+ ['node symlink', resolve(prefix, 'bin', node)],
+ ['logfile', /.*-debug-0.log/],
+ ['npm:load', /Completed in [0-9.]+ms/],
])
- t.equal(process.execPath, resolve(dir, 'bin', node))
+ t.equal(process.execPath, resolve(prefix, 'bin', node))
outputs.length = 0
+ logs.length = 0
await npm.exec('ll', [])
t.equal(npm.command, 'll', 'command set to first npm command')
@@ -271,33 +226,34 @@ t.test('npm.load', async t => {
})
t.test('--no-workspaces with --workspace', async t => {
- const dir = t.testdir({
- packages: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- scripts: { test: 'echo test a' },
- }),
+ mockGlobals(t, {
+ 'process.argv': [
+ process.execPath,
+ process.argv[1],
+ '--color', 'false',
+ '--workspaces', 'false',
+ '--workspace', 'a',
+ ],
+ })
+ const { npm } = await loadMockNpm(t, {
+ load: false,
+ testdir: {
+ packages: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ scripts: { test: 'echo test a' },
+ }),
+ },
},
+ 'package.json': JSON.stringify({
+ name: 'root',
+ version: '1.0.0',
+ workspaces: ['./packages/*'],
+ }),
},
- 'package.json': JSON.stringify({
- name: 'root',
- version: '1.0.0',
- workspaces: ['./packages/*'],
- }),
})
- process.argv = [
- process.execPath,
- process.argv[1],
- '--userconfig', resolve(dir, '.npmrc'),
- '--color', 'false',
- '--workspaces', 'false',
- '--workspace', 'a',
- ]
- const { Npm } = mockNpm(t)
- const npm = new Npm()
- npm.localPrefix = dir
await t.rejects(
npm.exec('run', []),
/Can not use --no-workspaces and --workspace at the same time/
@@ -305,47 +261,40 @@ t.test('npm.load', async t => {
})
t.test('workspace-aware configs and commands', async t => {
- const dir = t.testdir({
- packages: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- scripts: { test: 'echo test a' },
- }),
- },
- b: {
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.0.0',
- scripts: { test: 'echo test b' },
- }),
+ mockGlobals(t, {
+ 'process.argv': [
+ process.execPath,
+ process.argv[1],
+ '--color', 'false',
+ '--workspaces', 'true',
+ ],
+ })
+ const { npm, outputs } = await loadMockNpm(t, {
+ testdir: {
+ packages: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ scripts: { test: 'echo test a' },
+ }),
+ },
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ scripts: { test: 'echo test b' },
+ }),
+ },
},
+ 'package.json': JSON.stringify({
+ name: 'root',
+ version: '1.0.0',
+ workspaces: ['./packages/*'],
+ }),
},
- 'package.json': JSON.stringify({
- name: 'root',
- version: '1.0.0',
- workspaces: ['./packages/*'],
- }),
- '.npmrc': '',
})
- process.argv = [
- process.execPath,
- process.argv[1],
- '--userconfig',
- resolve(dir, '.npmrc'),
- '--color',
- 'false',
- '--workspaces',
- 'true',
- ]
-
- const { Npm, outputs } = mockNpm(t)
- const npm = new Npm()
- await npm.load()
- npm.localPrefix = dir
-
// verify that calling the command with a short name still sets
// the npm.command property to the full canonical name of the cmd.
npm.command = null
@@ -368,44 +317,42 @@ t.test('npm.load', async t => {
})
t.test('workspaces in global mode', async t => {
- const dir = t.testdir({
- packages: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- scripts: { test: 'echo test a' },
- }),
- },
- b: {
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.0.0',
- scripts: { test: 'echo test b' },
- }),
+ mockGlobals(t, {
+ 'process.argv': [
+ process.execPath,
+ process.argv[1],
+ '--color',
+ 'false',
+ '--workspaces',
+ '--global',
+ 'true',
+ ],
+ })
+ const { npm } = await loadMockNpm(t, {
+ testdir: {
+ packages: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ scripts: { test: 'echo test a' },
+ }),
+ },
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ scripts: { test: 'echo test b' },
+ }),
+ },
},
+ 'package.json': JSON.stringify({
+ name: 'root',
+ version: '1.0.0',
+ workspaces: ['./packages/*'],
+ }),
},
- 'package.json': JSON.stringify({
- name: 'root',
- version: '1.0.0',
- workspaces: ['./packages/*'],
- }),
})
- process.argv = [
- process.execPath,
- process.argv[1],
- '--userconfig',
- resolve(dir, '.npmrc'),
- '--color',
- 'false',
- '--workspaces',
- '--global',
- 'true',
- ]
- const { Npm } = mockNpm(t)
- const npm = new Npm()
- await npm.load()
- npm.localPrefix = dir
// verify that calling the command with a short name still sets
// the npm.command property to the full canonical name of the cmd.
npm.command = null
@@ -418,109 +365,156 @@ t.test('npm.load', async t => {
t.test('set process.title', async t => {
t.test('basic title setting', async t => {
- process.argv = [
- process.execPath,
- process.argv[1],
- '--usage',
- '--scope=foo',
- 'ls',
- ]
- const { Npm } = mockNpm(t)
- const npm = new Npm()
- await npm.load()
+ mockGlobals(t, {
+ 'process.argv': [
+ process.execPath,
+ process.argv[1],
+ '--usage',
+ '--scope=foo',
+ 'ls',
+ ],
+ })
+ const { npm } = await loadMockNpm(t)
t.equal(npm.title, 'npm ls')
t.equal(process.title, 'npm ls')
})
t.test('do not expose token being revoked', async t => {
- process.argv = [
- process.execPath,
- process.argv[1],
- '--usage',
- '--scope=foo',
- 'token',
- 'revoke',
- 'deadbeefcafebad',
- ]
- const { Npm } = mockNpm(t)
- const npm = new Npm()
- await npm.load()
+ mockGlobals(t, {
+ 'process.argv': [
+ process.execPath,
+ process.argv[1],
+ '--usage',
+ '--scope=foo',
+ 'token',
+ 'revoke',
+ 'deadbeefcafebad',
+ ],
+ })
+ const { npm } = await loadMockNpm(t)
t.equal(npm.title, 'npm token revoke ***')
t.equal(process.title, 'npm token revoke ***')
})
t.test('do show *** unless a token is actually being revoked', async t => {
- process.argv = [
- process.execPath,
- process.argv[1],
- '--usage',
- '--scope=foo',
- 'token',
- 'revoke',
- ]
- const { Npm } = mockNpm(t)
- const npm = new Npm()
- await npm.load()
+ mockGlobals(t, {
+ 'process.argv': [
+ process.execPath,
+ process.argv[1],
+ '--usage',
+ '--scope=foo',
+ 'token',
+ 'revoke',
+ ],
+ })
+ const { npm } = await loadMockNpm(t)
t.equal(npm.title, 'npm token revoke')
t.equal(process.title, 'npm token revoke')
})
})
-t.test('timings', t => {
- const { Npm, logs } = mockNpm(t)
- const npm = new Npm()
- process.emit('time', 'foo')
- process.emit('time', 'bar')
- t.match(npm.timers.get('foo'), Number, 'foo timer is a number')
- t.match(npm.timers.get('bar'), Number, 'foo timer is a number')
- process.emit('timeEnd', 'foo')
- process.emit('timeEnd', 'bar')
- process.emit('timeEnd', 'baz')
- t.match(logs, [
- ['timing', 'foo', /Completed in [0-9]+ms/],
- ['timing', 'bar', /Completed in [0-9]+ms/],
- [
- 'silly',
+t.test('debug-log', async t => {
+ const { npm, debugFile } = await loadMockNpm(t, { load: false })
+
+ const log1 = ['silly', 'test', 'before load']
+ const log2 = ['silly', 'test', 'after load']
+
+ process.emit('log', ...log1)
+ await npm.load()
+ process.emit('log', ...log2)
+
+ const debug = await debugFile()
+ t.equal(npm.logFiles.length, 1, 'one debug file')
+ t.match(debug, log1.join(' '), 'before load appears')
+ t.match(debug, log2.join(' '), 'after load log appears')
+})
+
+t.test('timings', async t => {
+ t.test('gets/sets timers', async t => {
+ const { npm, logs } = await loadMockNpm(t, { load: false })
+ process.emit('time', 'foo')
+ process.emit('time', 'bar')
+ t.match(npm.unfinishedTimers.get('foo'), Number, 'foo timer is a number')
+ t.match(npm.unfinishedTimers.get('bar'), Number, 'foo timer is a number')
+ process.emit('timeEnd', 'foo')
+ process.emit('timeEnd', 'bar')
+ process.emit('timeEnd', 'baz')
+ // npm timer is started by default
+ process.emit('timeEnd', 'npm')
+ t.match(logs.timing, [
+ ['foo', /Completed in [0-9]+ms/],
+ ['bar', /Completed in [0-9]+ms/],
+ ['npm', /Completed in [0-9]+ms/],
+ ])
+ t.match(logs.silly, [[
'timing',
"Tried to end timer that doesn't exist:",
'baz',
- ],
- ])
- t.notOk(npm.timers.has('foo'), 'foo timer is gone')
- t.notOk(npm.timers.has('bar'), 'bar timer is gone')
- t.match(npm.timings, { foo: Number, bar: Number })
- t.end()
+ ]])
+ t.notOk(npm.unfinishedTimers.has('foo'), 'foo timer is gone')
+ t.notOk(npm.unfinishedTimers.has('bar'), 'bar timer is gone')
+ t.match(npm.finishedTimers, { foo: Number, bar: Number, npm: Number })
+ t.end()
+ })
+
+ t.test('writes timings file', async t => {
+ const { npm, timingFile } = await loadMockNpm(t, {
+ config: { timing: true },
+ })
+ process.emit('time', 'foo')
+ process.emit('timeEnd', 'foo')
+ process.emit('time', 'bar')
+ npm.unload()
+ const timings = await timingFile()
+ t.match(timings, {
+ command: [],
+ logfile: String,
+ logfiles: [String],
+ version: String,
+ unfinished: {
+ bar: [Number, Number],
+ npm: [Number, Number],
+ },
+ foo: Number,
+ 'npm:load': Number,
+ })
+ })
+
+ t.test('does not write timings file with timers:false', async t => {
+ const { npm, timingFile } = await loadMockNpm(t, {
+ config: { false: true },
+ })
+ npm.unload()
+ await t.rejects(() => timingFile())
+ })
})
-t.test('output clears progress and console.logs the message', t => {
- const mock = mockNpm(t)
- const { Npm, logs } = mock
- const npm = new Npm()
- npm.output = mock.npmOutput
- const { log } = console
- const { log: { clearProgress, showProgress } } = npm
+t.test('output clears progress and console.logs the message', async t => {
+ t.plan(2)
let showingProgress = true
- npm.log.clearProgress = () => showingProgress = false
- npm.log.showProgress = () => showingProgress = true
- console.log = (...args) => {
- t.equal(showingProgress, false, 'should not be showing progress right now')
- logs.push(args)
- }
- t.teardown(() => {
- console.log = log
- npm.log.showProgress = showProgress
- npm.log.clearProgress = clearProgress
+ const logs = []
+ mockGlobals(t, {
+ 'console.log': (...args) => {
+ t.equal(showingProgress, false, 'should not be showing progress right now')
+ logs.push(args)
+ },
})
-
- npm.output('hello')
- t.strictSame(logs, [['hello']])
+ const { npm } = await loadMockNpm(t, {
+ load: false,
+ mocks: {
+ npmlog: {
+ clearProgress: () => showingProgress = false,
+ showProgress: () => showingProgress = true,
+ },
+ },
+ })
+ npm.originalOutput('hello')
+ t.match(logs, [['hello']])
t.end()
})
t.test('unknown command', async t => {
- const mock = mockNpm(t)
- const { Npm } = mock
- const npm = new Npm()
+ const { npm } = await loadMockNpm(t, { load: false })
await t.rejects(
npm.cmd('thisisnotacommand'),
{ code: 'EUNKNOWNCOMMAND' }
diff --git a/deps/npm/test/lib/utils/audit-error.js b/deps/npm/test/lib/utils/audit-error.js
index c683053cbf7871..bcb7d8c16dd7b6 100644
--- a/deps/npm/test/lib/utils/audit-error.js
+++ b/deps/npm/test/lib/utils/audit-error.js
@@ -3,14 +3,15 @@ const t = require('tap')
const LOGS = []
const OUTPUT = []
const output = (...msg) => OUTPUT.push(msg)
-const auditError = require('../../../lib/utils/audit-error.js')
+const auditError = t.mock('../../../lib/utils/audit-error.js', {
+ 'proc-log': {
+ warn: (...msg) => LOGS.push(msg),
+ },
+})
const npm = {
command: null,
flatOptions: {},
- log: {
- warn: (...msg) => LOGS.push(msg),
- },
output,
}
t.afterEach(() => {
diff --git a/deps/npm/test/lib/utils/cleanup-log-files.js b/deps/npm/test/lib/utils/cleanup-log-files.js
deleted file mode 100644
index e97cf36b55dec0..00000000000000
--- a/deps/npm/test/lib/utils/cleanup-log-files.js
+++ /dev/null
@@ -1,79 +0,0 @@
-const t = require('tap')
-
-const glob = require('glob')
-const rimraf = require('rimraf')
-const mocks = { glob, rimraf }
-const cleanup = t.mock('../../../lib/utils/cleanup-log-files.js', {
- glob: (...args) => mocks.glob(...args),
- rimraf: (...args) => mocks.rimraf(...args),
-})
-const { basename } = require('path')
-
-const fs = require('fs')
-
-t.test('clean up those files', t => {
- const cache = t.testdir({
- _logs: {
- '1-debug.log': 'hello',
- '2-debug.log': 'hello',
- '3-debug.log': 'hello',
- '4-debug.log': 'hello',
- '5-debug.log': 'hello',
- },
- })
- const warn = (...warning) => t.fail('failed cleanup', { warning })
- return cleanup(cache, 3, warn).then(() => {
- t.strictSame(fs.readdirSync(cache + '/_logs').sort(), [
- '3-debug.log',
- '4-debug.log',
- '5-debug.log',
- ])
- })
-})
-
-t.test('nothing to clean up', t => {
- const cache = t.testdir({
- _logs: {
- '4-debug.log': 'hello',
- '5-debug.log': 'hello',
- },
- })
- const warn = (...warning) => t.fail('failed cleanup', { warning })
- return cleanup(cache, 3, warn).then(() => {
- t.strictSame(fs.readdirSync(cache + '/_logs').sort(), [
- '4-debug.log',
- '5-debug.log',
- ])
- })
-})
-
-t.test('glob fail', t => {
- mocks.glob = (pattern, cb) => cb(new Error('no globbity'))
- t.teardown(() => mocks.glob = glob)
- const cache = t.testdir({})
- const warn = (...warning) => t.fail('failed cleanup', { warning })
- return cleanup(cache, 3, warn)
-})
-
-t.test('rimraf fail', t => {
- mocks.rimraf = (file, cb) => cb(new Error('youll never rimraf me!'))
- t.teardown(() => mocks.rimraf = rimraf)
-
- const cache = t.testdir({
- _logs: {
- '1-debug.log': 'hello',
- '2-debug.log': 'hello',
- '3-debug.log': 'hello',
- '4-debug.log': 'hello',
- '5-debug.log': 'hello',
- },
- })
- const warnings = []
- const warn = (...warning) => warnings.push(basename(warning[2]))
- return cleanup(cache, 3, warn).then(() => {
- t.strictSame(warnings.sort((a, b) => a.localeCompare(b, 'en')), [
- '1-debug.log',
- '2-debug.log',
- ])
- })
-})
diff --git a/deps/npm/test/lib/utils/config/definitions.js b/deps/npm/test/lib/utils/config/definitions.js
index f6813a8bc0bb5d..bf4b48709ae7b4 100644
--- a/deps/npm/test/lib/utils/config/definitions.js
+++ b/deps/npm/test/lib/utils/config/definitions.js
@@ -1,11 +1,9 @@
const t = require('tap')
-
const { resolve } = require('path')
+const mockGlobals = require('../../../fixtures/mock-globals')
// have to fake the node version, or else it'll only pass on this one
-Object.defineProperty(process, 'version', {
- value: 'v14.8.0',
-})
+mockGlobals(t, { 'process.version': 'v14.8.0', 'process.env.NODE_ENV': undefined })
// also fake the npm version, so that it doesn't get reset every time
const pkg = require('../../../../package.json')
@@ -13,8 +11,6 @@ const pkg = require('../../../../package.json')
// this is a pain to keep typing
const defpath = '../../../../lib/utils/config/definitions.js'
-// set this in the test when we need it
-delete process.env.NODE_ENV
const definitions = require(defpath)
// Tie the definitions to a snapshot so that if they change we are forced to
@@ -43,22 +39,19 @@ t.test('basic flattening function camelCases from css-case', t => {
t.test('editor', t => {
t.test('has EDITOR and VISUAL, use EDITOR', t => {
- process.env.EDITOR = 'vim'
- process.env.VISUAL = 'mate'
+ mockGlobals(t, { 'process.env': { EDITOR: 'vim', VISUAL: 'mate' } })
const defs = t.mock(defpath)
t.equal(defs.editor.default, 'vim')
t.end()
})
t.test('has VISUAL but no EDITOR, use VISUAL', t => {
- delete process.env.EDITOR
- process.env.VISUAL = 'mate'
+ mockGlobals(t, { 'process.env': { EDITOR: undefined, VISUAL: 'mate' } })
const defs = t.mock(defpath)
t.equal(defs.editor.default, 'mate')
t.end()
})
t.test('has neither EDITOR nor VISUAL, system specific', t => {
- delete process.env.EDITOR
- delete process.env.VISUAL
+ mockGlobals(t, { 'process.env': { EDITOR: undefined, VISUAL: undefined } })
const defsWin = t.mock(defpath, {
[isWin]: true,
})
@@ -74,12 +67,12 @@ t.test('editor', t => {
t.test('shell', t => {
t.test('windows, env.ComSpec then cmd.exe', t => {
- process.env.ComSpec = 'command.com'
+ mockGlobals(t, { 'process.env.ComSpec': 'command.com' })
const defsComSpec = t.mock(defpath, {
[isWin]: true,
})
t.equal(defsComSpec.shell.default, 'command.com')
- delete process.env.ComSpec
+ mockGlobals(t, { 'process.env.ComSpec': undefined })
const defsNoComSpec = t.mock(defpath, {
[isWin]: true,
})
@@ -88,12 +81,12 @@ t.test('shell', t => {
})
t.test('nix, SHELL then sh', t => {
- process.env.SHELL = '/usr/local/bin/bash'
+ mockGlobals(t, { 'process.env.SHELL': '/usr/local/bin/bash' })
const defsShell = t.mock(defpath, {
[isWin]: false,
})
t.equal(defsShell.shell.default, '/usr/local/bin/bash')
- delete process.env.SHELL
+ mockGlobals(t, { 'process.env.SHELL': undefined })
const defsNoShell = t.mock(defpath, {
[isWin]: false,
})
@@ -136,43 +129,40 @@ t.test('local-address allowed types', t => {
})
t.test('unicode allowed?', t => {
- const { LC_ALL, LC_CTYPE, LANG } = process.env
- t.teardown(() => Object.assign(process.env, { LC_ALL, LC_CTYPE, LANG }))
+ const setGlobal = (obj = {}) => mockGlobals(t, { 'process.env': obj })
- process.env.LC_ALL = 'utf8'
- process.env.LC_CTYPE = 'UTF-8'
- process.env.LANG = 'Unicode utf-8'
+ setGlobal({ LC_ALL: 'utf8', LC_CTYPE: 'UTF-8', LANG: 'Unicode utf-8' })
const lcAll = t.mock(defpath)
t.equal(lcAll.unicode.default, true)
- process.env.LC_ALL = 'no unicode for youUUUU!'
+ setGlobal({ LC_ALL: 'no unicode for youUUUU!' })
const noLcAll = t.mock(defpath)
t.equal(noLcAll.unicode.default, false)
- delete process.env.LC_ALL
+ setGlobal({ LC_ALL: undefined })
const lcCtype = t.mock(defpath)
t.equal(lcCtype.unicode.default, true)
- process.env.LC_CTYPE = 'something other than unicode version 8'
+ setGlobal({ LC_CTYPE: 'something other than unicode version 8' })
const noLcCtype = t.mock(defpath)
t.equal(noLcCtype.unicode.default, false)
- delete process.env.LC_CTYPE
+ setGlobal({ LC_CTYPE: undefined })
const lang = t.mock(defpath)
t.equal(lang.unicode.default, true)
- process.env.LANG = 'ISO-8859-1'
+ setGlobal({ LANG: 'ISO-8859-1' })
const noLang = t.mock(defpath)
t.equal(noLang.unicode.default, false)
t.end()
})
t.test('cache', t => {
- process.env.LOCALAPPDATA = 'app/data/local'
+ mockGlobals(t, { 'process.env.LOCALAPPDATA': 'app/data/local' })
const defsWinLocalAppData = t.mock(defpath, {
[isWin]: true,
})
t.equal(defsWinLocalAppData.cache.default, 'app/data/local/npm-cache')
- delete process.env.LOCALAPPDATA
+ mockGlobals(t, { 'process.env.LOCALAPPDATA': undefined })
const defsWinNoLocalAppData = t.mock(defpath, {
[isWin]: true,
})
@@ -241,7 +231,7 @@ t.test('flatteners that populate flat.omit array', t => {
definitions.omit.flatten('omit', obj, flat)
t.strictSame(flat, { omit: ['optional'] }, 'do not omit what is included')
- process.env.NODE_ENV = 'production'
+ mockGlobals(t, { 'process.env.NODE_ENV': 'production' })
const defProdEnv = t.mock(defpath)
t.strictSame(defProdEnv.omit.default, ['dev'], 'omit dev in production')
t.end()
@@ -372,42 +362,79 @@ t.test('cache-min', t => {
})
t.test('color', t => {
- const { isTTY } = process.stdout
- t.teardown(() => process.stdout.isTTY = isTTY)
+ const setTTY = (stream, value) => mockGlobals(t, { [`process.${stream}.isTTY`]: value })
const flat = {}
const obj = { color: 'always' }
definitions.color.flatten('color', obj, flat)
- t.strictSame(flat, { color: true }, 'true when --color=always')
+ t.strictSame(flat, { color: true, logColor: true }, 'true when --color=always')
obj.color = false
definitions.color.flatten('color', obj, flat)
- t.strictSame(flat, { color: false }, 'true when --no-color')
+ t.strictSame(flat, { color: false, logColor: false }, 'true when --no-color')
- process.stdout.isTTY = false
+ setTTY('stdout', false)
obj.color = true
definitions.color.flatten('color', obj, flat)
- t.strictSame(flat, { color: false }, 'no color when stdout not tty')
- process.stdout.isTTY = true
+ t.strictSame(flat, { color: false, logColor: false }, 'no color when stdout not tty')
+ setTTY('stdout', true)
definitions.color.flatten('color', obj, flat)
- t.strictSame(flat, { color: true }, '--color turns on color when stdout is tty')
+ t.strictSame(flat, { color: true, logColor: false }, '--color turns on color when stdout is tty')
+ setTTY('stdout', false)
- delete process.env.NO_COLOR
+ setTTY('stderr', false)
+ obj.color = true
+ definitions.color.flatten('color', obj, flat)
+ t.strictSame(flat, { color: false, logColor: false }, 'no color when stderr not tty')
+ setTTY('stderr', true)
+ definitions.color.flatten('color', obj, flat)
+ t.strictSame(flat, { color: false, logColor: true }, '--color turns on color when stderr is tty')
+ setTTY('stderr', false)
+
+ const setColor = (value) => mockGlobals(t, { 'process.env.NO_COLOR': value })
+
+ setColor(undefined)
const defsAllowColor = t.mock(defpath)
t.equal(defsAllowColor.color.default, true, 'default true when no NO_COLOR env')
- process.env.NO_COLOR = '0'
+ setColor('0')
const defsNoColor0 = t.mock(defpath)
t.equal(defsNoColor0.color.default, true, 'default true when no NO_COLOR=0')
- process.env.NO_COLOR = '1'
+ setColor('1')
const defsNoColor1 = t.mock(defpath)
t.equal(defsNoColor1.color.default, false, 'default false when no NO_COLOR=1')
t.end()
})
+t.test('progress', t => {
+ const setEnv = ({ tty, term } = {}) => mockGlobals(t, {
+ 'process.stderr.isTTY': tty,
+ 'process.env.TERM': term,
+ })
+
+ const flat = {}
+
+ definitions.progress.flatten('progress', {}, flat)
+ t.strictSame(flat, { progress: false })
+
+ setEnv({ tty: true, term: 'notdumb' })
+ definitions.progress.flatten('progress', { progress: true }, flat)
+ t.strictSame(flat, { progress: true })
+
+ setEnv({ tty: false, term: 'notdumb' })
+ definitions.progress.flatten('progress', { progress: true }, flat)
+ t.strictSame(flat, { progress: false })
+
+ setEnv({ tty: true, term: 'dumb' })
+ definitions.progress.flatten('progress', { progress: true }, flat)
+ t.strictSame(flat, { progress: false })
+
+ t.end()
+})
+
t.test('retry options', t => {
const obj = {}
// : flat.retry[]
@@ -488,15 +515,15 @@ t.test('maxSockets', t => {
t.end()
})
-t.test('projectScope', t => {
+t.test('scope', t => {
const obj = { scope: 'asdf' }
const flat = {}
definitions.scope.flatten('scope', obj, flat)
- t.strictSame(flat, { projectScope: '@asdf' }, 'prepend @ if needed')
+ t.strictSame(flat, { scope: '@asdf', projectScope: '@asdf' }, 'prepend @ if needed')
obj.scope = '@asdf'
definitions.scope.flatten('scope', obj, flat)
- t.strictSame(flat, { projectScope: '@asdf' }, 'leave untouched if has @')
+ t.strictSame(flat, { scope: '@asdf', projectScope: '@asdf' }, 'leave untouched if has @')
t.end()
})
diff --git a/deps/npm/test/lib/utils/did-you-mean.js b/deps/npm/test/lib/utils/did-you-mean.js
index 185368d61f2ed9..d3cb3a24f0ae5c 100644
--- a/deps/npm/test/lib/utils/did-you-mean.js
+++ b/deps/npm/test/lib/utils/did-you-mean.js
@@ -1,11 +1,9 @@
const t = require('tap')
-const { real: mockNpm } = require('../../fixtures/mock-npm.js')
-const { Npm } = mockNpm(t)
-const npm = new Npm()
+const { load: loadMockNpm } = require('../../fixtures/mock-npm.js')
const dym = require('../../../lib/utils/did-you-mean.js')
t.test('did-you-mean', async t => {
- await npm.load()
+ const { npm } = await loadMockNpm(t)
t.test('with package.json', async t => {
const testdir = t.testdir({
'package.json': JSON.stringify({
diff --git a/deps/npm/test/lib/utils/display.js b/deps/npm/test/lib/utils/display.js
new file mode 100644
index 00000000000000..30cd2cc270dc5d
--- /dev/null
+++ b/deps/npm/test/lib/utils/display.js
@@ -0,0 +1,85 @@
+const t = require('tap')
+const log = require('../../../lib/utils/log-shim')
+const mockLogs = require('../../fixtures/mock-logs')
+const mockGlobals = require('../../fixtures/mock-globals')
+
+const mockDisplay = (t, mocks) => {
+ const { logs, logMocks } = mockLogs(mocks)
+ const Display = t.mock('../../../lib/utils/display', {
+ ...mocks,
+ ...logMocks,
+ })
+ const display = new Display()
+ t.teardown(() => display.off())
+ return { display, logs }
+}
+
+t.test('setup', async (t) => {
+ const { display } = mockDisplay(t)
+
+ display.load({ timing: true, loglevel: 'notice' })
+ t.equal(log.level, 'timing')
+
+ display.load({ timing: false, loglevel: 'notice' })
+ t.equal(log.level, 'notice')
+
+ display.load({ color: true })
+ t.equal(log.useColor(), true)
+
+ display.load({ unicode: true })
+ t.equal(log.gauge._theme.hasUnicode, true)
+
+ display.load({ unicode: false })
+ t.equal(log.gauge._theme.hasUnicode, false)
+
+ mockGlobals(t, { 'process.stderr.isTTY': true })
+ display.load({ progress: true })
+ t.equal(log.progressEnabled, true)
+})
+
+t.test('can log', async (t) => {
+ const explains = []
+ const { display, logs } = mockDisplay(t, {
+ npmlog: {
+ error: (...args) => logs.push(['error', ...args]),
+ warn: (...args) => logs.push(['warn', ...args]),
+ },
+ '../../../lib/utils/explain-eresolve.js': {
+ explain: (...args) => {
+ explains.push(args)
+ return 'explanation'
+ },
+ },
+ })
+
+ display.log('error', 'test')
+ t.match(logs.error, [['test']])
+
+ display.log('warn', 'ERESOLVE', 'hello', { some: 'object' })
+ t.match(logs.warn, [['ERESOLVE', 'hello']])
+ t.match(explains, [[{ some: 'object' }, false, 2]])
+})
+
+t.test('handles log throwing', async (t) => {
+ const errors = []
+ mockGlobals(t, {
+ 'console.error': (...args) => errors.push(args),
+ })
+ const { display } = mockDisplay(t, {
+ npmlog: {
+ verbose: () => {
+ throw new Error('verbose')
+ },
+ },
+ '../../../lib/utils/explain-eresolve.js': {
+ explain: () => {
+ throw new Error('explain')
+ },
+ },
+ })
+
+ display.log('warn', 'ERESOLVE', 'hello', { some: 'object' })
+ t.match(errors, [
+ [/attempt to log .* crashed/, Error('explain'), Error('verbose')],
+ ])
+})
diff --git a/deps/npm/test/lib/utils/error-message.js b/deps/npm/test/lib/utils/error-message.js
index 1959b9217a7d0d..ddc88c1d990b09 100644
--- a/deps/npm/test/lib/utils/error-message.js
+++ b/deps/npm/test/lib/utils/error-message.js
@@ -1,87 +1,51 @@
const t = require('tap')
const path = require('path')
-const { real: mockNpm } = require('../../fixtures/mock-npm.js')
-const { Npm } = mockNpm(t, {
- '../../package.json': {
- version: '123.456.789-npm',
+const { load: _loadMockNpm } = require('../../fixtures/mock-npm.js')
+const mockGlobals = require('../../fixtures/mock-globals.js')
+const { cleanCwd, cleanDate } = require('../../fixtures/clean-snapshot.js')
+
+t.cleanSnapshot = p => cleanDate(cleanCwd(p))
+
+mockGlobals(t, {
+ process: {
+ getuid: () => 867,
+ getgid: () => 5309,
+ arch: 'x64',
+ version: '123.456.789-node',
+ platform: 'posix',
},
})
-const npm = new Npm()
-const { Npm: UnloadedNpm } = mockNpm(t, {
- '../../package.json': {
- version: '123.456.789-npm',
- },
-})
-const unloadedNpm = new UnloadedNpm()
-
-// make a bunch of stuff consistent for snapshots
-
-process.getuid = () => 867
-process.getgid = () => 5309
-
-Object.defineProperty(process, 'arch', {
- value: 'x64',
- configurable: true,
-})
-
-Object.defineProperty(process, 'version', {
- value: '123.456.789-node',
- configurable: true,
-})
-const CACHE = '/some/cache/dir'
-const testdir = t.testdir({})
-t.before(async () => {
- await npm.load()
- npm.localPrefix = testdir
- unloadedNpm.localPrefix = testdir
- npm.config.set('cache', CACHE)
- npm.config.set('node-version', '99.99.99')
- npm.version = '123.456.789-npm'
- unloadedNpm.version = '123.456.789-npm'
-})
-
-const { resolve } = require('path')
-
-const npmlog = require('npmlog')
-const verboseLogs = []
-npmlog.verbose = (...message) => {
- verboseLogs.push(message)
-}
-
-const EXPLAIN_CALLED = []
-const mocks = {
- '../../../lib/utils/explain-eresolve.js': {
- report: (...args) => {
- EXPLAIN_CALLED.push(args)
- return 'explanation'
+const loadMockNpm = async (t, { load, command, testdir, config } = {}) => {
+ const { npm, ...rest } = await _loadMockNpm(t, {
+ load,
+ testdir,
+ config,
+ mocks: {
+ '../../package.json': {
+ version: '123.456.789-npm',
+ },
},
- },
- // XXX ???
- get '../../../lib/utils/is-windows.js' () {
- return process.platform === 'win32'
- },
-}
-let errorMessage = t.mock('../../../lib/utils/error-message.js', { ...mocks })
-
-const beWindows = () => {
- Object.defineProperty(process, 'platform', {
- value: 'win32',
- configurable: true,
})
- errorMessage = t.mock('../../../lib/utils/error-message.js', { ...mocks })
+ if (command !== undefined) {
+ npm.command = command
+ }
+ return {
+ npm,
+ ...rest,
+ }
}
-const bePosix = () => {
- Object.defineProperty(process, 'platform', {
- value: 'posix',
- configurable: true,
- })
- errorMessage = t.mock('../../../lib/utils/error-message.js', { ...mocks })
-}
+const errorMessage = (er, { mocks, logMocks, npm } = {}) =>
+ t.mock('../../../lib/utils/error-message.js', { ...mocks, ...logMocks })(er, npm)
-t.test('just simple messages', t => {
- npm.command = 'audit'
+t.test('just simple messages', async t => {
+ const npm = await loadMockNpm(t, {
+ command: 'audit',
+ config: {
+ 'node-version': '99.99.99',
+ },
+ })
const codes = [
'ENOAUDIT',
'ENOLOCK',
@@ -108,7 +72,7 @@ t.test('just simple messages', t => {
'ERR_SOCKET_TIMEOUT',
]
t.plan(codes.length)
- codes.forEach(code => {
+ codes.forEach(async code => {
const path = '/some/path'
const pkgid = 'some@package'
const file = '/some/file'
@@ -124,8 +88,8 @@ t.test('just simple messages', t => {
})
})
-t.test('replace message/stack sensistive info', t => {
- npm.command = 'audit'
+t.test('replace message/stack sensistive info', async t => {
+ const npm = await loadMockNpm(t, { command: 'audit' })
const path = '/some/path'
const pkgid = 'some@package'
const file = '/some/file'
@@ -139,10 +103,10 @@ t.test('replace message/stack sensistive info', t => {
stack,
})
t.matchSnapshot(errorMessage(er, npm))
- t.end()
})
-t.test('bad engine without config loaded', t => {
+t.test('bad engine without config loaded', async t => {
+ const npm = await loadMockNpm(t, { load: false })
const path = '/some/path'
const pkgid = 'some@package'
const file = '/some/file'
@@ -154,11 +118,11 @@ t.test('bad engine without config loaded', t => {
file,
stack,
})
- t.matchSnapshot(errorMessage(er, unloadedNpm))
- t.end()
+ t.matchSnapshot(errorMessage(er, npm))
})
-t.test('enoent without a file', t => {
+t.test('enoent without a file', async t => {
+ const npm = await loadMockNpm(t)
const path = '/some/path'
const pkgid = 'some@package'
const stack = 'dummy stack trace'
@@ -169,11 +133,10 @@ t.test('enoent without a file', t => {
stack,
})
t.matchSnapshot(errorMessage(er, npm))
- t.end()
})
-t.test('enolock without a command', t => {
- npm.command = null
+t.test('enolock without a command', async t => {
+ const npm = await loadMockNpm(t, { command: null })
const path = '/some/path'
const pkgid = 'some@package'
const file = '/some/file'
@@ -186,12 +149,12 @@ t.test('enolock without a command', t => {
stack,
})
t.matchSnapshot(errorMessage(er, npm))
- t.end()
})
-t.test('default message', t => {
+t.test('default message', async t => {
+ const npm = await loadMockNpm(t)
t.matchSnapshot(errorMessage(new Error('error object'), npm))
- t.matchSnapshot(errorMessage('error string'), npm)
+ t.matchSnapshot(errorMessage('error string', npm))
t.matchSnapshot(errorMessage(Object.assign(new Error('cmd err'), {
cmd: 'some command',
signal: 'SIGYOLO',
@@ -199,10 +162,10 @@ t.test('default message', t => {
stdout: 'stdout',
stderr: 'stderr',
}), npm))
- t.end()
})
-t.test('args are cleaned', t => {
+t.test('args are cleaned', async t => {
+ const npm = await loadMockNpm(t)
t.matchSnapshot(errorMessage(Object.assign(new Error('cmd err'), {
cmd: 'some command',
signal: 'SIGYOLO',
@@ -210,35 +173,25 @@ t.test('args are cleaned', t => {
stdout: 'stdout',
stderr: 'stderr',
}), npm))
- t.end()
})
-t.test('eacces/eperm', t => {
- const runTest = (windows, loaded, cachePath, cacheDest) => t => {
+t.test('eacces/eperm', async t => {
+ const runTest = (windows, loaded, cachePath, cacheDest) => async t => {
if (windows) {
- beWindows()
- } else {
- bePosix()
+ mockGlobals(t, { 'process.platform': 'win32' })
}
-
- const path = `${cachePath ? CACHE : '/not/cache/dir'}/path`
- const dest = `${cacheDest ? CACHE : '/not/cache/dir'}/dest`
+ const npm = await loadMockNpm(t, { windows, load: loaded })
+ const path = `${cachePath ? npm.cache : '/not/cache/dir'}/path`
+ const dest = `${cacheDest ? npm.cache : '/not/cache/dir'}/dest`
const er = Object.assign(new Error('whoopsie'), {
code: 'EACCES',
path,
dest,
stack: 'dummy stack trace',
})
- verboseLogs.length = 0
- if (loaded) {
- t.matchSnapshot(errorMessage(er, npm))
- } else {
- t.matchSnapshot(errorMessage(er, unloadedNpm))
- }
- t.matchSnapshot(verboseLogs)
- t.end()
- verboseLogs.length = 0
+ t.matchSnapshot(errorMessage(er, npm))
+ t.matchSnapshot(npm.logs.verbose)
}
for (const windows of [true, false]) {
@@ -251,12 +204,13 @@ t.test('eacces/eperm', t => {
}
}
}
- t.end()
})
t.test('json parse', t => {
- t.test('merge conflict in package.json', t => {
- const dir = t.testdir({
+ mockGlobals(t, { 'process.argv': ['arg', 'v'] })
+
+ t.test('merge conflict in package.json', async t => {
+ const testdir = {
'package.json': `
{
"array": [
@@ -295,59 +249,35 @@ t.test('json parse', t => {
}
}
`,
- })
- const { prefix } = npm
- const { argv } = process
- t.teardown(() => {
- Object.defineProperty(npm, 'prefix', {
- value: prefix,
- configurable: true,
- })
- process.argv = argv
- })
- Object.defineProperty(npm, 'prefix', { value: dir, configurable: true })
- process.argv = ['arg', 'v']
+ }
+ const npm = await loadMockNpm(t, { testdir })
t.matchSnapshot(errorMessage(Object.assign(new Error('conflicted'), {
code: 'EJSONPARSE',
- path: resolve(dir, 'package.json'),
+ path: path.resolve(npm.prefix, 'package.json'),
}), npm))
t.end()
})
- t.test('just regular bad json in package.json', t => {
- const dir = t.testdir({
+ t.test('just regular bad json in package.json', async t => {
+ const testdir = {
'package.json': 'not even slightly json',
- })
- const { prefix } = npm
- const { argv } = process
- t.teardown(() => {
- Object.defineProperty(npm, 'prefix', {
- value: prefix,
- configurable: true,
- })
- process.argv = argv
- })
- Object.defineProperty(npm, 'prefix', { value: dir, configurable: true })
- process.argv = ['arg', 'v']
+ }
+ const npm = await loadMockNpm(t, { testdir })
t.matchSnapshot(errorMessage(Object.assign(new Error('not json'), {
code: 'EJSONPARSE',
- path: resolve(dir, 'package.json'),
+ path: path.resolve(npm.prefix, 'package.json'),
}), npm))
t.end()
})
- t.test('json somewhere else', t => {
- const dir = t.testdir({
+ t.test('json somewhere else', async t => {
+ const testdir = {
'blerg.json': 'not even slightly json',
- })
- const { argv } = process
- t.teardown(() => {
- process.argv = argv
- })
- process.argv = ['arg', 'v']
+ }
+ const npm = await loadMockNpm(t, { testdir })
t.matchSnapshot(errorMessage(Object.assign(new Error('not json'), {
code: 'EJSONPARSE',
- path: `${dir}/blerg.json`,
+ path: path.resolve(npm.prefix, 'blerg.json'),
}), npm))
t.end()
})
@@ -355,7 +285,9 @@ t.test('json parse', t => {
t.end()
})
-t.test('eotp/e401', t => {
+t.test('eotp/e401', async t => {
+ const npm = await loadMockNpm(t)
+
t.test('401, no auth headers', t => {
t.matchSnapshot(errorMessage(Object.assign(new Error('nope'), {
code: 'E401',
@@ -406,11 +338,11 @@ t.test('eotp/e401', t => {
})
}
})
-
- t.end()
})
-t.test('404', t => {
+t.test('404', async t => {
+ const npm = await loadMockNpm(t)
+
t.test('no package id', t => {
const er = Object.assign(new Error('404 not found'), { code: 'E404' })
t.matchSnapshot(errorMessage(er, npm))
@@ -448,10 +380,11 @@ t.test('404', t => {
t.matchSnapshot(errorMessage(er, npm))
t.end()
})
- t.end()
})
-t.test('bad platform', t => {
+t.test('bad platform', async t => {
+ const npm = await loadMockNpm(t)
+
t.test('string os/arch', t => {
const er = Object.assign(new Error('a bad plat'), {
pkgid: 'lodash@1.0.0',
@@ -484,19 +417,30 @@ t.test('bad platform', t => {
t.matchSnapshot(errorMessage(er, npm))
t.end()
})
-
- t.end()
})
-t.test('explain ERESOLVE errors', t => {
+t.test('explain ERESOLVE errors', async t => {
+ const npm = await loadMockNpm(t)
+ const EXPLAIN_CALLED = []
+
const er = Object.assign(new Error('could not resolve'), {
code: 'ERESOLVE',
})
- t.matchSnapshot(errorMessage(er, npm))
+
+ t.matchSnapshot(errorMessage(er, {
+ ...npm,
+ mocks: {
+ '../../../lib/utils/explain-eresolve.js': {
+ report: (...args) => {
+ EXPLAIN_CALLED.push(args)
+ return 'explanation'
+ },
+ },
+ },
+ }))
t.match(EXPLAIN_CALLED, [[
er,
- undefined,
+ false,
path.resolve(npm.cache, 'eresolve-report.txt'),
]])
- t.end()
})
diff --git a/deps/npm/test/lib/utils/exit-handler.js b/deps/npm/test/lib/utils/exit-handler.js
index adc7c3f4e90fd3..54bf48f89b0dd4 100644
--- a/deps/npm/test/lib/utils/exit-handler.js
+++ b/deps/npm/test/lib/utils/exit-handler.js
@@ -1,177 +1,213 @@
-/* eslint-disable no-extend-native */
-/* eslint-disable no-global-assign */
const t = require('tap')
-const EventEmitter = require('events')
const os = require('os')
-const fs = require('fs')
-const path = require('path')
-
-const { real: mockNpm } = require('../../fixtures/mock-npm')
-
-// generic error to be used in tests
-const err = Object.assign(new Error('ERROR'), { code: 'ERROR' })
-err.stack = 'Error: ERROR'
-
-const redactCwd = (path) => {
- const normalizePath = p => p
- .replace(/\\+/g, '/')
- .replace(/\r\n/g, '\n')
- return normalizePath(path)
- .replace(new RegExp(normalizePath(process.cwd()), 'g'), '{CWD}')
+const EventEmitter = require('events')
+const { format } = require('../../../lib/utils/log-file')
+const { load: loadMockNpm } = require('../../fixtures/mock-npm')
+const mockGlobals = require('../../fixtures/mock-globals')
+const { cleanCwd, cleanDate } = require('../../fixtures/clean-snapshot')
+
+const pick = (obj, ...keys) => keys.reduce((acc, key) => {
+ acc[key] = obj[key]
+ return acc
+}, {})
+
+t.formatSnapshot = (obj) => {
+ if (Array.isArray(obj)) {
+ return obj
+ .map((i) => Array.isArray(i) ? i.join(' ') : i)
+ .join('\n')
+ }
+ return obj
}
-t.cleanSnapshot = (str) => redactCwd(str)
-
-const cacheFolder = t.testdir({})
-const logFile = path.resolve(cacheFolder, '_logs', 'expecteddate-debug.log')
-const timingFile = path.resolve(cacheFolder, '_timing.json')
-
-const { Npm } = mockNpm(t, {
- '../../package.json': {
- version: '1.0.0',
- },
-})
-const npm = new Npm()
-
-t.before(async () => {
- await npm.load()
- npm.config.set('cache', cacheFolder)
-})
+t.cleanSnapshot = (path) => cleanDate(cleanCwd(path))
+// Config loading is dependent on env so strip those from snapshots
+ .replace(/.*timing config:load:.*\n/gm, '')
+ .replace(/(Completed in )\d+(ms)/g, '$1{TIME}$2')
// cut off process from script so that it won't quit the test runner
// while trying to run through the myriad of cases. need to make it
// have all the functions signal-exit relies on so that it doesn't
// nerf itself, thinking global.process is broken or gone.
-const _process = process
-process = Object.assign(
- new EventEmitter(),
- {
- argv: ['/node', ..._process.argv.slice(1)],
- cwd: _process.cwd,
- env: _process.env,
+mockGlobals(t, {
+ process: Object.assign(new EventEmitter(), {
+ ...pick(process, 'execPath', 'stdout', 'stderr', 'cwd', 'env'),
+ argv: ['/node', ...process.argv.slice(1)],
version: 'v1.0.0',
+ kill: () => {},
+ reallyExit: (code) => process.exit(code),
+ pid: 123456,
exit: (code) => {
process.exitCode = code || process.exitCode || 0
process.emit('exit', process.exitCode)
},
- stdout: { write (_, cb) {
- cb()
- } },
- stderr: { write () {} },
- hrtime: _process.hrtime,
- kill: () => {},
- reallyExit: (code) => process.exit(code),
- pid: 123456,
+ }),
+}, { replace: true })
+
+const mockExitHandler = async (t, { init, load, testdir, config } = {}) => {
+ const errors = []
+ mockGlobals(t, { 'console.error': (err) => errors.push(err) })
+
+ const { npm, logMocks, ...rest } = await loadMockNpm(t, {
+ init,
+ load,
+ testdir,
+ mocks: {
+ '../../package.json': {
+ version: '1.0.0',
+ },
+ },
+ config: {
+ loglevel: 'notice',
+ ...config,
+ },
+ })
+
+ const exitHandler = t.mock('../../../lib/utils/exit-handler.js', {
+ '../../../lib/utils/error-message.js': (err) => ({
+ ...err,
+ summary: [['ERR SUMMARY', err.message]],
+ detail: [['ERR DETAIL', err.message]],
+ }),
+ os: {
+ type: () => 'Foo',
+ release: () => '1.0.0',
+ },
+ ...logMocks,
+ })
+
+ if (npm) {
+ exitHandler.setNpm(npm)
}
-)
-
-const osType = os.type
-const osRelease = os.release
-// overrides OS type/release for cross platform snapshots
-os.type = () => 'Foo'
-os.release = () => '1.0.0'
-
-// generates logfile name with mocked date
-const _toISOString = Date.prototype.toISOString
-Date.prototype.toISOString = () => 'expecteddate'
-
-const consoleError = console.error
-const errors = []
-console.error = (err) => {
- errors.push(err)
-}
-t.teardown(() => {
- os.type = osType
- os.release = osRelease
- // needs to put process back in its place in order for tap to exit properly
- process = _process
- Date.prototype.toISOString = _toISOString
- console.error = consoleError
-})
-t.afterEach(() => {
- errors.length = 0
- npm.log.level = 'silent'
- // clear out the 'A complete log' message
- npm.log.record.length = 0
- delete process.exitCode
-})
+ t.teardown(() => {
+ delete process.exitCode
+ process.removeAllListeners('exit')
+ })
-const mocks = {
- '../../../lib/utils/error-message.js': (err) => ({
- ...err,
- summary: [['ERR', err.message]],
- detail: [['ERR', err.message]],
- }),
+ return {
+ ...rest,
+ 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
+ exitHandler: (...args) => new Promise(resolve => {
+ process.once('exit', resolve)
+ exitHandler(...args)
+ }),
+ }
}
-const exitHandler = t.mock('../../../lib/utils/exit-handler.js', mocks)
-exitHandler.setNpm(npm)
-
-t.test('exit handler never called - loglevel silent', (t) => {
- npm.log.level = 'silent'
- process.emit('exit', 1)
- const logData = fs.readFileSync(logFile, 'utf8')
- t.match(logData, 'Exit handler never called!')
- t.match(errors, [''], 'logs one empty string to console.error')
- t.end()
-})
+// Create errors with properties to be used in tests
+const err = (message = '', options = {}, noStack = false) => {
+ const e = Object.assign(
+ new Error(message),
+ typeof options !== 'object' ? { code: options } : options
+ )
+ e.stack = options.stack || `Error: ${message}`
+ if (noStack) {
+ delete e.stack
+ }
+ return e
+}
-t.test('exit handler never called - loglevel notice', (t) => {
- npm.log.level = 'notice'
- process.emit('exit', 1)
- const logData = fs.readFileSync(logFile, 'utf8')
- t.match(logData, 'Exit handler never called!')
- t.match(errors, ['', ''], 'logs two empty strings to console.error')
- t.end()
-})
+t.test('handles unknown error with logs and debug file', async (t) => {
+ const { exitHandler, debugFile, logs } = await mockExitHandler(t)
-t.test('handles unknown error', (t) => {
- t.plan(2)
+ await exitHandler(err('Unknown error', 'ECODE'))
- npm.log.level = 'notice'
+ const debugContent = await debugFile()
- process.once('timeEnd', (msg) => {
- t.equal(msg, 'npm', 'should trigger timeEnd for npm')
+ t.equal(process.exitCode, 1)
+ logs.forEach((logItem, i) => {
+ const logLines = format(i, ...logItem).trim().split(os.EOL)
+ logLines.forEach((line) => {
+ t.match(debugContent.trim(), line, 'log appears in debug file')
+ })
})
- exitHandler(err)
- const logData = fs.readFileSync(logFile, 'utf8')
- t.matchSnapshot(
- logData,
- 'should have expected log contents for unknown error'
- )
- t.end()
+ const lastLog = debugContent
+ .split('\n')
+ .reduce((__, l) => parseInt(l.match(/^(\d+)\s/)[1]))
+ t.equal(logs.length, lastLog + 1)
+ t.match(logs.error, [
+ ['code', 'ECODE'],
+ ['ERR SUMMARY', 'Unknown error'],
+ ['ERR DETAIL', 'Unknown error'],
+ ])
+ t.match(debugContent, /\d+ error code ECODE/)
+ t.match(debugContent, /\d+ error ERR SUMMARY Unknown error/)
+ t.match(debugContent, /\d+ error ERR DETAIL Unknown error/)
+ t.matchSnapshot(logs, 'logs')
+ t.matchSnapshot(debugContent, 'debug file contents')
})
-t.test('fail to write logfile', (t) => {
- t.plan(1)
-
- t.teardown(() => {
- npm.config.set('cache', cacheFolder)
+t.test('exit handler never called - loglevel silent', async (t) => {
+ const { logs, errors } = await mockExitHandler(t, {
+ config: { loglevel: 'silent' },
})
+ process.emit('exit', 1)
+ t.match(logs.error, [
+ ['', /Exit handler never called/],
+ ['', /error with npm itself/],
+ ])
+ t.strictSame(errors, [''], 'logs one empty string to console.error')
+})
- const badDir = t.testdir({
- _logs: 'is a file',
- })
+t.test('exit handler never called - loglevel notice', async (t) => {
+ const { logs, errors } = await mockExitHandler(t)
+ process.emit('exit', 1)
+ t.equal(process.exitCode, 1)
+ t.match(logs.error, [
+ ['', /Exit handler never called/],
+ ['', /error with npm itself/],
+ ])
+ t.strictSame(errors, ['', ''], 'logs two empty strings to console.error')
+})
+
+t.test('exit handler never called - no npm', async (t) => {
+ const { logs, errors } = await mockExitHandler(t, { init: false })
+ process.emit('exit', 1)
+ t.equal(process.exitCode, 1)
+ t.match(logs.error, [
+ ['', /Exit handler never called/],
+ ['', /error with npm itself/],
+ ])
+ t.strictSame(errors, [''], 'logs one empty string to console.error')
+})
- npm.config.set('cache', badDir)
+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.doesNotThrow(
- () => exitHandler(err),
- 'should not throw on cache write failure'
- )
+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.test('console.log output using --json', (t) => {
- t.plan(1)
+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/])
+})
- npm.config.set('json', true)
- t.teardown(() => {
- npm.config.set('json', false)
+t.test('console.log output using --json', async (t) => {
+ const { exitHandler, errors } = await mockExitHandler(t, {
+ config: {
+ json: true,
+ },
})
- exitHandler(new Error('Error: EBADTHING Something happened'))
+ await exitHandler(err('Error: EBADTHING Something happened'))
+
+ t.equal(process.exitCode, 1)
t.same(
JSON.parse(errors[0]),
{
@@ -185,213 +221,223 @@ t.test('console.log output using --json', (t) => {
)
})
-t.test('throw a non-error obj', (t) => {
- t.plan(2)
+t.test('throw a non-error obj', async (t) => {
+ const { exitHandler, logs } = await mockExitHandler(t)
- const weirdError = {
+ await exitHandler({
code: 'ESOMETHING',
message: 'foo bar',
- }
-
- process.once('exit', code => {
- t.equal(code, 1, 'exits with exitCode 1')
})
- exitHandler(weirdError)
- t.match(
- npm.log.record.find(r => r.level === 'error'),
- { message: 'foo bar' }
- )
+
+ t.equal(process.exitCode, 1)
+ t.match(logs.error, [
+ ['weird error', { code: 'ESOMETHING', message: 'foo bar' }],
+ ])
})
-t.test('throw a string error', (t) => {
- t.plan(2)
- const error = 'foo bar'
+t.test('throw a string error', async (t) => {
+ const { exitHandler, logs } = await mockExitHandler(t)
- process.once('exit', code => {
- t.equal(code, 1, 'exits with exitCode 1')
- })
- exitHandler(error)
- t.match(
- npm.log.record.find(r => r.level === 'error'),
- { message: 'foo bar' }
- )
+ await exitHandler('foo bar')
+
+ t.equal(process.exitCode, 1)
+ t.match(logs.error, [
+ ['', 'foo bar'],
+ ])
})
-t.test('update notification', (t) => {
- const updateMsg = 'you should update npm!'
- npm.updateNotification = updateMsg
- npm.log.level = 'silent'
+t.test('update notification', async (t) => {
+ const { exitHandler, logs, npm } = await mockExitHandler(t)
+ npm.updateNotification = 'you should update npm!'
- t.teardown(() => {
- delete npm.updateNotification
- })
+ await exitHandler()
- exitHandler()
- t.match(
- npm.log.record.find(r => r.level === 'notice'),
- { message: 'you should update npm!' }
- )
- t.end()
+ t.match(logs.notice, [
+ ['', 'you should update npm!'],
+ ])
})
-t.test('npm.config not ready', (t) => {
- t.plan(1)
+t.test('npm.config not ready', async (t) => {
+ const { exitHandler, logs, errors } = await mockExitHandler(t, {
+ load: false,
+ })
- const { Npm: Unloaded } = mockNpm(t)
- const unloaded = new Unloaded()
+ await exitHandler()
- t.teardown(() => {
- exitHandler.setNpm(npm)
+ t.equal(process.exitCode, 1)
+ t.match(errors, [
+ /Error: Exit prior to config file resolving./,
+ ], 'should exit with config error msg')
+ t.match(logs.verbose, [
+ ['stack', /Error: Exit prior to config file resolving./],
+ ], 'should exit with config error msg')
+})
+
+t.test('timing with no error', async (t) => {
+ const { exitHandler, timingFile, npm, logs } = await mockExitHandler(t, {
+ config: {
+ timing: true,
+ },
})
- exitHandler.setNpm(unloaded)
+ await exitHandler()
+ const timingFileData = await timingFile()
+
+ t.equal(process.exitCode, 0)
+
+ t.match(logs.error, [
+ ['', /A complete log of this run can be found in:[\s\S]*-debug-\d\.log/],
+ ])
- exitHandler()
t.match(
- errors[0],
- /Error: Exit prior to config file resolving./,
- 'should exit with config error msg'
+ timingFileData,
+ Object.keys(npm.finishedTimers).reduce((acc, k) => {
+ acc[k] = Number
+ return acc
+ }, {})
)
- t.end()
+ t.strictSame(npm.unfinishedTimers, new Map())
+ t.match(timingFileData, {
+ command: [],
+ version: '1.0.0',
+ npm: Number,
+ logfile: String,
+ logfiles: [String],
+ })
})
-t.test('timing', (t) => {
- npm.config.set('timing', true)
-
- t.teardown(() => {
- fs.unlinkSync(timingFile)
- npm.config.set('timing', false)
+t.test('unfinished timers', async (t) => {
+ const { exitHandler, timingFile, npm } = await mockExitHandler(t, {
+ config: {
+ timing: true,
+ },
})
- exitHandler()
- const timingData = JSON.parse(fs.readFileSync(timingFile, 'utf8'))
- t.match(timingData, { version: '1.0.0', 'config:load:defaults': Number })
- t.end()
-})
+ process.emit('time', 'foo')
+ process.emit('time', 'bar')
-t.test('timing - with error', (t) => {
- npm.config.set('timing', true)
+ await exitHandler()
+ const timingFileData = await timingFile()
- t.teardown(() => {
- fs.unlinkSync(timingFile)
- npm.config.set('timing', false)
+ t.equal(process.exitCode, 0)
+ t.match(npm.unfinishedTimers, new Map([['foo', Number], ['bar', Number]]))
+ t.match(timingFileData, {
+ command: [],
+ version: '1.0.0',
+ npm: Number,
+ logfile: String,
+ logfiles: [String],
+ unfinished: {
+ foo: [Number, Number],
+ bar: [Number, Number],
+ },
})
-
- exitHandler(err)
- const timingData = JSON.parse(fs.readFileSync(timingFile, 'utf8'))
- t.match(timingData, { version: '1.0.0', 'config:load:defaults': Number })
- t.end()
})
-t.test('uses code from errno', (t) => {
- t.plan(1)
+t.test('uses code from errno', async (t) => {
+ const { exitHandler, logs } = await mockExitHandler(t)
- process.once('exit', code => {
- t.equal(code, 127, 'should set exitCode from errno')
- })
- exitHandler(Object.assign(
- new Error('Error with errno'),
- {
- errno: 127,
- }
- ))
+ await exitHandler(err('Error with errno', { errno: 127 }))
+ t.equal(process.exitCode, 127)
+ t.match(logs.error, [['errno', 127]])
})
-t.test('uses code from number', (t) => {
- t.plan(1)
+t.test('uses code from number', async (t) => {
+ const { exitHandler, logs } = await mockExitHandler(t)
- process.once('exit', code => {
- t.equal(code, 404, 'should set exitCode from a number')
- })
- exitHandler(Object.assign(
- new Error('Error with code type number'),
- {
- code: 404,
- }
- ))
+ await exitHandler(err('Error with code type number', 404))
+ t.equal(process.exitCode, 404)
+ t.match(logs.error, [['code', 404]])
})
-t.test('call exitHandler with no error', (t) => {
- t.plan(1)
- process.once('exit', code => {
- t.equal(code, 0, 'should end up with exitCode 0 (default)')
- })
- exitHandler()
+t.test('uses all err special properties', async t => {
+ const { exitHandler, logs } = await mockExitHandler(t)
+
+ const keys = ['code', 'syscall', 'file', 'path', 'dest', 'errno']
+ const properties = keys.reduce((acc, k) => {
+ acc[k] = `${k}-hey`
+ return acc
+ }, {})
+
+ await exitHandler(err('Error with code type number', properties))
+ t.equal(process.exitCode, 1)
+ t.match(logs.error, keys.map((k) => [k, `${k}-hey`]), 'all special keys get logged')
})
-t.test('defaults to log error msg if stack is missing', (t) => {
- const { Npm: Unloaded } = mockNpm(t)
- const unloaded = new Unloaded()
+t.test('verbose logs replace info on err props', async t => {
+ const { exitHandler, logs } = await mockExitHandler(t)
- t.teardown(() => {
- exitHandler.setNpm(npm)
- })
+ const keys = ['type', 'stack', 'statusCode', 'pkgid']
+ const properties = keys.reduce((acc, k) => {
+ acc[k] = `${k}-https://user:pass@registry.npmjs.org/`
+ return acc
+ }, {})
- exitHandler.setNpm(unloaded)
- const noStackErr = Object.assign(
- new Error('Error with no stack'),
- {
- code: 'ENOSTACK',
- errno: 127,
- }
+ await exitHandler(err('Error with code type number', properties))
+ t.equal(process.exitCode, 1)
+ t.match(
+ logs.verbose.filter(([p]) => p !== 'logfile'),
+ keys.map((k) => [k, `${k}-https://user:***@registry.npmjs.org/`]),
+ 'all special keys get replaced'
)
- delete noStackErr.stack
+})
- exitHandler(noStackErr)
- t.equal(errors[0], 'Error with no stack', 'should use error msg')
- t.end()
+t.test('call exitHandler with no error', async (t) => {
+ const { exitHandler, logs } = await mockExitHandler(t)
+
+ await exitHandler()
+
+ t.equal(process.exitCode, 0)
+ t.match(logs.error, [])
+})
+
+t.test('defaults to log error msg if stack is missing when unloaded', async (t) => {
+ const { exitHandler, logs, errors } = await mockExitHandler(t, { load: false })
+
+ 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.match(logs.error, [
+ ['code', 'ENOSTACK'],
+ ['errno', 127],
+ ])
})
-t.test('exits uncleanly when only emitting exit event', (t) => {
- t.plan(2)
+t.test('exits uncleanly when only emitting exit event', async (t) => {
+ const { logs } = await mockExitHandler(t)
- npm.log.level = 'silent'
process.emit('exit')
- const logData = fs.readFileSync(logFile, 'utf8')
- t.match(logData, 'Exit handler never called!')
- t.match(process.exitCode, 1, 'exitCode coerced to 1')
+
+ t.match(logs.error, [['', 'Exit handler never called!']])
+ t.equal(process.exitCode, 1, 'exitCode coerced to 1')
t.end()
})
-t.test('do no fancy handling for shellouts', t => {
- const { command } = npm
- const LOG_RECORD = []
- npm.command = 'exec'
+t.test('do no fancy handling for shellouts', async t => {
+ const { exitHandler, npm, logs } = await mockExitHandler(t)
- t.teardown(() => {
- npm.command = command
- })
- t.beforeEach(() => LOG_RECORD.length = 0)
+ npm.command = 'exec'
- const loudNoises = () => npm.log.record
- .filter(({ level }) => ['warn', 'error'].includes(level))
+ const loudNoises = () =>
+ logs.filter(([level]) => ['warn', 'error'].includes(level))
- t.test('shellout with a numeric error code', t => {
- t.plan(2)
- process.once('exit', code => {
- t.equal(code, 5, 'got expected exit code')
- })
- exitHandler(Object.assign(new Error(), { code: 5 }))
+ t.test('shellout with a numeric error code', async t => {
+ await exitHandler(err('', 5))
+ t.equal(process.exitCode, 5, 'got expected exit code')
t.strictSame(loudNoises(), [], 'no noisy warnings')
})
- t.test('shellout without a numeric error code (something in npm)', t => {
- t.plan(2)
- process.once('exit', code => {
- t.equal(code, 1, 'got expected exit code')
- })
- exitHandler(Object.assign(new Error(), { code: 'banana stand' }))
+ t.test('shellout without a numeric error code (something in npm)', async 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(loudNoises(), [], 'bring the noise')
t.end()
})
- t.test('shellout with code=0 (extra weird?)', t => {
- t.plan(2)
- process.once('exit', code => {
- t.equal(code, 1, 'got expected exit code')
- })
- exitHandler(Object.assign(new Error(), { code: 0 }))
+ t.test('shellout with code=0 (extra weird?)', async t => {
+ await exitHandler(Object.assign(new Error(), { code: 0 }))
+ t.equal(process.exitCode, 1, 'got expected exit code')
t.strictNotSame(loudNoises(), [], 'bring the noise')
})
diff --git a/deps/npm/test/lib/utils/get-project-scope.js b/deps/npm/test/lib/utils/get-project-scope.js
deleted file mode 100644
index 9737b06433c227..00000000000000
--- a/deps/npm/test/lib/utils/get-project-scope.js
+++ /dev/null
@@ -1,48 +0,0 @@
-const getProjectScope = require('../../../lib/utils/get-project-scope.js')
-const t = require('tap')
-
-t.test('package.json with scope', t => {
- const dir = t.testdir({
- 'package.json': JSON.stringify({ name: '@foo/bar' }),
- })
- t.equal(getProjectScope(dir), '@foo')
- t.end()
-})
-
-t.test('package.json with slash, but no @', t => {
- const dir = t.testdir({
- 'package.json': JSON.stringify({ name: 'foo/bar' }),
- })
- t.equal(getProjectScope(dir), '')
- t.end()
-})
-
-t.test('package.json without scope', t => {
- const dir = t.testdir({
- 'package.json': JSON.stringify({ name: 'foo' }),
- })
- t.equal(getProjectScope(dir), '')
- t.end()
-})
-
-t.test('package.json without name', t => {
- const dir = t.testdir({
- 'package.json': JSON.stringify({}),
- })
- t.equal(getProjectScope(dir), '')
- t.end()
-})
-
-t.test('package.json not JSON', t => {
- const dir = t.testdir({
- 'package.json': 'hello',
- })
- t.equal(getProjectScope(dir), '')
- t.end()
-})
-
-t.test('no package.json', t => {
- const dir = t.testdir({})
- t.equal(getProjectScope(dir), '')
- t.end()
-})
diff --git a/deps/npm/test/lib/utils/is-windows-bash.js b/deps/npm/test/lib/utils/is-windows-bash.js
index 94fde0ace17ce4..0fbebdf8e3d534 100644
--- a/deps/npm/test/lib/utils/is-windows-bash.js
+++ b/deps/npm/test/lib/utils/is-windows-bash.js
@@ -1,4 +1,5 @@
const t = require('tap')
+const mockGlobal = require('../../fixtures/mock-globals.js')
const isWindowsBash = () => {
delete require.cache[require.resolve('../../../lib/utils/is-windows-bash.js')]
@@ -6,23 +7,24 @@ const isWindowsBash = () => {
return require('../../../lib/utils/is-windows-bash.js')
}
-Object.defineProperty(process, 'platform', {
- value: 'posix',
- configurable: true,
-})
-t.equal(isWindowsBash(), false, 'false when not windows')
+t.test('posix', (t) => {
+ mockGlobal(t, { 'process.platform': 'posix' })
+ t.equal(isWindowsBash(), false, 'false when not windows')
-Object.defineProperty(process, 'platform', {
- value: 'win32',
- configurable: true,
+ t.end()
})
-process.env.MSYSTEM = 'not ming'
-process.env.TERM = 'dumb'
-t.equal(isWindowsBash(), false, 'false when not mingw or cygwin')
-process.env.TERM = 'cygwin'
-t.equal(isWindowsBash(), true, 'true when cygwin')
+t.test('win32', (t) => {
+ mockGlobal(t, { 'process.platform': 'win32' })
+
+ mockGlobal(t, { 'process.env': { TERM: 'dumb', MSYSTEM: undefined } })
+ t.equal(isWindowsBash(), false, 'false when not mingw or cygwin')
+
+ mockGlobal(t, { 'process.env.TERM': 'cygwin' })
+ t.equal(isWindowsBash(), true, 'true when cygwin')
-process.env.MSYSTEM = 'MINGW64'
-process.env.TERM = 'dumb'
-t.equal(isWindowsBash(), true, 'true when mingw')
+ mockGlobal(t, { 'process.env': { TERM: 'dumb', MSYSTEM: 'MINGW64' } })
+ t.equal(isWindowsBash(), true, 'true when mingw')
+
+ t.end()
+})
diff --git a/deps/npm/test/lib/utils/log-file.js b/deps/npm/test/lib/utils/log-file.js
new file mode 100644
index 00000000000000..adc1a2e03ff3d8
--- /dev/null
+++ b/deps/npm/test/lib/utils/log-file.js
@@ -0,0 +1,333 @@
+const t = require('tap')
+const _fs = require('fs')
+const fs = _fs.promises
+const path = require('path')
+const os = require('os')
+const fsMiniPass = require('fs-minipass')
+const rimraf = require('rimraf')
+const LogFile = require('../../../lib/utils/log-file.js')
+const { cleanCwd } = require('../../fixtures/clean-snapshot')
+
+t.cleanSnapshot = (path) => cleanCwd(path)
+
+const last = arr => arr[arr.length - 1]
+const range = (n) => Array.from(Array(n).keys())
+const makeOldLogs = (count) => {
+ const d = new Date()
+ d.setHours(-1)
+ d.setSeconds(0)
+ return range(count / 2).reduce((acc, i) => {
+ const cloneDate = new Date(d.getTime())
+ cloneDate.setSeconds(i)
+ acc[LogFile.fileName(LogFile.logId(cloneDate), 0)] = 'hello'
+ acc[LogFile.fileName(LogFile.logId(cloneDate), 1)] = 'hello'
+ return acc
+ }, {})
+}
+
+const cleanErr = (message) => {
+ const err = new Error(message)
+ const stack = err.stack.split('\n')
+ err.stack = stack[0] + '\n' + range(10)
+ .map((__, i) => stack[1].replace(/^(\s+at\s).*/, `$1stack trace line ${i}`))
+ .join('\n')
+ return err
+}
+
+const loadLogFile = async (t, { buffer = [], mocks, testdir = {}, ...options } = {}) => {
+ const root = t.testdir(testdir)
+ const MockLogFile = t.mock('../../../lib/utils/log-file.js', mocks)
+ const logFile = new MockLogFile(Object.keys(options).length ? options : undefined)
+ buffer.forEach((b) => logFile.log(...b))
+ await logFile.load({ dir: root, ...options })
+ t.teardown(() => logFile.off())
+ return {
+ root,
+ logFile,
+ LogFile,
+ readLogs: async () => {
+ const logDir = await fs.readdir(root)
+ const logFiles = logDir.map((f) => path.join(root, f))
+ .filter((f) => _fs.existsSync(f))
+ return Promise.all(logFiles.map(async (f) => {
+ const content = await fs.readFile(f, 'utf8')
+ const rawLogs = content.split(os.EOL)
+ return {
+ filename: f,
+ content,
+ rawLogs,
+ logs: rawLogs.filter(Boolean),
+ }
+ }))
+ },
+ }
+}
+
+t.test('init', async t => {
+ const maxLogsPerFile = 10
+ const { root, logFile, readLogs } = await loadLogFile(t, {
+ maxLogsPerFile,
+ maxFilesPerProcess: 20,
+ buffer: [['error', 'buffered']],
+ })
+
+ for (const i of range(50)) {
+ logFile.log('error', `log ${i}`)
+ }
+
+ // Ignored
+ logFile.log('pause')
+ logFile.log('resume')
+ logFile.log('pause')
+
+ for (const i of range(50)) {
+ logFile.log('verb', `log ${i}`)
+ }
+
+ logFile.off()
+ logFile.log('error', 'ignored')
+
+ const logs = await readLogs()
+ t.equal(logs.length, 11, 'total log files')
+ t.ok(logs.slice(0, 10).every(f => f.logs.length === maxLogsPerFile), 'max logs per file')
+ t.ok(last(logs).logs.length, 1, 'last file has remaining logs')
+ t.ok(logs.every(f => last(f.rawLogs) === ''), 'all logs end with newline')
+ t.strictSame(
+ logFile.files,
+ logs.map((l) => path.resolve(root, l.filename))
+ )
+})
+
+t.test('max files per process', async t => {
+ const maxLogsPerFile = 10
+ const maxFilesPerProcess = 5
+ const { logFile, readLogs } = await loadLogFile(t, {
+ maxLogsPerFile,
+ maxFilesPerProcess,
+ })
+
+ for (const i of range(maxLogsPerFile * maxFilesPerProcess)) {
+ logFile.log('error', `log ${i}`)
+ }
+
+ for (const i of range(5)) {
+ logFile.log('verbose', `log ${i}`)
+ }
+
+ const logs = await readLogs()
+ t.equal(logs.length, maxFilesPerProcess, 'total log files')
+ t.equal(last(last(logs).logs), '49 error log 49')
+})
+
+t.test('stream error', async t => {
+ let times = 0
+ const { logFile, readLogs } = await loadLogFile(t, {
+ maxLogsPerFile: 1,
+ maxFilesPerProcess: 99,
+ mocks: {
+ 'fs-minipass': {
+ WriteStreamSync: class {
+ constructor (...args) {
+ if (times >= 5) {
+ throw new Error('bad stream')
+ }
+ times++
+ return new fsMiniPass.WriteStreamSync(...args)
+ }
+ },
+ },
+ },
+ })
+
+ for (const i of range(10)) {
+ logFile.log('verbose', `log ${i}`)
+ }
+
+ const logs = await readLogs()
+ t.equal(logs.length, 5, 'total log files')
+})
+
+t.test('initial stream error', async t => {
+ const { logFile, readLogs } = await loadLogFile(t, {
+ mocks: {
+ 'fs-minipass': {
+ WriteStreamSync: class {
+ constructor (...args) {
+ throw new Error('no stream')
+ }
+ },
+ },
+ },
+ })
+
+ for (const i of range(10)) {
+ logFile.log('verbose', `log ${i}`)
+ }
+
+ const logs = await readLogs()
+ t.equal(logs.length, 0, 'total log files')
+})
+
+t.test('turns off', async t => {
+ const { logFile, readLogs } = await loadLogFile(t)
+
+ logFile.log('error', 'test')
+ logFile.off()
+ logFile.log('error', 'test2')
+ logFile.load()
+
+ const logs = await readLogs()
+ t.equal(logs.length, 1)
+ t.equal(logs[0].logs[0], '0 error test')
+})
+
+t.test('cleans logs', async t => {
+ const logsMax = 5
+ const { readLogs } = await loadLogFile(t, {
+ logsMax,
+ testdir: makeOldLogs(10),
+ })
+
+ const logs = await readLogs()
+ t.equal(logs.length, logsMax + 1)
+})
+
+t.test('doesnt clean current log by default', async t => {
+ const logsMax = 0
+ const { readLogs, logFile } = await loadLogFile(t, {
+ logsMax,
+ testdir: makeOldLogs(10),
+ })
+
+ logFile.log('error', 'test')
+
+ const logs = await readLogs()
+ t.equal(logs.length, 1)
+ t.match(last(logs).content, /\d+ error test/)
+})
+
+t.test('negative logs max', async t => {
+ const logsMax = -10
+ const { readLogs, logFile } = await loadLogFile(t, {
+ logsMax,
+ testdir: makeOldLogs(10),
+ })
+
+ logFile.log('error', 'test')
+
+ const logs = await readLogs()
+ t.equal(logs.length, 1)
+ t.match(last(logs).content, /\d+ error test/)
+})
+
+t.test('doesnt need to clean', async t => {
+ const logsMax = 20
+ const oldLogs = 10
+ const { readLogs } = await loadLogFile(t, {
+ logsMax,
+ testdir: makeOldLogs(oldLogs),
+ })
+
+ const logs = await readLogs()
+ t.equal(logs.length, oldLogs + 1)
+})
+
+t.test('glob error', async t => {
+ const { readLogs } = await loadLogFile(t, {
+ logsMax: 5,
+ mocks: {
+ glob: () => {
+ throw new Error('bad glob')
+ },
+ },
+ })
+
+ const logs = await readLogs()
+ t.equal(logs.length, 1)
+ t.match(last(logs).content, /error cleaning log files .* bad glob/)
+})
+
+t.test('rimraf error', async t => {
+ const logsMax = 5
+ const oldLogs = 10
+ let count = 0
+ const { readLogs } = await loadLogFile(t, {
+ logsMax,
+ testdir: makeOldLogs(oldLogs),
+ mocks: {
+ rimraf: (...args) => {
+ if (count >= 3) {
+ throw new Error('bad rimraf')
+ }
+ count++
+ return rimraf(...args)
+ },
+ },
+ })
+
+ const logs = await readLogs()
+ t.equal(logs.length, oldLogs - 3 + 1)
+ t.match(last(logs).content, /error removing log file .* bad rimraf/)
+})
+
+t.test('delete log file while open', async t => {
+ const { logFile, root, readLogs } = await loadLogFile(t)
+
+ logFile.log('error', '', 'log 1')
+ const [log] = await readLogs(true)
+ t.match(log.content, /\d+ error log 1/)
+
+ await fs.unlink(path.resolve(root, log.filename))
+
+ logFile.log('error', '', 'log 2')
+ const logs = await readLogs()
+
+ // XXX: do some retry logic after error?
+ t.strictSame(logs, [], 'logs arent written after error')
+})
+
+t.test('snapshot', async t => {
+ const { logFile, readLogs } = await loadLogFile(t)
+
+ logFile.log('error', '', 'no prefix')
+ logFile.log('error', 'prefix', 'with prefix')
+ logFile.log('error', 'prefix', 1, 2, 3)
+
+ const nestedObj = { obj: { with: { many: { props: 1 } } } }
+ logFile.log('verbose', '', nestedObj)
+ logFile.log('verbose', '', JSON.stringify(nestedObj))
+ logFile.log('verbose', '', JSON.stringify(nestedObj, null, 2))
+
+ const arr = ['test', 'with', 'an', 'array']
+ logFile.log('verbose', '', arr)
+ logFile.log('verbose', '', JSON.stringify(arr))
+ logFile.log('verbose', '', JSON.stringify(arr, null, 2))
+
+ const nestedArr = ['test', ['with', ['an', ['array']]]]
+ logFile.log('verbose', '', nestedArr)
+ logFile.log('verbose', '', JSON.stringify(nestedArr))
+ logFile.log('verbose', '', JSON.stringify(nestedArr, null, 2))
+
+ // XXX: multiple errors are hard to parse visually
+ // the second error should start on a newline
+ logFile.log(...[
+ 'error',
+ 'pre',
+ 'has',
+ 'many',
+ 'errors',
+ cleanErr('message'),
+ cleanErr('message2'),
+ ])
+
+ const err = new Error('message')
+ delete err.stack
+ logFile.log(...[
+ 'error',
+ 'nostack',
+ err,
+ ])
+
+ const logs = await readLogs()
+ t.matchSnapshot(logs.map(l => l.content).join('\n'))
+})
diff --git a/deps/npm/test/lib/utils/log-shim.js b/deps/npm/test/lib/utils/log-shim.js
new file mode 100644
index 00000000000000..dee4efbaa4552d
--- /dev/null
+++ b/deps/npm/test/lib/utils/log-shim.js
@@ -0,0 +1,100 @@
+const t = require('tap')
+
+const makeShim = (mocks) => t.mock('../../../lib/utils/log-shim.js', mocks)
+
+const loggers = [
+ 'notice',
+ 'error',
+ 'warn',
+ 'info',
+ 'verbose',
+ 'http',
+ 'silly',
+ 'pause',
+ 'resume',
+]
+
+t.test('has properties', (t) => {
+ const shim = makeShim()
+
+ t.match(shim, {
+ level: String,
+ levels: {},
+ gauge: {},
+ stream: {},
+ heading: undefined,
+ enableColor: Function,
+ disableColor: Function,
+ enableUnicode: Function,
+ disableUnicode: Function,
+ enableProgress: Function,
+ disableProgress: Function,
+ ...loggers.reduce((acc, l) => {
+ acc[l] = Function
+ return acc
+ }, {}),
+ })
+
+ t.match(Object.keys(shim).sort(), [
+ 'level',
+ 'heading',
+ 'levels',
+ 'gauge',
+ 'stream',
+ 'tracker',
+ 'useColor',
+ 'enableColor',
+ 'disableColor',
+ 'enableUnicode',
+ 'disableUnicode',
+ 'enableProgress',
+ 'disableProgress',
+ 'progressEnabled',
+ 'clearProgress',
+ 'showProgress',
+ 'newItem',
+ 'newGroup',
+ ...loggers,
+ ].sort())
+
+ t.end()
+})
+
+t.test('works with npmlog/proclog proxy', t => {
+ const procLog = { silly: () => 'SILLY' }
+ const npmlog = { level: 'woo', enableColor: () => true }
+ const shim = makeShim({ npmlog, 'proc-log': procLog })
+
+ t.equal(shim.level, 'woo', 'can get a property')
+
+ npmlog.level = 'hey'
+ t.strictSame(
+ [shim.level, npmlog.level],
+ ['hey', 'hey'],
+ 'can get a property after update on npmlog'
+ )
+
+ shim.level = 'test'
+ t.strictSame(
+ [shim.level, npmlog.level],
+ ['test', 'test'],
+ 'can get a property after update on shim'
+ )
+
+ t.ok(shim.enableColor(), 'can call method on shim to call npmlog')
+ t.equal(shim.silly(), 'SILLY', 'can call method on proclog')
+ t.notOk(shim.LEVELS, 'only includes levels from npmlog')
+ t.throws(() => shim.gauge = 100, 'cant set getters properies')
+
+ t.end()
+})
+
+t.test('works with npmlog/proclog proxy', t => {
+ const shim = makeShim()
+
+ loggers.forEach((k) => {
+ t.doesNotThrow(() => shim[k]('test'))
+ })
+
+ t.end()
+})
diff --git a/deps/npm/test/lib/utils/npm-usage.js b/deps/npm/test/lib/utils/npm-usage.js
index 77254a80d017da..035d4bbb21ef72 100644
--- a/deps/npm/test/lib/utils/npm-usage.js
+++ b/deps/npm/test/lib/utils/npm-usage.js
@@ -1,10 +1,8 @@
const t = require('tap')
-const { real: mockNpm } = require('../../fixtures/mock-npm.js')
-const { Npm } = mockNpm(t)
-const npm = new Npm()
+const { load: loadMockNpm } = require('../../fixtures/mock-npm.js')
t.test('usage', async t => {
- await npm.load()
+ const { npm } = await loadMockNpm(t)
t.afterEach(() => {
npm.config.set('viewer', null)
npm.config.set('long', false)
diff --git a/deps/npm/test/lib/utils/proc-log-listener.js b/deps/npm/test/lib/utils/proc-log-listener.js
deleted file mode 100644
index d580defa8a98f2..00000000000000
--- a/deps/npm/test/lib/utils/proc-log-listener.js
+++ /dev/null
@@ -1,41 +0,0 @@
-const t = require('tap')
-const { inspect } = require('util')
-
-const logs = []
-const npmlog = {
- warn: (...args) => logs.push(['warn', ...args]),
- verbose: (...args) => logs.push(['verbose', ...args]),
-}
-
-t.mock('../../../lib/utils/proc-log-listener.js', {
- npmlog,
-})()
-
-process.emit('log', 'warn', 'hello', 'i am a warning')
-t.strictSame(logs, [['warn', 'hello', 'i am a warning']])
-logs.length = 0
-
-const nopeError = new Error('nope')
-npmlog.warn = () => {
- throw nopeError
-}
-
-process.emit('log', 'warn', 'fail')
-t.strictSame(logs, [[
- 'verbose',
- `attempt to log ${inspect(['warn', 'fail'])} crashed`,
- nopeError,
-]])
-logs.length = 0
-
-npmlog.verbose = () => {
- throw nopeError
-}
-const consoleErrors = []
-console.error = (...args) => consoleErrors.push(args)
-process.emit('log', 'warn', 'fail2')
-t.strictSame(logs, [])
-t.strictSame(consoleErrors, [[
- `attempt to log ${inspect(['warn', 'fail2'])} crashed`,
- nopeError,
-]])
diff --git a/deps/npm/test/lib/utils/pulse-till-done.js b/deps/npm/test/lib/utils/pulse-till-done.js
index acbf66396a702c..9f7a94614d3bb5 100644
--- a/deps/npm/test/lib/utils/pulse-till-done.js
+++ b/deps/npm/test/lib/utils/pulse-till-done.js
@@ -1,18 +1,17 @@
const t = require('tap')
let pulseStarted = null
-const npmlog = {
- gauge: {
- pulse: () => {
- if (pulseStarted) {
- pulseStarted()
- }
- },
- },
-}
const pulseTillDone = t.mock('../../../lib/utils/pulse-till-done.js', {
- npmlog,
+ npmlog: {
+ gauge: {
+ pulse: () => {
+ if (pulseStarted) {
+ pulseStarted()
+ }
+ },
+ },
+ },
})
t.test('pulses (with promise)', async (t) => {
diff --git a/deps/npm/test/lib/utils/read-user-info.js b/deps/npm/test/lib/utils/read-user-info.js
index 35101f1d7029a8..be805a2a87c6a0 100644
--- a/deps/npm/test/lib/utils/read-user-info.js
+++ b/deps/npm/test/lib/utils/read-user-info.js
@@ -7,11 +7,6 @@ const read = (opts, cb) => {
return cb(null, readResult)
}
-const npmlog = {
- clearProgress: () => {},
- showProgress: () => {},
-}
-
const npmUserValidate = {
username: (username) => {
if (username === 'invalid') {
@@ -29,12 +24,23 @@ const npmUserValidate = {
},
}
+let logMsg = null
const readUserInfo = t.mock('../../../lib/utils/read-user-info.js', {
read,
- npmlog,
+ npmlog: {
+ clearProgress: () => {},
+ showProgress: () => {},
+ },
+ 'proc-log': {
+ warn: (msg) => logMsg = msg,
+ },
'npm-user-validate': npmUserValidate,
})
+t.beforeEach(() => {
+ logMsg = null
+})
+
t.test('otp', async (t) => {
readResult = '1234'
t.teardown(() => {
@@ -75,11 +81,7 @@ t.test('username - invalid warns and retries', async (t) => {
readOpts = null
})
- let logMsg
- const log = {
- warn: (msg) => logMsg = msg,
- }
- const pResult = readUserInfo.username(null, null, { log })
+ const pResult = readUserInfo.username(null, null)
// have to swap it to a valid username after execution starts
// or it will loop forever
readResult = 'valid'
@@ -105,11 +107,7 @@ t.test('email - invalid warns and retries', async (t) => {
readOpts = null
})
- let logMsg
- const log = {
- warn: (msg) => logMsg = msg,
- }
- const pResult = readUserInfo.email(null, null, { log })
+ const pResult = readUserInfo.email(null, null)
readResult = 'foo@bar.baz'
const result = await pResult
t.equal(result, 'foo@bar.baz', 'received the email')
diff --git a/deps/npm/test/lib/utils/reify-output.js b/deps/npm/test/lib/utils/reify-output.js
index 9a1bffb4033f90..4e9ed7133c18c7 100644
--- a/deps/npm/test/lib/utils/reify-output.js
+++ b/deps/npm/test/lib/utils/reify-output.js
@@ -1,7 +1,9 @@
const t = require('tap')
+const log = require('../../../lib/utils/log-shim')
-const log = require('npmlog')
-log.level = 'warn'
+const _level = log.level
+t.beforeEach(() => log.level = 'warn')
+t.teardown(() => log.level = _level)
t.cleanSnapshot = str => str.replace(/in [0-9]+m?s/g, 'in {TIME}')
@@ -237,7 +239,6 @@ t.test('showing and not showing audit report', async t => {
npm.output = out => {
t.fail('should not get output when silent', { actual: out })
}
- t.teardown(() => log.level = 'warn')
log.level = 'silent'
reifyOutput(npm, {
actualTree: { inventory: { size: 999 }, children: [] },
diff --git a/deps/npm/test/lib/utils/setup-log.js b/deps/npm/test/lib/utils/setup-log.js
deleted file mode 100644
index 7f907bc7e41482..00000000000000
--- a/deps/npm/test/lib/utils/setup-log.js
+++ /dev/null
@@ -1,296 +0,0 @@
-const t = require('tap')
-
-const settings = {
- level: 'warn',
-}
-t.afterEach(() => {
- Object.keys(settings).forEach(k => {
- delete settings[k]
- })
-})
-
-const WARN_CALLED = []
-const npmlog = {
- warn: (...args) => {
- WARN_CALLED.push(args)
- },
- levels: {
- silly: -Infinity,
- verbose: 1000,
- info: 2000,
- timing: 2500,
- http: 3000,
- notice: 3500,
- warn: 4000,
- error: 5000,
- silent: Infinity,
- },
- settings,
- enableColor: () => {
- settings.color = true
- },
- disableColor: () => {
- settings.color = false
- },
- enableUnicode: () => {
- settings.unicode = true
- },
- disableUnicode: () => {
- settings.unicode = false
- },
- enableProgress: () => {
- settings.progress = true
- },
- disableProgress: () => {
- settings.progress = false
- },
- get heading () {
- return settings.heading
- },
- set heading (h) {
- settings.heading = h
- },
- get level () {
- return settings.level
- },
- set level (l) {
- settings.level = l
- },
-}
-
-const EXPLAIN_CALLED = []
-const setupLog = t.mock('../../../lib/utils/setup-log.js', {
- '../../../lib/utils/explain-eresolve.js': {
- explain: (...args) => {
- EXPLAIN_CALLED.push(args)
- return 'explanation'
- },
- },
- npmlog,
-})
-
-const config = obj => ({
- get (k) {
- return obj[k]
- },
- set (k, v) {
- obj[k] = v
- },
-})
-
-t.test('setup with color=always and unicode', t => {
- npmlog.warn('ERESOLVE', 'hello', { some: 'object' })
- t.strictSame(EXPLAIN_CALLED, [], 'log.warn() not patched yet')
- t.strictSame(WARN_CALLED, [['ERESOLVE', 'hello', { some: 'object' }]])
- WARN_CALLED.length = 0
-
- setupLog(config({
- loglevel: 'warn',
- color: 'always',
- unicode: true,
- progress: false,
- }))
-
- npmlog.warn('ERESOLVE', 'hello', { some: { other: 'object' } })
- t.strictSame(EXPLAIN_CALLED, [[{ some: { other: 'object' } }, true, 2]],
- 'log.warn(ERESOLVE) patched to call explainEresolve()')
- t.strictSame(WARN_CALLED, [
- ['ERESOLVE', 'hello'],
- ['', 'explanation'],
- ], 'warn the explanation')
- EXPLAIN_CALLED.length = 0
- WARN_CALLED.length = 0
- npmlog.warn('some', 'other', 'thing')
- t.strictSame(EXPLAIN_CALLED, [], 'do not try to explain other things')
- t.strictSame(WARN_CALLED, [['some', 'other', 'thing']], 'warnings passed through')
-
- t.strictSame(settings, {
- level: 'warn',
- color: true,
- unicode: true,
- progress: false,
- heading: 'npm',
- })
-
- t.end()
-})
-
-t.test('setup with color=true, no unicode, and non-TTY terminal', t => {
- const { isTTY: stderrIsTTY } = process.stderr
- const { isTTY: stdoutIsTTY } = process.stdout
- t.teardown(() => {
- process.stderr.isTTY = stderrIsTTY
- process.stdout.isTTY = stdoutIsTTY
- })
- process.stderr.isTTY = false
- process.stdout.isTTY = false
-
- setupLog(config({
- loglevel: 'warn',
- color: false,
- progress: false,
- heading: 'asdf',
- }))
-
- t.strictSame(settings, {
- level: 'warn',
- color: false,
- unicode: false,
- progress: false,
- heading: 'asdf',
- })
-
- t.end()
-})
-
-t.test('setup with color=true, no unicode, and dumb TTY terminal', t => {
- const { isTTY: stderrIsTTY } = process.stderr
- const { isTTY: stdoutIsTTY } = process.stdout
- const { TERM } = process.env
- t.teardown(() => {
- process.stderr.isTTY = stderrIsTTY
- process.stdout.isTTY = stdoutIsTTY
- process.env.TERM = TERM
- })
- process.stderr.isTTY = true
- process.stdout.isTTY = true
- process.env.TERM = 'dumb'
-
- setupLog(config({
- loglevel: 'warn',
- color: true,
- progress: false,
- heading: 'asdf',
- }))
-
- t.strictSame(settings, {
- level: 'warn',
- color: true,
- unicode: false,
- progress: false,
- heading: 'asdf',
- })
-
- t.end()
-})
-
-t.test('setup with color=true, no unicode, and non-dumb TTY terminal', t => {
- const { isTTY: stderrIsTTY } = process.stderr
- const { isTTY: stdoutIsTTY } = process.stdout
- const { TERM } = process.env
- t.teardown(() => {
- process.stderr.isTTY = stderrIsTTY
- process.stdout.isTTY = stdoutIsTTY
- process.env.TERM = TERM
- })
- process.stderr.isTTY = true
- process.stdout.isTTY = true
- process.env.TERM = 'totes not dum'
-
- setupLog(config({
- loglevel: 'warn',
- color: true,
- progress: true,
- heading: 'asdf',
- }))
-
- t.strictSame(settings, {
- level: 'warn',
- color: true,
- unicode: false,
- progress: true,
- heading: 'asdf',
- })
-
- t.end()
-})
-
-t.test('setup with non-TTY stdout, TTY stderr', t => {
- const { isTTY: stderrIsTTY } = process.stderr
- const { isTTY: stdoutIsTTY } = process.stdout
- const { TERM } = process.env
- t.teardown(() => {
- process.stderr.isTTY = stderrIsTTY
- process.stdout.isTTY = stdoutIsTTY
- process.env.TERM = TERM
- })
- process.stderr.isTTY = true
- process.stdout.isTTY = false
- process.env.TERM = 'definitely not a dummy'
-
- setupLog(config({
- loglevel: 'warn',
- color: true,
- progress: true,
- heading: 'asdf',
- }))
-
- t.strictSame(settings, {
- level: 'warn',
- color: true,
- unicode: false,
- progress: true,
- heading: 'asdf',
- })
-
- t.end()
-})
-
-t.test('setup with TTY stdout, non-TTY stderr', t => {
- const { isTTY: stderrIsTTY } = process.stderr
- const { isTTY: stdoutIsTTY } = process.stdout
- const { TERM } = process.env
- t.teardown(() => {
- process.stderr.isTTY = stderrIsTTY
- process.stdout.isTTY = stdoutIsTTY
- process.env.TERM = TERM
- })
- process.stderr.isTTY = false
- process.stdout.isTTY = true
-
- setupLog(config({
- loglevel: 'warn',
- color: true,
- progress: true,
- heading: 'asdf',
- }))
-
- t.strictSame(settings, {
- level: 'warn',
- color: false,
- unicode: false,
- progress: false,
- heading: 'asdf',
- })
-
- t.end()
-})
-
-t.test('set loglevel to timing', t => {
- setupLog(config({
- timing: true,
- loglevel: 'notice',
- }))
- t.equal(settings.level, 'timing')
- t.end()
-})
-
-t.test('silent has no logging', t => {
- const { isTTY: stderrIsTTY } = process.stderr
- const { isTTY: stdoutIsTTY } = process.stdout
- const { TERM } = process.env
- t.teardown(() => {
- process.stderr.isTTY = stderrIsTTY
- process.stdout.isTTY = stdoutIsTTY
- process.env.TERM = TERM
- })
- process.stderr.isTTY = true
- process.stdout.isTTY = true
- process.env.TERM = 'totes not dum'
-
- setupLog(config({
- loglevel: 'silent',
- }))
- t.equal(settings.progress, false, 'progress disabled when silent')
- t.end()
-})
diff --git a/deps/npm/test/lib/utils/tar.js b/deps/npm/test/lib/utils/tar.js
index 19d94916945dbd..adc5cb364997f2 100644
--- a/deps/npm/test/lib/utils/tar.js
+++ b/deps/npm/test/lib/utils/tar.js
@@ -2,18 +2,20 @@ const t = require('tap')
const pack = require('libnpmpack')
const ssri = require('ssri')
-const { logTar, getContents } = require('../../../lib/utils/tar.js')
+const { getContents } = require('../../../lib/utils/tar.js')
-const printLogs = (tarball, unicode) => {
+const mockTar = ({ notice }) => t.mock('../../../lib/utils/tar.js', {
+ 'proc-log': {
+ notice,
+ },
+})
+
+const printLogs = (tarball, options) => {
const logs = []
- logTar(tarball, {
- log: {
- notice: (...args) => {
- args.map(el => logs.push(el))
- },
- },
- unicode,
+ const { logTar } = mockTar({
+ notice: (...args) => args.map(el => logs.push(el)),
})
+ logTar(tarball, options)
return logs.join('\n')
}
@@ -41,16 +43,14 @@ t.test('should log tarball contents', async (t) => {
version: '1.0.0',
}, tarball)
- t.matchSnapshot(printLogs(tarballContents, false))
+ t.matchSnapshot(printLogs(tarballContents))
})
t.test('should log tarball contents with unicode', async (t) => {
- const { logTar } = t.mock('../../../lib/utils/tar.js', {
- npmlog: {
- notice: (str) => {
- t.ok(true, 'defaults to npmlog')
- return str
- },
+ const { logTar } = mockTar({
+ notice: (str) => {
+ t.ok(true, 'defaults to proc-log')
+ return str
},
})
@@ -64,26 +64,6 @@ t.test('should log tarball contents with unicode', async (t) => {
t.end()
})
-t.test('should default to npmlog', async (t) => {
- const { logTar } = t.mock('../../../lib/utils/tar.js', {
- npmlog: {
- notice: (str) => {
- t.ok(true, 'defaults to npmlog')
- return str
- },
- },
- })
-
- logTar({
- files: [],
- bundled: [],
- size: 0,
- unpackedSize: 0,
- integrity: '',
- })
- t.end()
-})
-
t.test('should getContents of a tarball', async (t) => {
const testDir = t.testdir({
'package.json': JSON.stringify({
diff --git a/deps/npm/test/lib/utils/timers.js b/deps/npm/test/lib/utils/timers.js
new file mode 100644
index 00000000000000..6127f346b179e0
--- /dev/null
+++ b/deps/npm/test/lib/utils/timers.js
@@ -0,0 +1,82 @@
+const t = require('tap')
+const { resolve } = require('path')
+const fs = require('graceful-fs')
+const mockLogs = require('../../fixtures/mock-logs')
+
+const mockTimers = (t, options) => {
+ const { logs, logMocks } = mockLogs()
+ const Timers = t.mock('../../../lib/utils/timers', {
+ ...logMocks,
+ })
+ const timers = new Timers(options)
+ t.teardown(() => timers.off())
+ return { timers, logs }
+}
+
+t.test('getters', async (t) => {
+ const { timers } = mockTimers(t)
+ t.match(timers.unfinished, new Map())
+ t.match(timers.finished, {})
+})
+
+t.test('listens/stops on process', async (t) => {
+ const { timers } = mockTimers(t)
+ process.emit('time', 'foo')
+ process.emit('time', 'bar')
+ process.emit('timeEnd', 'bar')
+ t.match(timers.unfinished, new Map([['foo', Number]]))
+ t.match(timers.finished, { bar: Number })
+ timers.off()
+ process.emit('time', 'baz')
+ t.notOk(timers.unfinished.get('baz'))
+})
+
+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 listener', async (t) => {
+ const events = []
+ const listener = (...args) => events.push(args)
+ const { timers } = 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.test('finish unstarted timer', async (t) => {
+ const { logs } = mockTimers(t)
+ process.emit('timeEnd', 'foo')
+ t.match(logs.silly, [['timing', /^Tried to end timer/, 'foo']])
+})
+
+t.test('writes file', async (t) => {
+ const { timers } = mockTimers(t)
+ const dir = t.testdir()
+ process.emit('time', 'foo')
+ process.emit('timeEnd', 'foo')
+ timers.load({ dir })
+ timers.writeFile({ some: 'data' })
+ const data = JSON.parse(fs.readFileSync(resolve(dir, '_timing.json')))
+ t.match(data, {
+ some: 'data',
+ foo: Number,
+ unfinished: {
+ npm: [Number, Number],
+ },
+ })
+})
+
+t.test('fails to write file', async (t) => {
+ const { logs, timers } = mockTimers(t)
+ timers.writeFile()
+ t.match(logs.warn, [
+ ['timing', 'could not write timing file', Error],
+ ])
+})
diff --git a/deps/npm/test/lib/utils/unsupported.js b/deps/npm/test/lib/utils/unsupported.js
index 4d806cefc4e52f..2703044a227d36 100644
--- a/deps/npm/test/lib/utils/unsupported.js
+++ b/deps/npm/test/lib/utils/unsupported.js
@@ -1,5 +1,6 @@
const t = require('tap')
const unsupported = require('../../../lib/utils/unsupported.js')
+const mockGlobals = require('../../fixtures/mock-globals.js')
const versions = [
// broken unsupported
@@ -55,42 +56,30 @@ t.test('checkForBrokenNode', t => {
// run it once to not fail
unsupported.checkForBrokenNode()
- const { exit } = process
- const { error } = console
- const versionPropDesc = Object.getOwnPropertyDescriptor(process, 'version')
-
- t.teardown(() => {
- process.exit = exit
- Object.defineProperty(process, 'version', versionPropDesc)
- console.error = error
- })
-
- // then make it a thing that fails
- process.exit = code => {
- t.equal(code, 1)
- t.strictSame(logs, expectLogs)
- t.end()
- }
- Object.defineProperty(process, 'version', { value: '1.2.3', configurable: true })
const logs = []
const expectLogs = [
'ERROR: npm is known not to run on Node.js 1.2.3',
"You'll need to upgrade to a newer Node.js version in order to use this",
'version of npm. You can find the latest version at https://nodejs.org/',
]
- console.error = msg => logs.push(msg)
+
+ // then make it a thing that fails
+ mockGlobals(t, {
+ 'console.error': msg => logs.push(msg),
+ 'process.version': '1.2.3',
+ 'process.exit': (code) => {
+ t.equal(code, 1)
+ t.strictSame(logs, expectLogs)
+ t.end()
+ },
+ })
+
unsupported.checkForBrokenNode()
})
t.test('checkForUnsupportedNode', t => {
- const npmlog = require('npmlog')
- const { warn } = npmlog
- const versionPropDesc = Object.getOwnPropertyDescriptor(process, 'version')
-
- t.teardown(() => {
- Object.defineProperty(process, 'version', versionPropDesc)
- npmlog.warn = warn
- })
+ // run it once to not fail or warn
+ unsupported.checkForUnsupportedNode()
const logs = []
const expectLogs = [
@@ -99,14 +88,15 @@ t.test('checkForUnsupportedNode', t => {
"can't make any promises that npm will work with this version.",
'You can find the latest version at https://nodejs.org/',
]
- npmlog.warn = (section, msg) => logs.push(msg)
-
- // run it once to not fail or warn
- unsupported.checkForUnsupportedNode()
// then make it a thing that fails
- Object.defineProperty(process, 'version', { value: '8.0.0' })
+ mockGlobals(t, {
+ 'console.error': msg => logs.push(msg),
+ 'process.version': '8.0.0',
+ })
+
unsupported.checkForUnsupportedNode()
+
t.strictSame(logs, expectLogs)
t.end()
})
diff --git a/deps/npm/test/lib/utils/update-notifier.js b/deps/npm/test/lib/utils/update-notifier.js
index 78ff93825e4899..a7a800c602fd6f 100644
--- a/deps/npm/test/lib/utils/update-notifier.js
+++ b/deps/npm/test/lib/utils/update-notifier.js
@@ -36,18 +36,13 @@ const pacote = {
},
}
-const npm = {
+const defaultNpm = {
flatOptions,
- log: { useColor: () => true },
version: CURRENT_VERSION,
config: { get: k => k !== 'global' },
command: 'view',
argv: ['npm'],
}
-const npmNoColor = {
- ...npm,
- log: { useColor: () => false },
-}
const { basename } = require('path')
@@ -80,12 +75,6 @@ const fs = {
},
}
-const updateNotifier = t.mock('../../../lib/utils/update-notifier.js', {
- '@npmcli/ci-detect': () => ciMock,
- pacote,
- fs,
-})
-
t.afterEach(() => {
MANIFEST_REQUEST.length = 0
STAT_ERROR = null
@@ -94,16 +83,21 @@ t.afterEach(() => {
WRITE_ERROR = null
})
-const runUpdateNotifier = async npm => {
- await updateNotifier(npm)
- return npm.updateNotification
+const runUpdateNotifier = async ({ color = true, ...npmOptions } = {}) => {
+ const _npm = { ...defaultNpm, ...npmOptions }
+ await t.mock('../../../lib/utils/update-notifier.js', {
+ '@npmcli/ci-detect': () => ciMock,
+ pacote,
+ fs,
+ npmlog: { useColor: () => color },
+ })(_npm)
+ return _npm.updateNotification
}
t.test('situations in which we do not notify', t => {
t.test('nothing to do if notifier disabled', async t => {
t.equal(
await runUpdateNotifier({
- ...npm,
config: { get: k => k !== 'update-notifier' },
}),
null
@@ -114,7 +108,6 @@ t.test('situations in which we do not notify', t => {
t.test('do not suggest update if already updating', async t => {
t.equal(
await runUpdateNotifier({
- ...npm,
flatOptions: { ...flatOptions, global: true },
command: 'install',
argv: ['npm'],
@@ -127,7 +120,6 @@ t.test('situations in which we do not notify', t => {
t.test('do not suggest update if already updating with spec', async t => {
t.equal(
await runUpdateNotifier({
- ...npm,
flatOptions: { ...flatOptions, global: true },
command: 'install',
argv: ['npm@latest'],
@@ -138,31 +130,31 @@ t.test('situations in which we do not notify', t => {
})
t.test('do not update if same as latest', async t => {
- t.equal(await runUpdateNotifier(npm), null)
+ t.equal(await runUpdateNotifier(), null)
t.strictSame(MANIFEST_REQUEST, ['npm@latest'], 'requested latest version')
})
t.test('check if stat errors (here for coverage)', async t => {
STAT_ERROR = new Error('blorg')
- t.equal(await runUpdateNotifier(npm), null)
+ t.equal(await runUpdateNotifier(), null)
t.strictSame(MANIFEST_REQUEST, ['npm@latest'], 'requested latest version')
})
t.test('ok if write errors (here for coverage)', async t => {
WRITE_ERROR = new Error('grolb')
- t.equal(await runUpdateNotifier(npm), null)
+ t.equal(await runUpdateNotifier(), null)
t.strictSame(MANIFEST_REQUEST, ['npm@latest'], 'requested latest version')
})
t.test('ignore pacote failures (here for coverage)', async t => {
PACOTE_ERROR = new Error('pah-KO-tchay')
- t.equal(await runUpdateNotifier(npm), null)
+ t.equal(await runUpdateNotifier(), null)
t.strictSame(MANIFEST_REQUEST, ['npm@latest'], 'requested latest version')
})
t.test('do not update if newer than latest, but same as next', async t => {
- t.equal(await runUpdateNotifier({ ...npm, version: NEXT_VERSION }), null)
+ t.equal(await runUpdateNotifier({ version: NEXT_VERSION }), null)
const reqs = ['npm@latest', `npm@^${NEXT_VERSION}`]
t.strictSame(MANIFEST_REQUEST, reqs, 'requested latest and next versions')
})
t.test('do not update if on the latest beta', async t => {
- t.equal(await runUpdateNotifier({ ...npm, version: CURRENT_BETA }), null)
+ t.equal(await runUpdateNotifier({ version: CURRENT_BETA }), null)
const reqs = [`npm@^${CURRENT_BETA}`]
t.strictSame(MANIFEST_REQUEST, reqs, 'requested latest and next versions')
})
@@ -172,21 +164,21 @@ t.test('situations in which we do not notify', t => {
ciMock = null
})
ciMock = 'something'
- t.equal(await runUpdateNotifier(npm), null)
+ t.equal(await runUpdateNotifier(), null)
t.strictSame(MANIFEST_REQUEST, [], 'no requests for manifests')
})
t.test('only check weekly for GA releases', async t => {
// One week (plus five minutes to account for test environment fuzziness)
STAT_MTIME = Date.now() - 1000 * 60 * 60 * 24 * 7 + 1000 * 60 * 5
- t.equal(await runUpdateNotifier(npm), null)
+ t.equal(await runUpdateNotifier(), null)
t.strictSame(MANIFEST_REQUEST, [], 'no requests for manifests')
})
t.test('only check daily for betas', async t => {
// One day (plus five minutes to account for test environment fuzziness)
STAT_MTIME = Date.now() - 1000 * 60 * 60 * 24 + 1000 * 60 * 5
- t.equal(await runUpdateNotifier({ ...npm, version: HAVE_BETA }), null)
+ t.equal(await runUpdateNotifier({ version: HAVE_BETA }), null)
t.strictSame(MANIFEST_REQUEST, [], 'no requests for manifests')
})
@@ -196,9 +188,9 @@ t.test('situations in which we do not notify', t => {
t.test('notification situations', t => {
t.test('new beta available', async t => {
const version = HAVE_BETA
- t.matchSnapshot(await runUpdateNotifier({ ...npm, version }), 'color')
+ t.matchSnapshot(await runUpdateNotifier({ version }), 'color')
t.matchSnapshot(
- await runUpdateNotifier({ ...npmNoColor, version }),
+ await runUpdateNotifier({ version, color: false }),
'no color'
)
t.strictSame(MANIFEST_REQUEST, [`npm@^${version}`, `npm@^${version}`])
@@ -206,9 +198,9 @@ t.test('notification situations', t => {
t.test('patch to next version', async t => {
const version = NEXT_PATCH
- t.matchSnapshot(await runUpdateNotifier({ ...npm, version }), 'color')
+ t.matchSnapshot(await runUpdateNotifier({ version }), 'color')
t.matchSnapshot(
- await runUpdateNotifier({ ...npmNoColor, version }),
+ await runUpdateNotifier({ version, color: false }),
'no color'
)
t.strictSame(MANIFEST_REQUEST, [
@@ -221,9 +213,9 @@ t.test('notification situations', t => {
t.test('minor to next version', async t => {
const version = NEXT_MINOR
- t.matchSnapshot(await runUpdateNotifier({ ...npm, version }), 'color')
+ t.matchSnapshot(await runUpdateNotifier({ version }), 'color')
t.matchSnapshot(
- await runUpdateNotifier({ ...npmNoColor, version }),
+ await runUpdateNotifier({ version, color: false }),
'no color'
)
t.strictSame(MANIFEST_REQUEST, [
@@ -236,9 +228,9 @@ t.test('notification situations', t => {
t.test('patch to current', async t => {
const version = CURRENT_PATCH
- t.matchSnapshot(await runUpdateNotifier({ ...npm, version }), 'color')
+ t.matchSnapshot(await runUpdateNotifier({ version }), 'color')
t.matchSnapshot(
- await runUpdateNotifier({ ...npmNoColor, version }),
+ await runUpdateNotifier({ version, color: false }),
'no color'
)
t.strictSame(MANIFEST_REQUEST, ['npm@latest', 'npm@latest'])
@@ -246,9 +238,9 @@ t.test('notification situations', t => {
t.test('minor to current', async t => {
const version = CURRENT_MINOR
- t.matchSnapshot(await runUpdateNotifier({ ...npm, version }), 'color')
+ t.matchSnapshot(await runUpdateNotifier({ version }), 'color')
t.matchSnapshot(
- await runUpdateNotifier({ ...npmNoColor, version }),
+ await runUpdateNotifier({ version, color: false }),
'no color'
)
t.strictSame(MANIFEST_REQUEST, ['npm@latest', 'npm@latest'])
@@ -256,9 +248,9 @@ t.test('notification situations', t => {
t.test('major to current', async t => {
const version = CURRENT_MAJOR
- t.matchSnapshot(await runUpdateNotifier({ ...npm, version }), 'color')
+ t.matchSnapshot(await runUpdateNotifier({ version }), 'color')
t.matchSnapshot(
- await runUpdateNotifier({ ...npmNoColor, version }),
+ await runUpdateNotifier({ version, color: false }),
'no color'
)
t.strictSame(MANIFEST_REQUEST, ['npm@latest', 'npm@latest'])