summaryrefslogtreecommitdiff
path: root/deps/npm
diff options
context:
space:
mode:
authornpm team <ops+robot@npmjs.com>2021-12-02 22:04:46 +0000
committerRich Trott <rtrott@gmail.com>2021-12-05 08:31:02 -0800
commitb323cec78f713bc113be7f6030d787804a9af5a0 (patch)
tree1605ce209f7625877e5e2de629299d63dbd3f0b3 /deps/npm
parentb9f81ad1ae49f96dc585b0399320ce8c075e907f (diff)
downloadnode-new-b323cec78f713bc113be7f6030d787804a9af5a0.tar.gz
deps: upgrade npm to 8.2.0
PR-URL: https://github.com/nodejs/node/pull/41065 Reviewed-By: Myles Borins <myles.borins@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
Diffstat (limited to 'deps/npm')
-rw-r--r--deps/npm/docs/content/using-npm/config.md6
-rw-r--r--deps/npm/docs/content/using-npm/logging.md60
-rw-r--r--deps/npm/docs/content/using-npm/scripts.md2
-rw-r--r--deps/npm/docs/content/using-npm/workspaces.md2
-rw-r--r--deps/npm/docs/output/commands/npm-ls.html2
-rw-r--r--deps/npm/docs/output/commands/npm.html2
-rw-r--r--deps/npm/docs/output/using-npm/config.html6
-rw-r--r--deps/npm/docs/output/using-npm/logging.html203
-rw-r--r--deps/npm/docs/output/using-npm/scripts.html2
-rw-r--r--deps/npm/docs/output/using-npm/workspaces.html2
-rw-r--r--deps/npm/lib/auth/legacy.js11
-rw-r--r--deps/npm/lib/auth/sso.js3
-rw-r--r--deps/npm/lib/cli.js33
-rw-r--r--deps/npm/lib/commands/adduser.js3
-rw-r--r--deps/npm/lib/commands/bin.js1
-rw-r--r--deps/npm/lib/commands/bugs.js2
-rw-r--r--deps/npm/lib/commands/cache.js4
-rw-r--r--deps/npm/lib/commands/ci.js5
-rw-r--r--deps/npm/lib/commands/config.js11
-rw-r--r--deps/npm/lib/commands/dedupe.js3
-rw-r--r--deps/npm/lib/commands/diff.js16
-rw-r--r--deps/npm/lib/commands/dist-tag.js3
-rw-r--r--deps/npm/lib/commands/docs.js3
-rw-r--r--deps/npm/lib/commands/doctor.js17
-rw-r--r--deps/npm/lib/commands/exec.js2
-rw-r--r--deps/npm/lib/commands/explore.js7
-rw-r--r--deps/npm/lib/commands/fund.js3
-rw-r--r--deps/npm/lib/commands/init.js16
-rw-r--r--deps/npm/lib/commands/install.js6
-rw-r--r--deps/npm/lib/commands/link.js11
-rw-r--r--deps/npm/lib/commands/logout.js2
-rw-r--r--deps/npm/lib/commands/owner.js3
-rw-r--r--deps/npm/lib/commands/pack.js9
-rw-r--r--deps/npm/lib/commands/ping.js2
-rw-r--r--deps/npm/lib/commands/profile.js6
-rw-r--r--deps/npm/lib/commands/prune.js3
-rw-r--r--deps/npm/lib/commands/publish.js6
-rw-r--r--deps/npm/lib/commands/repo.js3
-rw-r--r--deps/npm/lib/commands/run-script.js2
-rw-r--r--deps/npm/lib/commands/search.js2
-rw-r--r--deps/npm/lib/commands/set-script.js2
-rw-r--r--deps/npm/lib/commands/shrinkwrap.js3
-rw-r--r--deps/npm/lib/commands/star.js3
-rw-r--r--deps/npm/lib/commands/stars.js3
-rw-r--r--deps/npm/lib/commands/token.js2
-rw-r--r--deps/npm/lib/commands/uninstall.js3
-rw-r--r--deps/npm/lib/commands/unpublish.js8
-rw-r--r--deps/npm/lib/commands/update.js4
-rw-r--r--deps/npm/lib/commands/view.js4
-rw-r--r--deps/npm/lib/npm.js158
-rw-r--r--deps/npm/lib/utils/audit-error.js4
-rw-r--r--deps/npm/lib/utils/cleanup-log-files.js35
-rw-r--r--deps/npm/lib/utils/config/definitions.js20
-rw-r--r--deps/npm/lib/utils/deref-command.js2
-rw-r--r--deps/npm/lib/utils/display.js119
-rw-r--r--deps/npm/lib/utils/error-message.js9
-rw-r--r--deps/npm/lib/utils/exit-handler.js207
-rw-r--r--deps/npm/lib/utils/get-project-scope.js19
-rw-r--r--deps/npm/lib/utils/log-file.js245
-rw-r--r--deps/npm/lib/utils/log-shim.js59
-rw-r--r--deps/npm/lib/utils/proc-log-listener.js22
-rw-r--r--deps/npm/lib/utils/pulse-till-done.js2
-rw-r--r--deps/npm/lib/utils/read-user-info.js14
-rw-r--r--deps/npm/lib/utils/reify-output.js2
-rw-r--r--deps/npm/lib/utils/setup-log.js66
-rw-r--r--deps/npm/lib/utils/tar.js4
-rw-r--r--deps/npm/lib/utils/timers.js111
-rw-r--r--deps/npm/lib/utils/unsupported.js16
-rw-r--r--deps/npm/lib/utils/update-notifier.js3
-rw-r--r--deps/npm/lib/utils/usage.js2
-rw-r--r--deps/npm/lib/utils/with-chown-sync.js13
-rw-r--r--deps/npm/man/man1/npm-access.12
-rw-r--r--deps/npm/man/man1/npm-adduser.12
-rw-r--r--deps/npm/man/man1/npm-audit.12
-rw-r--r--deps/npm/man/man1/npm-bin.12
-rw-r--r--deps/npm/man/man1/npm-bugs.12
-rw-r--r--deps/npm/man/man1/npm-cache.12
-rw-r--r--deps/npm/man/man1/npm-ci.12
-rw-r--r--deps/npm/man/man1/npm-completion.12
-rw-r--r--deps/npm/man/man1/npm-config.12
-rw-r--r--deps/npm/man/man1/npm-dedupe.12
-rw-r--r--deps/npm/man/man1/npm-deprecate.12
-rw-r--r--deps/npm/man/man1/npm-diff.12
-rw-r--r--deps/npm/man/man1/npm-dist-tag.12
-rw-r--r--deps/npm/man/man1/npm-docs.12
-rw-r--r--deps/npm/man/man1/npm-doctor.12
-rw-r--r--deps/npm/man/man1/npm-edit.12
-rw-r--r--deps/npm/man/man1/npm-exec.12
-rw-r--r--deps/npm/man/man1/npm-explain.12
-rw-r--r--deps/npm/man/man1/npm-explore.12
-rw-r--r--deps/npm/man/man1/npm-find-dupes.12
-rw-r--r--deps/npm/man/man1/npm-fund.12
-rw-r--r--deps/npm/man/man1/npm-help-search.12
-rw-r--r--deps/npm/man/man1/npm-help.12
-rw-r--r--deps/npm/man/man1/npm-hook.12
-rw-r--r--deps/npm/man/man1/npm-init.12
-rw-r--r--deps/npm/man/man1/npm-install-ci-test.12
-rw-r--r--deps/npm/man/man1/npm-install-test.12
-rw-r--r--deps/npm/man/man1/npm-install.12
-rw-r--r--deps/npm/man/man1/npm-link.12
-rw-r--r--deps/npm/man/man1/npm-logout.12
-rw-r--r--deps/npm/man/man1/npm-ls.14
-rw-r--r--deps/npm/man/man1/npm-org.12
-rw-r--r--deps/npm/man/man1/npm-outdated.12
-rw-r--r--deps/npm/man/man1/npm-owner.12
-rw-r--r--deps/npm/man/man1/npm-pack.12
-rw-r--r--deps/npm/man/man1/npm-ping.12
-rw-r--r--deps/npm/man/man1/npm-pkg.12
-rw-r--r--deps/npm/man/man1/npm-prefix.12
-rw-r--r--deps/npm/man/man1/npm-profile.12
-rw-r--r--deps/npm/man/man1/npm-prune.12
-rw-r--r--deps/npm/man/man1/npm-publish.12
-rw-r--r--deps/npm/man/man1/npm-rebuild.12
-rw-r--r--deps/npm/man/man1/npm-repo.12
-rw-r--r--deps/npm/man/man1/npm-restart.12
-rw-r--r--deps/npm/man/man1/npm-root.12
-rw-r--r--deps/npm/man/man1/npm-run-script.12
-rw-r--r--deps/npm/man/man1/npm-search.12
-rw-r--r--deps/npm/man/man1/npm-set-script.12
-rw-r--r--deps/npm/man/man1/npm-shrinkwrap.12
-rw-r--r--deps/npm/man/man1/npm-star.12
-rw-r--r--deps/npm/man/man1/npm-stars.12
-rw-r--r--deps/npm/man/man1/npm-start.12
-rw-r--r--deps/npm/man/man1/npm-stop.12
-rw-r--r--deps/npm/man/man1/npm-team.12
-rw-r--r--deps/npm/man/man1/npm-test.12
-rw-r--r--deps/npm/man/man1/npm-token.12
-rw-r--r--deps/npm/man/man1/npm-uninstall.12
-rw-r--r--deps/npm/man/man1/npm-unpublish.12
-rw-r--r--deps/npm/man/man1/npm-unstar.12
-rw-r--r--deps/npm/man/man1/npm-update.12
-rw-r--r--deps/npm/man/man1/npm-version.12
-rw-r--r--deps/npm/man/man1/npm-view.12
-rw-r--r--deps/npm/man/man1/npm-whoami.12
-rw-r--r--deps/npm/man/man1/npm.14
-rw-r--r--deps/npm/man/man1/npx.12
-rw-r--r--deps/npm/man/man5/folders.52
-rw-r--r--deps/npm/man/man5/install.52
-rw-r--r--deps/npm/man/man5/npm-shrinkwrap-json.52
-rw-r--r--deps/npm/man/man5/npmrc.52
-rw-r--r--deps/npm/man/man5/package-json.52
-rw-r--r--deps/npm/man/man5/package-lock-json.52
-rw-r--r--deps/npm/man/man7/config.78
-rw-r--r--deps/npm/man/man7/developers.72
-rw-r--r--deps/npm/man/man7/logging.774
-rw-r--r--deps/npm/man/man7/orgs.72
-rw-r--r--deps/npm/man/man7/registry.72
-rw-r--r--deps/npm/man/man7/removal.72
-rw-r--r--deps/npm/man/man7/scope.72
-rw-r--r--deps/npm/man/man7/scripts.74
-rw-r--r--deps/npm/man/man7/workspaces.74
-rw-r--r--deps/npm/node_modules/@npmcli/config/lib/index.js8
-rw-r--r--deps/npm/node_modules/@npmcli/config/package.json2
-rw-r--r--deps/npm/node_modules/are-we-there-yet/package.json2
-rw-r--r--deps/npm/node_modules/code-point-at/index.js32
-rw-r--r--deps/npm/node_modules/code-point-at/license21
-rw-r--r--deps/npm/node_modules/code-point-at/package.json38
-rw-r--r--deps/npm/node_modules/code-point-at/readme.md32
-rw-r--r--deps/npm/node_modules/node-gyp/CHANGELOG.md17
-rw-r--r--deps/npm/node_modules/node-gyp/docs/Updating-npm-bundled-node-gyp.md4
-rw-r--r--deps/npm/node_modules/node-gyp/node_modules/aproba/LICENSE13
-rw-r--r--deps/npm/node_modules/node-gyp/node_modules/aproba/index.js105
-rw-r--r--deps/npm/node_modules/node-gyp/node_modules/aproba/package.json34
-rw-r--r--deps/npm/node_modules/node-gyp/node_modules/gauge/LICENSE13
-rw-r--r--deps/npm/node_modules/node-gyp/node_modules/gauge/base-theme.js14
-rw-r--r--deps/npm/node_modules/node-gyp/node_modules/gauge/error.js24
-rw-r--r--deps/npm/node_modules/node-gyp/node_modules/gauge/has-color.js12
-rw-r--r--deps/npm/node_modules/node-gyp/node_modules/gauge/index.js233
-rw-r--r--deps/npm/node_modules/node-gyp/node_modules/gauge/package.json63
-rw-r--r--deps/npm/node_modules/node-gyp/node_modules/gauge/plumbing.js48
-rw-r--r--deps/npm/node_modules/node-gyp/node_modules/gauge/process.js3
-rw-r--r--deps/npm/node_modules/node-gyp/node_modules/gauge/progress-bar.js35
-rw-r--r--deps/npm/node_modules/node-gyp/node_modules/gauge/render-template.js181
-rw-r--r--deps/npm/node_modules/node-gyp/node_modules/gauge/set-immediate.js7
-rw-r--r--deps/npm/node_modules/node-gyp/node_modules/gauge/set-interval.js3
-rw-r--r--deps/npm/node_modules/node-gyp/node_modules/gauge/spin.js5
-rw-r--r--deps/npm/node_modules/node-gyp/node_modules/gauge/template-item.js72
-rw-r--r--deps/npm/node_modules/node-gyp/node_modules/gauge/theme-set.js114
-rw-r--r--deps/npm/node_modules/node-gyp/node_modules/gauge/themes.js54
-rw-r--r--deps/npm/node_modules/node-gyp/node_modules/gauge/wide-truncate.js25
-rw-r--r--deps/npm/node_modules/node-gyp/node_modules/is-fullwidth-code-point/index.js46
-rw-r--r--deps/npm/node_modules/node-gyp/node_modules/is-fullwidth-code-point/license21
-rw-r--r--deps/npm/node_modules/node-gyp/node_modules/is-fullwidth-code-point/package.json45
-rw-r--r--deps/npm/node_modules/node-gyp/node_modules/npmlog/LICENSE15
-rw-r--r--deps/npm/node_modules/node-gyp/node_modules/npmlog/log.js309
-rw-r--r--deps/npm/node_modules/node-gyp/node_modules/npmlog/package.json28
-rw-r--r--deps/npm/node_modules/node-gyp/node_modules/string-width/index.js37
-rw-r--r--deps/npm/node_modules/node-gyp/node_modules/string-width/license21
-rw-r--r--deps/npm/node_modules/node-gyp/node_modules/string-width/package.json56
-rw-r--r--deps/npm/node_modules/node-gyp/package.json4
-rw-r--r--deps/npm/node_modules/npmlog/node_modules/are-we-there-yet/LICENSE.md18
-rw-r--r--deps/npm/node_modules/npmlog/node_modules/are-we-there-yet/lib/index.js4
-rw-r--r--deps/npm/node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker-base.js11
-rw-r--r--deps/npm/node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker-group.js116
-rw-r--r--deps/npm/node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker-stream.js36
-rw-r--r--deps/npm/node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker.js32
-rw-r--r--deps/npm/node_modules/npmlog/node_modules/are-we-there-yet/package.json53
-rw-r--r--deps/npm/node_modules/number-is-nan/index.js4
-rw-r--r--deps/npm/node_modules/number-is-nan/license21
-rw-r--r--deps/npm/node_modules/number-is-nan/package.json35
-rw-r--r--deps/npm/node_modules/number-is-nan/readme.md28
-rw-r--r--deps/npm/package.json12
-rw-r--r--deps/npm/tap-snapshots/test/lib/commands/config.js.test.cjs6
-rw-r--r--deps/npm/tap-snapshots/test/lib/commands/shrinkwrap.js.test.cjs70
-rw-r--r--deps/npm/tap-snapshots/test/lib/commands/view.js.test.cjs8
-rw-r--r--deps/npm/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs6
-rw-r--r--deps/npm/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs6
-rw-r--r--deps/npm/tap-snapshots/test/lib/utils/error-message.js.test.cjs83
-rw-r--r--deps/npm/tap-snapshots/test/lib/utils/exit-handler.js.test.cjs62
-rw-r--r--deps/npm/tap-snapshots/test/lib/utils/log-file.js.test.cjs68
-rw-r--r--deps/npm/test/fixtures/clean-snapshot.js19
-rw-r--r--deps/npm/test/fixtures/mock-globals.js210
-rw-r--r--deps/npm/test/fixtures/mock-logs.js71
-rw-r--r--deps/npm/test/fixtures/mock-npm.js190
-rw-r--r--deps/npm/test/fixtures/sandbox.js46
-rw-r--r--deps/npm/test/index.js4
-rw-r--r--deps/npm/test/lib/auth/legacy.js2
-rw-r--r--deps/npm/test/lib/auth/sso.js2
-rw-r--r--deps/npm/test/lib/cli.js182
-rw-r--r--deps/npm/test/lib/commands/access.js307
-rw-r--r--deps/npm/test/lib/commands/adduser.js9
-rw-r--r--deps/npm/test/lib/commands/audit.js143
-rw-r--r--deps/npm/test/lib/commands/birthday.js13
-rw-r--r--deps/npm/test/lib/commands/cache.js19
-rw-r--r--deps/npm/test/lib/commands/ci.js2
-rw-r--r--deps/npm/test/lib/commands/completion.js249
-rw-r--r--deps/npm/test/lib/commands/dedupe.js61
-rw-r--r--deps/npm/test/lib/commands/diff.js2
-rw-r--r--deps/npm/test/lib/commands/dist-tag.js2
-rw-r--r--deps/npm/test/lib/commands/doctor.js83
-rw-r--r--deps/npm/test/lib/commands/exec.js30
-rw-r--r--deps/npm/test/lib/commands/explore.js11
-rw-r--r--deps/npm/test/lib/commands/find-dupes.js35
-rw-r--r--deps/npm/test/lib/commands/get.js6
-rw-r--r--deps/npm/test/lib/commands/init.js32
-rw-r--r--deps/npm/test/lib/commands/install.js62
-rw-r--r--deps/npm/test/lib/commands/logout.js131
-rw-r--r--deps/npm/test/lib/commands/owner.js22
-rw-r--r--deps/npm/test/lib/commands/pack.js146
-rw-r--r--deps/npm/test/lib/commands/ping.js6
-rw-r--r--deps/npm/test/lib/commands/prefix.js5
-rw-r--r--deps/npm/test/lib/commands/profile.js36
-rw-r--r--deps/npm/test/lib/commands/prune.js26
-rw-r--r--deps/npm/test/lib/commands/publish.js31
-rw-r--r--deps/npm/test/lib/commands/repo.js91
-rw-r--r--deps/npm/test/lib/commands/restart.js34
-rw-r--r--deps/npm/test/lib/commands/root.js5
-rw-r--r--deps/npm/test/lib/commands/run-script.js12
-rw-r--r--deps/npm/test/lib/commands/set-script.js2
-rw-r--r--deps/npm/test/lib/commands/set.js1
-rw-r--r--deps/npm/test/lib/commands/shrinkwrap.js34
-rw-r--r--deps/npm/test/lib/commands/star.js10
-rw-r--r--deps/npm/test/lib/commands/stars.js12
-rw-r--r--deps/npm/test/lib/commands/start.js33
-rw-r--r--deps/npm/test/lib/commands/stop.js30
-rw-r--r--deps/npm/test/lib/commands/test.js32
-rw-r--r--deps/npm/test/lib/commands/token.js24
-rw-r--r--deps/npm/test/lib/commands/unpublish.js9
-rw-r--r--deps/npm/test/lib/commands/update.js28
-rw-r--r--deps/npm/test/lib/commands/version.js504
-rw-r--r--deps/npm/test/lib/commands/view.js18
-rw-r--r--deps/npm/test/lib/commands/whoami.js20
-rw-r--r--deps/npm/test/lib/fixtures/mock-globals.js321
-rw-r--r--deps/npm/test/lib/load-all-commands.js13
-rw-r--r--deps/npm/test/lib/load-all.js39
-rw-r--r--deps/npm/test/lib/npm.js528
-rw-r--r--deps/npm/test/lib/utils/audit-error.js9
-rw-r--r--deps/npm/test/lib/utils/cleanup-log-files.js79
-rw-r--r--deps/npm/test/lib/utils/config/definitions.js113
-rw-r--r--deps/npm/test/lib/utils/did-you-mean.js6
-rw-r--r--deps/npm/test/lib/utils/display.js85
-rw-r--r--deps/npm/test/lib/utils/error-message.js264
-rw-r--r--deps/npm/test/lib/utils/exit-handler.js618
-rw-r--r--deps/npm/test/lib/utils/get-project-scope.js48
-rw-r--r--deps/npm/test/lib/utils/is-windows-bash.js34
-rw-r--r--deps/npm/test/lib/utils/log-file.js333
-rw-r--r--deps/npm/test/lib/utils/log-shim.js100
-rw-r--r--deps/npm/test/lib/utils/npm-usage.js6
-rw-r--r--deps/npm/test/lib/utils/proc-log-listener.js41
-rw-r--r--deps/npm/test/lib/utils/pulse-till-done.js19
-rw-r--r--deps/npm/test/lib/utils/read-user-info.js30
-rw-r--r--deps/npm/test/lib/utils/reify-output.js7
-rw-r--r--deps/npm/test/lib/utils/setup-log.js296
-rw-r--r--deps/npm/test/lib/utils/tar.js52
-rw-r--r--deps/npm/test/lib/utils/timers.js82
-rw-r--r--deps/npm/test/lib/utils/unsupported.js52
-rw-r--r--deps/npm/test/lib/utils/update-notifier.js70
287 files changed, 5105 insertions, 5604 deletions
diff --git a/deps/npm/docs/content/using-npm/config.md b/deps/npm/docs/content/using-npm/config.md
index a5017e61db..fe197e344d 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`
<!-- automatically generated, do not edit manually -->
<!-- see lib/utils/config/definitions.js -->
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 0000000000..b7c5e89977
--- /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 fba37c2860..737cef3f43 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 fc29907225..c2ecce5ef4 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 e344845a34..9fd0fb148a 100644
--- a/deps/npm/docs/output/commands/npm-ls.html
+++ b/deps/npm/docs/output/commands/npm-ls.html
@@ -160,7 +160,7 @@ tree at all, use <a href="../commands/npm-explain.html"><code>npm explain</code>
the results to only the paths to the packages named. Note that nested
packages will <em>also</em> show the paths to the specified packages. For
example, running <code>npm ls promzard</code> in npm's source tree will show:</p>
-<pre lang="bash"><code>npm@8.1.4 /path/to/npm
+<pre lang="bash"><code>npm@8.2.0 /path/to/npm
└─┬ init-package-json@0.0.4
└── promzard@0.1.5
</code></pre>
diff --git a/deps/npm/docs/output/commands/npm.html b/deps/npm/docs/output/commands/npm.html
index dd111c40be..8f1c16a442 100644
--- a/deps/npm/docs/output/commands/npm.html
+++ b/deps/npm/docs/output/commands/npm.html
@@ -149,7 +149,7 @@ npm command-line interface
<pre lang="bash"><code>npm &lt;command&gt; [args]
</code></pre>
<h3 id="version">Version</h3>
-<p>8.1.4</p>
+<p>8.2.0</p>
<h3 id="description">Description</h3>
<p>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 639ef624bc..f3db847b48 100644
--- a/deps/npm/docs/output/using-npm/config.html
+++ b/deps/npm/docs/output/using-npm/config.html
@@ -962,8 +962,8 @@ Ideal if all users are on npm version 7 and higher.</p>
<li>Type: "silent", "error", "warn", "notice", "http", "timing", "info",
"verbose", or "silly"</li>
</ul>
-<p>What level of logs to report. On failure, <em>all</em> logs are written to
-<code>npm-debug.log</code> in the current working directory.</p>
+<p>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>
<p>Any logs of a higher level than the setting are shown. The default is
"notice".</p>
<p>See also the <code>foreground-scripts</code> config.</p>
@@ -1259,7 +1259,7 @@ rather than using npm's default semver range operator.</p>
<li>Default: false</li>
<li>Type: Boolean</li>
</ul>
-<p>Save installed packages. to a package.json file as <code>peerDependencies</code></p>
+<p>Save installed packages to a package.json file as <code>peerDependencies</code></p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<h4 id="save-prefix"><code>save-prefix</code></h4>
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 0000000000..d4b9760967
--- /dev/null
+++ b/deps/npm/docs/output/using-npm/logging.html
@@ -0,0 +1,203 @@
+<!DOCTYPE html><html><head>
+<meta charset="utf-8">
+<title>Logging</title>
+<style>
+body {
+ background-color: #ffffff;
+ color: #24292e;
+
+ margin: 0;
+
+ line-height: 1.5;
+
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
+}
+#rainbar {
+ height: 10px;
+ background-image: linear-gradient(139deg, #fb8817, #ff4b01, #c12127, #e02aff);
+}
+
+a {
+ text-decoration: none;
+ color: #0366d6;
+}
+a:hover {
+ text-decoration: underline;
+}
+
+pre {
+ margin: 1em 0px;
+ padding: 1em;
+ border: solid 1px #e1e4e8;
+ border-radius: 6px;
+
+ display: block;
+ overflow: auto;
+
+ white-space: pre;
+
+ background-color: #f6f8fa;
+ color: #393a34;
+}
+code {
+ font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;
+ font-size: 85%;
+ padding: 0.2em 0.4em;
+ background-color: #f6f8fa;
+ color: #393a34;
+}
+pre > code {
+ padding: 0;
+ background-color: inherit;
+ color: inherit;
+}
+h1, h2, h3 {
+ font-weight: 600;
+}
+
+#logobar {
+ background-color: #333333;
+ margin: 0 auto;
+ padding: 1em 4em;
+}
+#logobar .logo {
+ float: left;
+}
+#logobar .title {
+ font-weight: 600;
+ color: #dddddd;
+ float: left;
+ margin: 5px 0 0 1em;
+}
+#logobar:after {
+ content: "";
+ display: block;
+ clear: both;
+}
+
+#content {
+ margin: 0 auto;
+ padding: 0 4em;
+}
+
+#table_of_contents > h2 {
+ font-size: 1.17em;
+}
+#table_of_contents ul:first-child {
+ border: solid 1px #e1e4e8;
+ border-radius: 6px;
+ padding: 1em;
+ background-color: #f6f8fa;
+ color: #393a34;
+}
+#table_of_contents ul {
+ list-style-type: none;
+ padding-left: 1.5em;
+}
+#table_of_contents li {
+ font-size: 0.9em;
+}
+#table_of_contents li a {
+ color: #000000;
+}
+
+header.title {
+ border-bottom: solid 1px #e1e4e8;
+}
+header.title > h1 {
+ margin-bottom: 0.25em;
+}
+header.title > .description {
+ display: block;
+ margin-bottom: 0.5em;
+ line-height: 1;
+}
+
+footer#edit {
+ border-top: solid 1px #e1e4e8;
+ margin: 3em 0 4em 0;
+ padding-top: 2em;
+}
+</style>
+</head>
+<body>
+<div id="banner">
+<div id="rainbar"></div>
+<div id="logobar">
+<svg class="logo" role="img" height="32" width="32" viewBox="0 0 700 700">
+<polygon fill="#cb0000" points="0,700 700,700 700,0 0,0"></polygon>
+<polygon fill="#ffffff" points="150,550 350,550 350,250 450,250 450,550 550,550 550,150 150,150"></polygon>
+</svg>
+<div class="title">
+npm command-line interface
+</div>
+</div>
+</div>
+
+<section id="content">
+<header class="title">
+<h1 id="logging">Logging</h1>
+<span class="description">Why, What &amp; How we Log</span>
+</header>
+
+<section id="table_of_contents">
+<h2 id="table-of-contents">Table of contents</h2>
+<div id="_table_of_contents"><ul><li><a href="#description">Description</a></li><li><a href="#setting-log-levels">Setting Log Levels</a></li><ul><li><a href="#loglevel"><code>loglevel</code></a></li><ul><li><a href="#aliases">Aliases</a></li></ul><li><a href="#foreground-scripts"><code>foreground-scripts</code></a></li></ul><li><a href="#registry-response-headers">Registry Response Headers</a></li><ul><li><a href="#npm-notice"><code>npm-notice</code></a></li></ul><li><a href="#see-also">See also</a></li></ul></div>
+</section>
+
+<div id="_content"><h3 id="description">Description</h3>
+<p>The <code>npm</code> CLI has various mechanisms for showing different levels of information back to end-users for certain commands, configurations &amp; environments.</p>
+<h3 id="setting-log-levels">Setting Log Levels</h3>
+<h4 id="loglevel"><code>loglevel</code></h4>
+<p><code>loglevel</code> is a global argument/config that can be set to determine the type of information to be displayed.</p>
+<p>The default value of <code>loglevel</code> is <code>"notice"</code> but there are several levels/types of logs available, including:</p>
+<ul>
+<li><code>"silent"</code></li>
+<li><code>"error"</code></li>
+<li><code>"warn"</code></li>
+<li><code>"notice"</code></li>
+<li><code>"http"</code></li>
+<li><code>"timing"</code></li>
+<li><code>"info"</code></li>
+<li><code>"verbose"</code></li>
+<li><code>"silly"</code></li>
+</ul>
+<p>All logs pertaining to a level proceeding the current setting will be shown.</p>
+<p>All logs are written to a debug log, with the path to that file printed if the execution of a command fails.</p>
+<h5 id="aliases">Aliases</h5>
+<p>The log levels listed above have various corresponding aliases, including:</p>
+<ul>
+<li><code>-d</code>: <code>--loglevel info</code></li>
+<li><code>--dd</code>: <code>--loglevel verbose</code></li>
+<li><code>--verbose</code>: <code>--loglevel verbose</code></li>
+<li><code>--ddd</code>: <code>--loglevel silly</code></li>
+<li><code>-q</code>: <code>--loglevel warn</code></li>
+<li><code>--quiet</code>: <code>--loglevel warn</code></li>
+<li><code>-s</code>: <code>--loglevel silent</code></li>
+<li><code>--silent</code>: <code>--loglevel silent</code></li>
+</ul>
+<h4 id="foreground-scripts"><code>foreground-scripts</code></h4>
+<p>The <code>npm</code> CLI began hiding the output of lifecycle scripts for <code>npm install</code> as of <code>v7</code>. 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 <code>package.json</code>. If you'd like to change this behavior &amp; log this output you can set <code>foreground-scripts</code> to <code>true</code>.</p>
+<h3 id="registry-response-headers">Registry Response Headers</h3>
+<h4 id="npm-notice"><code>npm-notice</code></h4>
+<p>The <code>npm</code> CLI reads from &amp; logs any <code>npm-notice</code> 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>
+<p>This header is not cached, and will not be logged if the request is served from the cache.</p>
+<h3 id="see-also">See also</h3>
+<ul>
+<li><a href="../using-npm/config.html">config</a></li>
+</ul>
+</div>
+
+<footer id="edit">
+<a href="https://github.com/npm/cli/edit/latest/docs/content/using-npm/logging.md">
+<svg role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentcolor" style="vertical-align: text-bottom; margin-right: 0.3em;">
+<path fill-rule="evenodd" d="M11.013 1.427a1.75 1.75 0 012.474 0l1.086 1.086a1.75 1.75 0 010 2.474l-8.61 8.61c-.21.21-.47.364-.756.445l-3.251.93a.75.75 0 01-.927-.928l.929-3.25a1.75 1.75 0 01.445-.758l8.61-8.61zm1.414 1.06a.25.25 0 00-.354 0L10.811 3.75l1.439 1.44 1.263-1.263a.25.25 0 000-.354l-1.086-1.086zM11.189 6.25L9.75 4.81l-6.286 6.287a.25.25 0 00-.064.108l-.558 1.953 1.953-.558a.249.249 0 00.108-.064l6.286-6.286z"></path>
+</svg>
+Edit this page on GitHub
+</a>
+</footer>
+</section>
+
+
+
+</body></html> \ 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 3a51b05707..19082719ef 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 file, then your package scripts would have the
<code>npm_package_version</code> set to "1.2.5". You can access these variables
in your code with <code>process.env.npm_package_name</code> and
<code>process.env.npm_package_version</code>, and so on for other fields.</p>
-<p>See <a href="../configuring-npm/package-json.html"><code>package-json.md</code></a> for more on package configs.</p>
+<p>See <a href="../configuring-npm/package-json.html"><code>package.json</code></a> for more on package configs.</p>
<h4 id="current-lifecycle-event">current lifecycle event</h4>
<p>Lastly, the <code>npm_lifecycle_event</code> 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 6f5a23e749..42f10e5f3d 100644
--- a/deps/npm/docs/output/using-npm/workspaces.html
+++ b/deps/npm/docs/output/using-npm/workspaces.html
@@ -148,7 +148,7 @@ npm command-line interface
<div id="_content"><h3 id="description">Description</h3>
<p><strong>Workspaces</strong> 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.</p>
+file system from within a singular top-level, root package.</p>
<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
as part of <code>npm install</code> and avoiding manually having to use <code>npm link</code> in
diff --git a/deps/npm/lib/auth/legacy.js b/deps/npm/lib/auth/legacy.js
index 2da82e361d..d1401ce14b 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 6fcfc30e5d..795eb8972a 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 9dcd9d04d2..3d0c32d4be 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 6cd6d3001c..1cf70fffbf 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 8f5ae0cc52..bb700d45a8 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 8ca8188ccd..5dfd1eb918 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 b1c045bbfa..ecb34cb891 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 e928a01d15..2c2f8da866 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 0cdcd576f5..eb1d570c6e 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 e1eafbe3bc..cc4b119d09 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 3134f502ea..d737a58dc4 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 fa79b293c5..bf2dffe912 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 9aba242057..19cd735642 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 6b8878b6f4..47a522eb67 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 515ac910f8..61a6d96595 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 f94fff01c4..90e6af69fe 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 81c6d9a1b0..47a51c33a6 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 eaca2716ee..7e8a8f7a5c 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 02ccb57248..a92a5edc5e 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 8755af6f68..e8e2c6b349 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 e17b2b8790..4e6bab9859 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 8f0b1f1eff..c027ad6464 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 d84dde86e8..0719fa3b85 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 a049d24127..993e029d45 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 0939013cc2..1250ed7d1c 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 403575e024..5831df6285 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 88ddcae7bb..ad538668b6 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 cc68e85650..8ac4178f26 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 37140c8c53..cd877e0b3d 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 ff533ebbd1..bdeeffe816 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 58fd2726db..7c73ff01b9 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 dfb3c8e381..05e3f6d278 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 1bbd25efda..ec11605899 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 1260655d07..f45ec846dc 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 db23742038..df80f1afec 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 dba45e127a..b40c59bda4 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 3636dc58a6..578890025d 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 4bb74990be..a8bbc4c969 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 105ebc16df..4f7464ddd7 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 ecc7f0a7de..4d22b531a4 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 b4ab26fd0c..7feccc739b 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 8fb0fa1550..0000000000
--- 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 b47a46de85..ac8a4e2f67 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 dd89fb5a4f..0a3c8c90bc 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 0000000000..aae51e8806
--- /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 48ad4676f4..4d584346d0 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 5b2811468e..3243466242 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('', ' <https://github.com/npm/cli/issues>')
- // 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('', ' <https://github.com/npm/cli/issues>')
+ 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 dc1b4deba3..0000000000
--- 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 0000000000..b37fd23e07
--- /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 0000000000..9d5a36d967
--- /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 2cfe94ecb0..0000000000
--- 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 a88b8aacd8..2229414147 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 993aa886f6..ac24396c6a 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 7741b72200..b4114c1b2f 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 05ca38c828..0000000000
--- 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 26e7a98df6..2f2773c6d4 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 0000000000..acff29eb05
--- /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 5f6a341a83..75aad5e780 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 2b45d54c81..44b6a5433c 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 e23e50c51c..39eaa45e41 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 0000000000..481b5696dd
--- /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 6ee369df5a..e6786f2a04 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 10d035f753..859088196e 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 4f2c25c675..9279f1f6e8 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 927373bc4b..fa1abc087e 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 2356611d4c..857b78727a 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 1f93ecf7e5..0ae5e8251e 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 9e9951fbbf..fdd6edbdc0 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 c79b8b0d88..93b7785ec9 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 87b2e4082b..8b667c03d9 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 e619784485..dff883b827 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 a4eb24c0be..f83b46a156 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 74e801df1e..e730b597a6 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 5d52da1d13..e2bd3c0e28 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 edbeef32a4..d0f2ce82c2 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 9c371ff0cc..3b863eddab 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 b8b0404eb5..4d3bf1711d 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 6d6100c15d..545d799306 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 239c988cf5..91a66ff3f5 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 8f0097241d..79e4e5a7df 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 49fff29263..bd157ab7fd 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 de01552c76..488dd168c6 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 12ee237f06..8566e38185 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 aa62e72ac0..260a253fed 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 8ebd352d87..609604155b 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 65108e2c07..8119ff10fd 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 df9f22e7da..5b2e09cf1c 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 7250721f6d..451ae94e87 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 7f0c422ded..cf93650b30 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 83700438ce..b15ac7bce6 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 a9f0ebe55e..17534e845f 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 784b338ec9..5320cc51fb 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 c92d90a759..3ca826bd6c 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 6477c2ea0d..e596e77c34 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 a7d6b45b74..289d67a668 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 13bc733666..42ab2fa74f 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 75db070280..885cbd837d 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 aaa37abe84..dcb6a8bb4d 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 f986f28c75..259b85e7ee 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 e3a365ecd1..176afb69c2 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 4fb47b337b..54204593ff 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 6657ee20e5..ca9a3041bf 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 1f5ecab8dd..5b0e96d04b 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 e763152ac8..178816429a 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 d113d2fdb6..37060c2b6f 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 24b6a36e23..9ac47bbeb3 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 da566d33f2..22b80dbf02 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 281ad48c3f..5b16ae5bab 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 453a2ccec6..960d5d81fa 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 793c13d6d7..166ec5da10 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 ed2cb43004..7b580abec8 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 93221b69d1..3cf9bdc96e 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 ca5d0490ed..66b9a935ff 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 ff301333aa..daf293986b 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 97e06883db..a75060f1b2 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 abff79323a..44e0d716c8 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 99476c0ce1..a1ff1bc883 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 16af51f32e..f1015a4174 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 8d3b3e0298..052d7ef4c4 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 c61a8a5bd5..ef9fe6e386 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 800b69de2d..4188dda6b1 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 ebe993deb5..73fcf0bdfa 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 5af03df4b3..4ff00fa934 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 e3c7524455..bd3aea36aa 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 5bd83235ff..bddb695d55 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 <command> [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 46c9be0529..f210e94f09 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 859e3b38bf..7b0161242f 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 99a90dcaaf..1879e6557f 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 9fdb54c6b1..05f6cf4fd8 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 60c03a8c14..33f011e795 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 857d564953..6f38ff876b 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 8544d70b71..22cccd59d3 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 2157f70cce..c366ec1bef 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
<!\-\- automatically generated, do not edit manually \-\->
<!\-\- see lib/utils/config/definitions\.js \-\->
diff --git a/deps/npm/man/man7/developers.7 b/deps/npm/man/man7/developers.7
index 9461ca9fc8..017beab9da 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 0000000000..9098c38849
--- /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 a6664a1dac..32941be2f6 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 6b46806bf0..3f5a28edcd 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 24d66dfa92..daf2873184 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 f5fa03206b..d4702277a7 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 9d1659eeee..2c121b1f4a 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 c72ae28b11..c809092741 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 724ce14c38..e52f7a14f7 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 f36d8f7b11..299202ec2d 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 d3901a86d6..5714e09c3b 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 0432fe6a30..0000000000
--- 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 654d0bfe94..0000000000
--- a/deps/npm/node_modules/code-point-at/license
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (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 c5907a5078..0000000000
--- 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 4c97730e69..0000000000
--- 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 e5d1a4d065..1e54fd69a6 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 01ad5642b2..0777687c22 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 2a4982dc40..0000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/aproba/LICENSE
+++ /dev/null
@@ -1,13 +0,0 @@
-Copyright (c) 2015, Rebecca Turner <me@re-becca.org>
-
-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 6f3f797c09..0000000000
--- 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 f008787bc2..0000000000
--- 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 <me@re-becca.org>",
- "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 e756052969..0000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/gauge/LICENSE
+++ /dev/null
@@ -1,13 +0,0 @@
-Copyright (c) 2014, Rebecca Turner <me@re-becca.org>
-
-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 0b67638e02..0000000000
--- 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 d9914ba533..0000000000
--- 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 e283a256f2..0000000000
--- 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 c55324008c..0000000000
--- 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 4882cff839..0000000000
--- 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 <me@re-becca.org>",
- "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 1afb4af6d5..0000000000
--- 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 05e85694d7..0000000000
--- 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 7f8dd68be2..0000000000
--- 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 3261bfbe6f..0000000000
--- 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 6650a485c4..0000000000
--- 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 576198793c..0000000000
--- 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 34142ee31a..0000000000
--- 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 4f02fefaa2..0000000000
--- 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 c022d61cf1..0000000000
--- 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 eb5a4f5b5e..0000000000
--- 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 c531bc491f..0000000000
--- 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 a7d3e3855f..0000000000
--- 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 654d0bfe94..0000000000
--- 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@gmail.com> (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 b678d40de7..0000000000
--- 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 19129e315f..0000000000
--- 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 341f3313ab..0000000000
--- 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 7220f8e72a..0000000000
--- a/deps/npm/node_modules/node-gyp/node_modules/npmlog/package.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "author": "Isaac Z. Schlueter <i@izs.me> (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 b9bec62440..0000000000
--- 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 654d0bfe94..0000000000
--- 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@gmail.com> (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 5ba436166e..0000000000
--- 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 ea06551817..fbeae5e20d 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 <nathan@tootallnate.net> (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 845be76f64..0000000000
--- 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 57d8743fda..0000000000
--- 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 6f43687557..0000000000
--- 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 9da13f8a7e..0000000000
--- 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 e1cf850557..0000000000
--- 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 a8f8b3ba01..0000000000
--- 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 5714e09c3b..0000000000
--- 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 79be4b9cb8..0000000000
--- 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 654d0bfe94..0000000000
--- a/deps/npm/node_modules/number-is-nan/license
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (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 d2f51d4b1d..0000000000
--- 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 2463508712..0000000000
--- 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 43456fef9a..f9ba8cd3c8 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 c7be15f0c7..12cd631045 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 a0d5795776..ddc80a9350 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 10d38cb3f8..72d09b44e2 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:
latest: 1.0.0
-published yesterday
+published {TIME} ago
`
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:
latest: 1.0.0
-published yesterday
+published {TIME} ago
`
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:
latest: 1.0.0
-published yesterday
+published {TIME} ago
`
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:
latest: 1.0.0
-published yesterday
+published {TIME} ago
blue@1.0.1 | Proprietary | deps: none | versions: 2
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 8c85225f2f..84bb22ff0e 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 1ebb336092..3db90f7679 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\`
<!-- automatically generated, do not edit manually -->
<!-- see lib/utils/config/definitions.js -->
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 f035285d70..069212cec3 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"
),
],
],
@@ -527,6 +532,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"
),
],
],
@@ -554,6 +563,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"
),
],
],
@@ -581,6 +594,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 eb383c104a..523aabca29 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 0000000000..ecce9eafcc
--- /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 0000000000..037155eea1
--- /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 0000000000..29da2a48b0
--- /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 0000000000..80037c6ffa
--- /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 a51ec3e5bb..7518855319 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 b012790fb5..701d9cea72 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 26db16e1f7..081c89cee9 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 7b61e9f6e9..0c23f8ba6b 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 d592205593..473c8cc241 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 d762943b47..f02c57d8cf 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 fdf132aff9..298897e4f5 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 71d79ea935..8a9358f9ab 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 3c87c76a8f..05f268d6bc 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 8c95dd57b2..9156d3df09 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 70a8ba1b20..fc92facff7 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 1091f9125b..537d0784f8 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 51212f06d8..dd571baf79 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 8fc0be0618..2e2fae2381 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 811936fe6d..ed0702e378 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 6b45dc1167..756a09d7de 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 e3ad5cc726..51b6111a0a 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 4ab26568f1..3c75c1d8d8 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 b2e7be2136..d1355d7671 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 c1b9c71df5..06bd097b6c 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 ba9e770e3e..597cccc3ff 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 74b33168ad..215ebc5811 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 994684596a..d5db3af673 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 39ef86c843..ee01e7500d 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 8645b349f8..b5d4d15842 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 <user> <pkg> 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 <user> <pkg> 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 <user> <pkg> 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 <user> <pkg> 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 <user> <pkg> 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 <user> <pkg> 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 bc88772086..21057e2079 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 7011c709b0..f808e0ac3b 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 6f059e73a7..e8295cf6a5 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 6554ca89e4..3d55a37ddb 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 <key> <value>', 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 49d5ab9be3..a7f56547b1 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 5f4fb40106..1178cd6ee1 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 4e61047b4e..93eb6d0311 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 608de0331d..7730f1a301 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 9871ddb25d..a886b30c3e 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 e421c655ef..ea0227cda0 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 592a2431c2..2c4fe57d68 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 a57ea1a540..feeb901571 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 db4021abd6..2b9e46c70c 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 13838bb105..9a49036422 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 4ed6438589..959739653d 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 1f26f38ead..4f7dc366db 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 4f189449ba..53d057b711 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 4e5ce289bc..a3dbd3ff4c 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 6d0dc9d7e0..65a094a0bc 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 6ac2067531..1424adf5c9 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 <pkg>@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 <pkg>@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 6ca6dbc87d..aecb2c32b5 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=<number>', 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=<number>', 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 6603b58106..980353897c 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 728787ec4a..035490a79f 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 dc6144ec1d..66c3f0c6b3 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 0000000000..02566e575a
--- /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 f813e50b22..248c81a30a 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 fb45331ba9..e5d7b558c2 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 1ccd26e375..2a0c5a89d2 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 c683053cbf..bcb7d8c16d 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 e97cf36b55..0000000000
--- 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 f6813a8bc0..bf4b48709a 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 = {}
// <config>: flat.retry[<option>]
@@ -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 185368d61f..d3cb3a24f0 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 0000000000..30cd2cc270
--- /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 1959b9217a..ddc88c1d99 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 adc7c3f4e9..54bf48f89b 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 9737b06433..0000000000
--- 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 94fde0ace1..0fbebdf8e3 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 0000000000..adc1a2e03f
--- /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 0000000000..dee4efbaa4
--- /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 77254a80d0..035d4bbb21 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 d580defa8a..0000000000
--- 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 acbf66396a..9f7a94614d 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 35101f1d70..be805a2a87 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 9a1bffb403..4e9ed7133c 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 7f907bc7e4..0000000000
--- 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 19d9491694..adc5cb3649 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 0000000000..6127f346b1
--- /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 4d806cefc4..2703044a22 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 78ff93825e..a7a800c602 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'])