diff options
author | Ruy Adorno <ruyadorno@hotmail.com> | 2020-12-04 15:51:55 -0500 |
---|---|---|
committer | Node.js GitHub Bot <github-bot@iojs.org> | 2020-12-09 15:17:41 +0000 |
commit | 8d8c7af1c0f99e8b7ee57ed154f965bbbc713c28 (patch) | |
tree | 0ccad68d3263d6dedab8c795e19f33bc2b3f29d4 /deps | |
parent | 348b7a9606da61fbb5437e27f479363114ecf4eb (diff) | |
download | ios-node-v8-8d8c7af1c0f99e8b7ee57ed154f965bbbc713c28.tar.gz ios-node-v8-8d8c7af1c0f99e8b7ee57ed154f965bbbc713c28.tar.bz2 ios-node-v8-8d8c7af1c0f99e8b7ee57ed154f965bbbc713c28.zip |
deps: upgrade npm to 7.1.0
PR-URL: https://github.com/nodejs/node/pull/36395
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Diffstat (limited to 'deps')
125 files changed, 1501 insertions, 488 deletions
diff --git a/deps/npm/AUTHORS b/deps/npm/AUTHORS index 33647f0927..008d909956 100644 --- a/deps/npm/AUTHORS +++ b/deps/npm/AUTHORS @@ -738,3 +738,4 @@ Hollow Man <hollowman@hollowman.ml> kai zhu <kaizhu256@gmail.com> Alex Woollam <alexjhwoollam@gmail.com> Daniel Fischer <daniel@d-fischer.dev> +Yash-Singh1 <saiansh2525@gmail.com> diff --git a/deps/npm/CHANGELOG.md b/deps/npm/CHANGELOG.md index a3a9984d24..cb9f013bc3 100644 --- a/deps/npm/CHANGELOG.md +++ b/deps/npm/CHANGELOG.md @@ -1,3 +1,37 @@ +## 7.1.0 (2020-12-04) + +### FEATURES + +* [`6b1575110`](https://github.com/npm/cli/commit/6b15751106beb99234aa4bf39ae05cf40076d42a) + [#2237](https://github.com/npm/cli/pull/2237) + add `npm set-script` command + ([@Yash-Singh1](https://github.com/Yash-Singh1)) +* [`15d7333f8`](https://github.com/npm/cli/commit/15d7333f832e3d68ae16895569f27a27ef86573e) + add interactive `npm exec` + ([@isaacs](https://github.com/isaacs)) + +### BUG FIXES + +* [`2a1192e4b`](https://github.com/npm/cli/commit/2a1192e4b03acdf6e6e24e58de68f736ab9bb35f) + [#2202](https://github.com/npm/cli/pull/2202) + Do not run interactive `npm exec` in CI when a TTY + ([@isaacs](https://github.com/isaacs)) + +### DOCUMENTATION + +* [`0599cc37d`](https://github.com/npm/cli/commit/0599cc37df453bf79d47490eb4fca3cd63f67f80) + [#2271](https://github.com/npm/cli/pull/2271) + don't wrap code block + ([@ethomson](https://github.com/ethomson)) + +### DEPENDENCIES + +* [`def85c726`](https://github.com/npm/cli/commit/def85c72640ffe2d27977c56b7aa06c6f6346ca9) + `@npmcli/arborist@1.0.14` + * fixes running `npm exec` from file system root folder +* [`4c94673ab`](https://github.com/npm/cli/commit/4c94673ab5399d27e5a48e52f7a65b038a456265) + `semver@7.3.4` + ## 7.0.15 (2020-11-27) ### DEPENDENCIES diff --git a/deps/npm/docs/content/commands/npm-dist-tag.md b/deps/npm/docs/content/commands/npm-dist-tag.md index 65ce22a179..585da16ad2 100644 --- a/deps/npm/docs/content/commands/npm-dist-tag.md +++ b/deps/npm/docs/content/commands/npm-dist-tag.md @@ -78,8 +78,8 @@ This command used to be known as `npm tag`, which only created new tags, and so had a different syntax. Tags must share a namespace with version numbers, because they are -specified in the same slot: `npm install <pkg>@<version>` vs `npm install -<pkg>@<tag>`. +specified in the same slot: `npm install <pkg>@<version>` vs +`npm install <pkg>@<tag>`. Tags that can be interpreted as valid semver ranges will be rejected. For example, `v1.4` cannot be used as a tag, because it is interpreted by diff --git a/deps/npm/docs/content/commands/npm-exec.md b/deps/npm/docs/content/commands/npm-exec.md index c9de9933be..3ae30fa0cb 100644 --- a/deps/npm/docs/content/commands/npm-exec.md +++ b/deps/npm/docs/content/commands/npm-exec.md @@ -16,9 +16,11 @@ npx <pkg>[@<specifier>] [args...] npx -p <pkg>[@<specifier>] <cmd> [args...] npx -c '<cmd> [args...]' npx -p <pkg>[@<specifier>] -c '<cmd> [args...]' +Run without --call or positional args to open interactive subshell alias: npm x, npx +common options: --package=<pkg> (may be specified multiple times) -p is a shorthand for --package only when using npx executable -c <cmd> --call=<cmd> (may not be mixed with positional arguments) @@ -30,6 +32,11 @@ This command allows you to run an arbitrary command from an npm package (either one installed locally, or fetched remotely), in a similar context as running it via `npm run`. +Run without positional arguments or `--call`, this allows you to +interactively run commands in the same sort of shell environment that +`package.json` scripts are run. Interactive mode is not supported in CI +environments when standard input is a TTY, to prevent hangs. + Whatever packages are specified by the `--package` option will be provided in the `PATH` of the executed command, along with any locally installed package executables. The `--package` option may be diff --git a/deps/npm/docs/content/commands/npm-set-script.md b/deps/npm/docs/content/commands/npm-set-script.md new file mode 100644 index 0000000000..7bc8f75d23 --- /dev/null +++ b/deps/npm/docs/content/commands/npm-set-script.md @@ -0,0 +1,34 @@ +--- +title: npm-set-script +section: 1 +description: Set tasks in the scripts section of package.json +--- + +### Synopsis +An npm command that lets you create a task in the scripts section of the package.json. + +```bash +npm set-script [<script>] [<command>] +``` + + +**Example:** + +* `npm set-script start "http-server ."` + +```json +{ + "name": "my-project", + "scripts": { + "start": "http-server .", + "test": "some existing value" + } +} +``` + +### See Also + +* [npm run-script](/commands/npm-run-script) +* [npm install](/commands/npm-install) +* [npm test](/commands/npm-test) +* [npm start](/commands/npm-start) diff --git a/deps/npm/docs/output/commands/npm-dist-tag.html b/deps/npm/docs/output/commands/npm-dist-tag.html index 39d3310ecd..41d39176fa 100644 --- a/deps/npm/docs/output/commands/npm-dist-tag.html +++ b/deps/npm/docs/output/commands/npm-dist-tag.html @@ -201,7 +201,8 @@ versions such as prereleases.</p> <p>This command used to be known as <code>npm tag</code>, which only created new tags, and so had a different syntax.</p> <p>Tags must share a namespace with version numbers, because they are -specified in the same slot: <code>npm install <pkg>@<version></code> vs <code>npm install <pkg>@<tag></code>.</p> +specified in the same slot: <code>npm install <pkg>@<version></code> vs +<code>npm install <pkg>@<tag></code>.</p> <p>Tags that can be interpreted as valid semver ranges will be rejected. For example, <code>v1.4</code> cannot be used as a tag, because it is interpreted by semver as <code>>=1.4.0 <1.5.0</code>. See <a href="https://github.com/npm/npm/issues/6082">https://github.com/npm/npm/issues/6082</a>.</p> diff --git a/deps/npm/docs/output/commands/npm-exec.html b/deps/npm/docs/output/commands/npm-exec.html index 6e50a1cb9a..ecee5f0143 100644 --- a/deps/npm/docs/output/commands/npm-exec.html +++ b/deps/npm/docs/output/commands/npm-exec.html @@ -154,9 +154,11 @@ npx <pkg>[@<specifier>] [args...] npx -p <pkg>[@<specifier>] <cmd> [args...] npx -c '<cmd> [args...]' npx -p <pkg>[@<specifier>] -c '<cmd> [args...]' +Run without --call or positional args to open interactive subshell alias: npm x, npx +common options: --package=<pkg> (may be specified multiple times) -p is a shorthand for --package only when using npx executable -c <cmd> --call=<cmd> (may not be mixed with positional arguments) @@ -165,6 +167,10 @@ alias: npm x, npx <p>This command allows you to run an arbitrary command from an npm package (either one installed locally, or fetched remotely), in a similar context as running it via <code>npm run</code>.</p> +<p>Run without positional arguments or <code>--call</code>, this allows you to +interactively run commands in the same sort of shell environment that +<code>package.json</code> scripts are run. Interactive mode is not supported in CI +environments when standard input is a TTY, to prevent hangs.</p> <p>Whatever packages are specified by the <code>--package</code> option will be provided in the <code>PATH</code> of the executed command, along with any locally installed package executables. The <code>--package</code> option may be diff --git a/deps/npm/docs/output/commands/npm-ls.html b/deps/npm/docs/output/commands/npm-ls.html index 39519f2971..b0e067c15e 100644 --- a/deps/npm/docs/output/commands/npm-ls.html +++ b/deps/npm/docs/output/commands/npm-ls.html @@ -156,7 +156,7 @@ installed, as well as their dependencies, in a tree-structure.</p> limit 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@7.0.15 /path/to/npm +<pre lang="bash"><code> npm@7.1.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-set-script.html b/deps/npm/docs/output/commands/npm-set-script.html new file mode 100644 index 0000000000..8594e62b6a --- /dev/null +++ b/deps/npm/docs/output/commands/npm-set-script.html @@ -0,0 +1,184 @@ +<html><head> +<title>npm-set-script</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="npm-set-script">npm-set-script</h1> +<span class="description">Set tasks in the scripts section of package.json</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="#synopsis">Synopsis</a></li><li><a href="#see-also">See Also</a></li></ul></div> +</section> + +<div id="_content"><h3 id="synopsis">Synopsis</h3> +<p>An npm command that lets you create a task in the scripts section of the package.json.</p> +<pre lang="bash"><code>npm set-script [<script>] [<command>] +</code></pre> +<p><strong>Example:</strong></p> +<ul> +<li><code>npm set-script start "http-server ."</code></li> +</ul> +<pre lang="json"><code>{ + "name": "my-project", + "scripts": { + "start": "http-server .", + "test": "some existing value" + } +} +</code></pre> +<h3 id="see-also">See Also</h3> +<ul> +<li><a href="../commands/npm-run-script.html">npm run-script</a></li> +<li><a href="../commands/npm-install.html">npm install</a></li> +<li><a href="../commands/npm-test.html">npm test</a></li> +<li><a href="../commands/npm-start.html">npm start</a></li> +</ul> +</div> + +<footer id="edit"> +<a href="https://github.com/npm/cli/edit/latest/docs/content/commands/npm-set-script.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/commands/npm.html b/deps/npm/docs/output/commands/npm.html index 2e8ed9e710..15491711a6 100644 --- a/deps/npm/docs/output/commands/npm.html +++ b/deps/npm/docs/output/commands/npm.html @@ -148,7 +148,7 @@ npm command-line interface <pre lang="bash"><code>npm <command> [args] </code></pre> <h3 id="version">Version</h3> -<p>7.0.15</p> +<p>7.1.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/lib/exec.js b/deps/npm/lib/exec.js index 6bcaf838ed..d4bcac0252 100644 --- a/deps/npm/lib/exec.js +++ b/deps/npm/lib/exec.js @@ -1,7 +1,6 @@ const npm = require('./npm.js') - +const output = require('./utils/output.js') const usageUtil = require('./utils/usage.js') - const usage = usageUtil('exec', 'Run a command from a local or remote npm package.\n\n' + @@ -13,7 +12,9 @@ const usage = usageUtil('exec', 'npx <pkg>[@<specifier>] [args...]\n' + 'npx -p <pkg>[@<specifier>] <cmd> [args...]\n' + 'npx -c \'<cmd> [args...]\'\n' + - 'npx -p <pkg>[@<specifier>] -c \'<cmd> [args...]\'', + 'npx -p <pkg>[@<specifier>] -c \'<cmd> [args...]\'' + + '\n' + + 'Run without --call or positional args to open interactive subshell\n', '\n--package=<pkg> (may be specified multiple times)\n' + '-p is a shorthand for --package only when using npx executable\n' + @@ -59,15 +60,14 @@ const ciDetect = require('@npmcli/ci-detect') const crypto = require('crypto') const pacote = require('pacote') const npa = require('npm-package-arg') -const escapeArg = require('./utils/escape-arg.js') const fileExists = require('./utils/file-exists.js') const PATH = require('./utils/path.js') const cmd = (args, cb) => exec(args).then(() => cb()).catch(cb) -const run = async ({ args, call, pathArr }) => { +const run = async ({ args, call, pathArr, shell }) => { // turn list of args into command string - const script = call || args.map(escapeArg).join(' ').trim() + const script = call || args.join(' ').trim() || shell // do the fakey runScript dance // still should work if no package.json in cwd @@ -83,7 +83,15 @@ const run = async ({ args, call, pathArr }) => { npm.log.disableProgress() try { + if (script === shell) { + if (process.stdin.isTTY) { + if (ciDetect()) + return npm.log.warn('exec', 'Interactive mode disabled in CI environment') + output(`\nEntering npm script environment\nType 'exit' or ^D when finished\n`) + } + } return await runScript({ + ...npm.flatOptions, pkg, banner: false, // we always run in cwd, not --prefix @@ -101,13 +109,23 @@ const run = async ({ args, call, pathArr }) => { } const exec = async args => { - const { package: packages, call } = npm.flatOptions + const { package: packages, call, shell } = npm.flatOptions if (call && args.length) throw usage const pathArr = [...PATH] + // nothing to maybe install, skip the arborist dance + if (!call && !args.length && !packages.length) { + return await run({ + args, + call, + shell, + pathArr, + }) + } + const needPackageCommandSwap = args.length && !packages.length // if there's an argument and no package has been explicitly asked for // check the local and global bin paths for a binary named the same as @@ -126,8 +144,9 @@ const exec = async args => { if (binExists) { return await run({ args, - call: [args[0], ...args.slice(1).map(escapeArg)].join(' ').trim(), + call: [args[0], ...args.slice(1)].join(' ').trim(), pathArr, + shell, }) } @@ -181,15 +200,18 @@ const exec = async args => { // no need to install if already present if (add.length) { - const isTTY = process.stdin.isTTY && process.stdout.isTTY if (!npm.flatOptions.yes) { // set -n to always say no if (npm.flatOptions.yes === false) throw 'canceled' - if (!isTTY || ciDetect()) - npm.log.warn('exec', `The following package${add.length === 1 ? ' was' : 's were'} not found and will be installed: ${add.map((pkg) => pkg.replace(/@$/, '')).join(', ')}`) - else { + if (!process.stdin.isTTY || ciDetect()) { + npm.log.warn('exec', `The following package${ + add.length === 1 ? ' was' : 's were' + } not found and will be installed: ${ + add.map((pkg) => pkg.replace(/@$/, '')).join(', ') + }`) + } else { const addList = add.map(a => ` ${a.replace(/@$/, '')}`) .join('\n') + '\n' const prompt = `Need to install the following packages:\n${ @@ -205,7 +227,7 @@ const exec = async args => { pathArr.unshift(resolve(installDir, 'node_modules/.bin')) } - return await run({ args, call, pathArr }) + return await run({ args, call, pathArr, shell }) } const manifestMissing = (tree, mani) => { diff --git a/deps/npm/lib/explore.js b/deps/npm/lib/explore.js index 96221cb497..e9b09707ec 100644 --- a/deps/npm/lib/explore.js +++ b/deps/npm/lib/explore.js @@ -4,59 +4,65 @@ const usageUtil = require('./utils/usage.js') const completion = require('./utils/completion/installed-shallow.js') const usage = usageUtil('explore', 'npm explore <pkg> [ -- <command>]') +const rpj = require('read-package-json-fast') const cmd = (args, cb) => explore(args).then(() => cb()).catch(cb) const output = require('./utils/output.js') const npm = require('./npm.js') -const isWindows = require('./utils/is-windows.js') -const escapeArg = require('./utils/escape-arg.js') -const escapeExecPath = require('./utils/escape-exec-path.js') -const log = require('npmlog') -const spawn = require('@npmcli/promise-spawn') - -const { resolve } = require('path') -const { promisify } = require('util') -const stat = promisify(require('fs').stat) +const runScript = require('@npmcli/run-script') +const { join, resolve, relative } = require('path') const explore = async args => { if (args.length < 1 || !args[0]) throw usage - const pkg = args.shift() - const cwd = resolve(npm.dir, pkg) - const opts = { cwd, stdio: 'inherit', stdioString: true } - - const shellArgs = [] - if (args.length) { - if (isWindows) { - const execCmd = escapeExecPath(args.shift()) - opts.windowsVerbatimArguments = true - shellArgs.push('/d', '/s', '/c', execCmd, ...args.map(escapeArg)) - } else - shellArgs.push('-c', args.map(escapeArg).join(' ').trim()) - } + const pkgname = args.shift() - await stat(cwd).catch(er => { - throw new Error(`It doesn't look like ${pkg} is installed.`) - }) + // detect and prevent any .. shenanigans + const path = join(npm.dir, join('/', pkgname)) + if (relative(path, npm.dir) === '') + throw usage - const sh = npm.flatOptions.shell - log.disableProgress() + // run as if running a script named '_explore', which we set to either + // the set of arguments, or the shell config, and let @npmcli/run-script + // handle all the escaping and PATH setup stuff. - if (!shellArgs.length) - output(`\nExploring ${cwd}\nType 'exit' or ^D when finished\n`) + const pkg = await rpj(resolve(path, 'package.json')).catch(er => { + npm.log.error('explore', `It doesn't look like ${pkgname} is installed.`) + throw er + }) - log.silly('explore', { sh, shellArgs, opts }) + const { shell } = npm.flatOptions + pkg.scripts = { + ...(pkg.scripts || {}), + _explore: args.join(' ').trim() || shell, + } - // only noisily fail if non-interactive, but still keep exit code intact - const proc = spawn(sh, shellArgs, opts) + if (!args.length) + output(`\nExploring ${path}\nType 'exit' or ^D when finished\n`) + npm.log.disableProgress() try { - const res = await (shellArgs.length ? proc : proc.catch(er => er)) - process.exitCode = res.code + return await runScript({ + ...npm.flatOptions, + pkg, + banner: false, + path, + stdioString: true, + event: '_explore', + stdio: 'inherit', + }).catch(er => { + process.exitCode = typeof er.code === 'number' && er.code !== 0 ? er.code + : 1 + // if it's not an exit error, or non-interactive, throw it + const isProcExit = er.message === 'command failed' && + (typeof er.code === 'number' || /^SIG/.test(er.signal || '')) + if (args.length || !isProcExit) + throw er + }) } finally { - log.enableProgress() + npm.log.enableProgress() } } diff --git a/deps/npm/lib/set-script.js b/deps/npm/lib/set-script.js new file mode 100644 index 0000000000..4dfc67fbbe --- /dev/null +++ b/deps/npm/lib/set-script.js @@ -0,0 +1,55 @@ +'use strict' + +const log = require('npmlog') +const usageUtil = require('./utils/usage.js') +const { localPrefix } = require('./npm.js') +const fs = require('fs') +const usage = usageUtil('set-script', 'npm set-script [<script>] [<command>]') +const completion = require('./utils/completion/none.js') +const parseJSON = require('json-parse-even-better-errors') +const rpj = require('read-package-json-fast') + +const cmd = (args, cb) => set(args).then(() => cb()).catch(cb) + +const set = async function (args) { + if (process.env.npm_lifecycle_event === 'postinstall') + throw new Error('Scripts can’t set from the postinstall script') + + // Parse arguments + if (args.length !== 2) + throw new Error(`Expected 2 arguments: got ${args.length}`) + + // Set the script + let manifest + let warn = false + try { + manifest = fs.readFileSync(localPrefix + '/package.json', 'utf-8') + } catch (error) { + throw new Error('package.json not found') + } + try { + manifest = parseJSON(manifest) + } catch (error) { + throw new Error(`Invalid package.json: ${error}`) + } + if (!manifest.scripts) + manifest.scripts = {} + if (manifest.scripts[args[0]] && manifest.scripts[args[0]] !== args[1]) + warn = true + manifest.scripts[args[0]] = args[1] + // format content + const packageJsonInfo = await rpj(localPrefix + '/package.json') + const { + [Symbol.for('indent')]: indent, + [Symbol.for('newline')]: newline, + } = packageJsonInfo + const format = indent === undefined ? ' ' : indent + const eol = newline === undefined ? '\n' : newline + const content = (JSON.stringify(manifest, null, format) + '\n') + .replace(/\n/g, eol) + fs.writeFileSync(localPrefix + '/package.json', content) + if (warn) + log.warn('set-script', `Script "${args[0]}" was overwritten`) +} + +module.exports = Object.assign(cmd, { usage, completion }) diff --git a/deps/npm/lib/uninstall.js b/deps/npm/lib/uninstall.js index dbaa992f50..4f63abfafc 100644 --- a/deps/npm/lib/uninstall.js +++ b/deps/npm/lib/uninstall.js @@ -1,11 +1,18 @@ -// remove a package. +'use strict' +const { resolve } = require('path') const Arborist = require('@npmcli/arborist') -const npm = require('./npm.js') const rpj = require('read-package-json-fast') -const { resolve } = require('path') + +const npm = require('./npm.js') const usageUtil = require('./utils/usage.js') const reifyFinish = require('./utils/reify-finish.js') +const completion = require('./utils/completion/installed-shallow.js') + +const usage = usageUtil( + 'uninstall', + 'npm uninstall [<@scope>/]<pkg>[@<version>]... [--save-prod|--save-dev|--save-optional] [--no-save]' +) const cmd = (args, cb) => rm(args).then(() => cb()).catch(cb) @@ -16,12 +23,19 @@ const rm = async args => { if (!args.length) { if (!global) - throw new Error('must provide a package name to remove') + throw new Error('Must provide a package name to remove') else { - const pkg = await rpj(resolve(npm.localPrefix, 'package.json')) - .catch(er => { - throw er.code !== 'ENOENT' && er.code !== 'ENOTDIR' ? er : usage() - }) + let pkg + + try { + pkg = await rpj(resolve(npm.localPrefix, 'package.json')) + } catch (er) { + if (er.code !== 'ENOENT' && er.code !== 'ENOTDIR') + throw er + else + throw usage + } + args.push(pkg.name) } } @@ -35,11 +49,4 @@ const rm = async args => { await reifyFinish(arb) } -const usage = usageUtil( - 'uninstall', - 'npm uninstall [<@scope>/]<pkg>[@<version>]... [--save-prod|--save-dev|--save-optional] [--no-save]' -) - -const completion = require('./utils/completion/installed-shallow.js') - module.exports = Object.assign(cmd, { usage, completion }) diff --git a/deps/npm/lib/update.js b/deps/npm/lib/update.js index 0a786e30f3..dd6b0d09ff 100644 --- a/deps/npm/lib/update.js +++ b/deps/npm/lib/update.js @@ -1,7 +1,10 @@ +'use strict' + const path = require('path') -const Arborist = require('@npmcli/arborist') +const Arborist = require('@npmcli/arborist') const log = require('npmlog') + const npm = require('./npm.js') const usageUtil = require('./utils/usage.js') const reifyFinish = require('./utils/reify-finish.js') diff --git a/deps/npm/lib/utils/cmd-list.js b/deps/npm/lib/utils/cmd-list.js index 8d8c898d94..8c092e719c 100644 --- a/deps/npm/lib/utils/cmd-list.js +++ b/deps/npm/lib/utils/cmd-list.js @@ -127,6 +127,7 @@ const cmdList = [ 'start', 'restart', 'run-script', + 'set-script', 'completion', 'doctor', 'exec', diff --git a/deps/npm/lib/utils/depr-check.js b/deps/npm/lib/utils/depr-check.js deleted file mode 100644 index aa728a3363..0000000000 --- a/deps/npm/lib/utils/depr-check.js +++ /dev/null @@ -1,22 +0,0 @@ -'use strict' - -const log = require('npmlog') - -const deprecated = {} -const deprWarned = {} - -module.exports = deprCheck -function deprCheck (data) { - if (deprecated[data._id]) - data.deprecated = deprecated[data._id] - - if (data.deprecated) { - deprecated[data._id] = data.deprecated - if (!deprWarned[data._id]) { - deprWarned[data._id] = true - log.warn('deprecated', '%s: %s', data._id, data.deprecated) - } - } - - return data -} diff --git a/deps/npm/lib/utils/escape-arg.js b/deps/npm/lib/utils/escape-arg.js deleted file mode 100644 index 135d380fc2..0000000000 --- a/deps/npm/lib/utils/escape-arg.js +++ /dev/null @@ -1,18 +0,0 @@ -const { normalize } = require('path') -const isWindows = require('./is-windows.js') - -/* -Escape the name of an executable suitable for passing to the system shell. - -Windows is easy, wrap in double quotes and you're done, as there's no -facility to create files with quotes in their names. - -Unix-likes are a little more complicated, wrap in single quotes and escape -any single quotes in the filename. The '"'"' construction ends the quoted -block, creates a new " quoted string with ' in it. So, `foo'bar` becomes -`'foo'"'"'bar'`, which is the bash way of saying `'foo' + "'" + 'bar'`. -*/ - -module.exports = str => isWindows ? '"' + normalize(str) + '"' - : /[^-_.~/\w]/.test(str) ? "'" + str.replace(/'/g, '\'"\'"\'') + "'" - : str diff --git a/deps/npm/lib/utils/escape-exec-path.js b/deps/npm/lib/utils/escape-exec-path.js deleted file mode 100644 index 83c70680b4..0000000000 --- a/deps/npm/lib/utils/escape-exec-path.js +++ /dev/null @@ -1,21 +0,0 @@ -const { normalize } = require('path') -const isWindows = require('./is-windows.js') - -/* -Escape the name of an executable suitable for passing to the system shell. - -Windows is easy, wrap in double quotes and you're done, as there's no -facility to create files with quotes in their names. - -Unix-likes are a little more complicated, wrap in single quotes and escape -any single quotes in the filename. The '"'"' construction ends the quoted -block, creates a new " quoted string with ' in it. So, `foo'bar` becomes -`'foo'"'"'bar'`, which is the bash way of saying `'foo' + "'" + 'bar'`. -*/ - -const winQuote = str => !/ /.test(str) ? str : '"' + str + '"' -const winEsc = str => normalize(str).split(/\\/).map(winQuote).join('\\') - -module.exports = str => isWindows ? winEsc(str) - : /[^-_.~/\w]/.test(str) ? "'" + str.replace(/'/g, '\'"\'"\'') + "'" - : str diff --git a/deps/npm/lib/utils/package-id.js b/deps/npm/lib/utils/package-id.js deleted file mode 100644 index 4048aee4f7..0000000000 --- a/deps/npm/lib/utils/package-id.js +++ /dev/null @@ -1,15 +0,0 @@ -'use strict' -var moduleName = require('./module-name.js') - -module.exports = function (tree) { - var pkg = tree.package || tree - // FIXME: Excluding the '@' here is cleaning up after the mess that - // read-package-json makes. =( - if (pkg._id && pkg._id !== '@') - return pkg._id - var name = moduleName(tree) - if (pkg.version) - return name + '@' + pkg.version - else - return name -} diff --git a/deps/npm/lib/utils/pick-manifest-from-registry-metadata.js b/deps/npm/lib/utils/pick-manifest-from-registry-metadata.js deleted file mode 100644 index a92e30b73b..0000000000 --- a/deps/npm/lib/utils/pick-manifest-from-registry-metadata.js +++ /dev/null @@ -1,26 +0,0 @@ -'use strict' -module.exports = pickManifestFromRegistryMetadata - -var log = require('npmlog') -var semver = require('semver') - -function pickManifestFromRegistryMetadata (spec, tag, versions, metadata) { - log.silly('pickManifestFromRegistryMetadata', 'spec', spec, 'tag', tag, 'versions', versions) - - // if the tagged version satisfies, then use that. - var tagged = metadata['dist-tags'][tag] - if (tagged && - metadata.versions[tagged] && - semver.satisfies(tagged, spec, true)) - return { resolvedTo: tag, manifest: metadata.versions[tagged] } - - // find the max satisfying version. - var ms = semver.maxSatisfying(versions, spec, true) - if (ms) - return { resolvedTo: ms, manifest: metadata.versions[ms] } - else if (spec === '*' && versions.length && tagged && metadata.versions[tagged]) - return { resolvedTo: tag, manifest: metadata.versions[tagged] } - else { - - } -} diff --git a/deps/npm/lib/utils/save-stack.js b/deps/npm/lib/utils/save-stack.js deleted file mode 100644 index 42c4aab5f9..0000000000 --- a/deps/npm/lib/utils/save-stack.js +++ /dev/null @@ -1,16 +0,0 @@ -'use strict' -var inherits = require('inherits') - -module.exports = SaveStack - -function SaveStack (fn) { - Error.call(this) - Error.captureStackTrace(this, fn || SaveStack) -} -inherits(SaveStack, Error) - -SaveStack.prototype.completeWith = function (er) { - this['__' + 'proto' + '__'] = er - this.stack = this.stack + '\n\n' + er.stack - return this -} diff --git a/deps/npm/lib/utils/unix-format-path.js b/deps/npm/lib/utils/unix-format-path.js deleted file mode 100644 index a82cd7135c..0000000000 --- a/deps/npm/lib/utils/unix-format-path.js +++ /dev/null @@ -1,5 +0,0 @@ -'use strict' - -module.exports = function (path) { - return path.replace(/\\/g, '/') -} diff --git a/deps/npm/lib/utils/warn-deprecated.js b/deps/npm/lib/utils/warn-deprecated.js deleted file mode 100644 index ce690f78eb..0000000000 --- a/deps/npm/lib/utils/warn-deprecated.js +++ /dev/null @@ -1,28 +0,0 @@ -module.exports = warnDeprecated - -var log = require('npmlog') - -var deprecations = {} - -function warnDeprecated (type) { - return function warn (messages, instance) { - if (!instance) { - if (!deprecations[type]) { - deprecations[type] = {} - messages.forEach(function (m) { - log.warn(type, m) - }) - } - } else { - if (!deprecations[type]) - deprecations[type] = {} - - if (!deprecations[type][instance]) { - deprecations[type][instance] = true - messages.forEach(function (m) { - log.warn(type, m) - }) - } - } - } -} diff --git a/deps/npm/man/man1/npm-access.1 b/deps/npm/man/man1/npm-access.1 index 918f9afe52..9d7e11f24e 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 2020" "" "" +.TH "NPM\-ACCESS" "1" "December 2020" "" "" .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 7f6b8d3dfc..2ca265c538 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 2020" "" "" +.TH "NPM\-ADDUSER" "1" "December 2020" "" "" .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 cd52afeac3..a7ec23cf49 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 2020" "" "" +.TH "NPM\-AUDIT" "1" "December 2020" "" "" .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 ac116c9d58..36c609858c 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 2020" "" "" +.TH "NPM\-BIN" "1" "December 2020" "" "" .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 7ae89cf6ba..4abbb02740 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 2020" "" "" +.TH "NPM\-BUGS" "1" "December 2020" "" "" .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 b222b0b07b..09f9b1c225 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 2020" "" "" +.TH "NPM\-CACHE" "1" "December 2020" "" "" .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 a37956df80..fee1a3a788 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 2020" "" "" +.TH "NPM\-CI" "1" "December 2020" "" "" .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 1b2f72dcab..26ca627f89 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 2020" "" "" +.TH "NPM\-COMPLETION" "1" "December 2020" "" "" .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 7745167245..46e4342644 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 2020" "" "" +.TH "NPM\-CONFIG" "1" "December 2020" "" "" .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 bd93629e0b..5e4ef93d90 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 2020" "" "" +.TH "NPM\-DEDUPE" "1" "December 2020" "" "" .SH "NAME" \fBnpm-dedupe\fR \- Reduce duplication .SS Synopsis diff --git a/deps/npm/man/man1/npm-deprecate.1 b/deps/npm/man/man1/npm-deprecate.1 index 1c282e1dff..6be05b311c 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 2020" "" "" +.TH "NPM\-DEPRECATE" "1" "December 2020" "" "" .SH "NAME" \fBnpm-deprecate\fR \- Deprecate a version of a package .SS Synopsis diff --git a/deps/npm/man/man1/npm-dist-tag.1 b/deps/npm/man/man1/npm-dist-tag.1 index d11e09bc27..bc70f7dc80 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 2020" "" "" +.TH "NPM\-DIST\-TAG" "1" "December 2020" "" "" .SH "NAME" \fBnpm-dist-tag\fR \- Modify package distribution tags .SS Synopsis @@ -81,8 +81,8 @@ This command used to be known as \fBnpm tag\fP, which only created new tags, and so had a different syntax\. .P Tags must share a namespace with version numbers, because they are -specified in the same slot: \fBnpm install <pkg>@<version>\fP vs \fBnpm install -<pkg>@<tag>\fP\|\. +specified in the same slot: \fBnpm install <pkg>@<version>\fP vs +\fBnpm install <pkg>@<tag>\fP\|\. .P Tags that can be interpreted as valid semver ranges will be rejected\. For example, \fBv1\.4\fP cannot be used as a tag, because it is interpreted by diff --git a/deps/npm/man/man1/npm-docs.1 b/deps/npm/man/man1/npm-docs.1 index bb145a6daf..a53481b7ba 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 2020" "" "" +.TH "NPM\-DOCS" "1" "December 2020" "" "" .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 5d96b27fab..96772d5c7e 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 2020" "" "" +.TH "NPM\-DOCTOR" "1" "December 2020" "" "" .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 53acbb98a8..14e28635a9 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 2020" "" "" +.TH "NPM\-EDIT" "1" "December 2020" "" "" .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 17d436812e..5628bda39d 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 2020" "" "" +.TH "NPM\-EXEC" "1" "December 2020" "" "" .SH "NAME" \fBnpm-exec\fR \- Run a command from a local or remote npm package .SS Synopsis @@ -14,9 +14,11 @@ npx <pkg>[@<specifier>] [args\.\.\.] npx \-p <pkg>[@<specifier>] <cmd> [args\.\.\.] npx \-c '<cmd> [args\.\.\.]' npx \-p <pkg>[@<specifier>] \-c '<cmd> [args\.\.\.]' +Run without \-\-call or positional args to open interactive subshell alias: npm x, npx +common options: \-\-package=<pkg> (may be specified multiple times) \-p is a shorthand for \-\-package only when using npx executable \-c <cmd> \-\-call=<cmd> (may not be mixed with positional arguments) @@ -28,6 +30,11 @@ This command allows you to run an arbitrary command from an npm package (either one installed locally, or fetched remotely), in a similar context as running it via \fBnpm run\fP\|\. .P +Run without positional arguments or \fB\-\-call\fP, this allows you to +interactively run commands in the same sort of shell environment that +\fBpackage\.json\fP scripts are run\. Interactive mode is not supported in CI +environments when standard input is a TTY, to prevent hangs\. +.P Whatever packages are specified by the \fB\-\-package\fP option will be provided in the \fBPATH\fP of the executed command, along with any locally installed package executables\. The \fB\-\-package\fP option may be diff --git a/deps/npm/man/man1/npm-explain.1 b/deps/npm/man/man1/npm-explain.1 index 1c30b568c5..a8a25fea3d 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 2020" "" "" +.TH "NPM\-EXPLAIN" "1" "December 2020" "" "" .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 d16c16530a..1d58315a08 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 2020" "" "" +.TH "NPM\-EXPLORE" "1" "December 2020" "" "" .SH "NAME" \fBnpm-explore\fR \- Browse an installed package .SS Synopsis diff --git a/deps/npm/man/man1/npm-fund.1 b/deps/npm/man/man1/npm-fund.1 index c6ad3f2928..25871805d9 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 2020" "" "" +.TH "NPM\-FUND" "1" "December 2020" "" "" .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 a798297a1d..737aab6e13 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 2020" "" "" +.TH "NPM\-HELP\-SEARCH" "1" "December 2020" "" "" .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 f042ba5173..ef5f950c95 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 2020" "" "" +.TH "NPM\-HELP" "1" "December 2020" "" "" .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 63bc52fcac..c3ed5ac6c0 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 2020" "" "" +.TH "NPM\-HOOK" "1" "December 2020" "" "" .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 4e75b3e5e9..bf0b98145a 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 2020" "" "" +.TH "NPM\-INIT" "1" "December 2020" "" "" .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 86605c13da..48e2956f3f 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 2020" "" "" +.TH "NPM\-INSTALL\-CI\-TEST" "1" "December 2020" "" "" .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 836fbfce15..e9bd0501e7 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 2020" "" "" +.TH "NPM\-INSTALL\-TEST" "1" "December 2020" "" "" .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 a133668f47..95ab212127 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 2020" "" "" +.TH "NPM\-INSTALL" "1" "December 2020" "" "" .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 9930a6c337..8279583335 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 2020" "" "" +.TH "NPM\-LINK" "1" "December 2020" "" "" .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 9715a8754d..c7c41a0c7e 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 2020" "" "" +.TH "NPM\-LOGOUT" "1" "December 2020" "" "" .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 cfd7ca7ac8..c41c73d804 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 2020" "" "" +.TH "NPM\-LS" "1" "December 2020" "" "" .SH "NAME" \fBnpm-ls\fR \- List installed packages .SS Synopsis @@ -22,7 +22,7 @@ For example, running \fBnpm ls promzard\fP in npm's source tree will show: .P .RS 2 .nf - npm@7\.0\.15 /path/to/npm + npm@7\.1\.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 fca9dd3c5f..905a0c2f55 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 2020" "" "" +.TH "NPM\-ORG" "1" "December 2020" "" "" .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 8d6a78034e..137d77d2fa 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 2020" "" "" +.TH "NPM\-OUTDATED" "1" "December 2020" "" "" .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 bc1e5d2e9b..158220d0e7 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 2020" "" "" +.TH "NPM\-OWNER" "1" "December 2020" "" "" .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 1c048031cb..64ce95a4b1 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 2020" "" "" +.TH "NPM\-PACK" "1" "December 2020" "" "" .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 07a65248b3..5912ad0824 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 2020" "" "" +.TH "NPM\-PING" "1" "December 2020" "" "" .SH "NAME" \fBnpm-ping\fR \- Ping npm registry .SS Synopsis diff --git a/deps/npm/man/man1/npm-prefix.1 b/deps/npm/man/man1/npm-prefix.1 index 75ea3b6a43..6d569b40f3 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 2020" "" "" +.TH "NPM\-PREFIX" "1" "December 2020" "" "" .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 e67ec8afd7..db8a068b6f 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 2020" "" "" +.TH "NPM\-PROFILE" "1" "December 2020" "" "" .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 c473c27337..a60b131ea1 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 2020" "" "" +.TH "NPM\-PRUNE" "1" "December 2020" "" "" .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 f9e6331833..eea0d29da0 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 2020" "" "" +.TH "NPM\-PUBLISH" "1" "December 2020" "" "" .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 4807f81a96..93a75ce734 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 2020" "" "" +.TH "NPM\-REBUILD" "1" "December 2020" "" "" .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 6beb1dab60..f08b62c174 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 2020" "" "" +.TH "NPM\-REPO" "1" "December 2020" "" "" .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 5e0dc83aa9..a3f9d6a9b8 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 2020" "" "" +.TH "NPM\-RESTART" "1" "December 2020" "" "" .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 180ae54d8b..b7c2fba376 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 2020" "" "" +.TH "NPM\-ROOT" "1" "December 2020" "" "" .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 df3a6424d0..8ed1c64e46 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 2020" "" "" +.TH "NPM\-RUN\-SCRIPT" "1" "December 2020" "" "" .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 4b72f2e855..d597664d37 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 2020" "" "" +.TH "NPM\-SEARCH" "1" "December 2020" "" "" .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 new file mode 100644 index 0000000000..97979b100a --- /dev/null +++ b/deps/npm/man/man1/npm-set-script.1 @@ -0,0 +1,43 @@ +.TH "NPM\-SET\-SCRIPT" "1" "December 2020" "" "" +.SH "NAME" +\fBnpm-set-script\fR \- Set tasks in the scripts section of package\.json +.SS Synopsis +.P +An npm command that lets you create a task in the scripts section of the package\.json\. +.P +.RS 2 +.nf +npm set\-script [<script>] [<command>] +.fi +.RE +.P +\fBExample:\fR +.RS 0 +.IP \(bu 2 +\fBnpm set\-script start "http\-server \."\fP + +.RE +.P +.RS 2 +.nf +{ + "name": "my\-project", + "scripts": { + "start": "http\-server \.", + "test": "some existing value" + } +} +.fi +.RE +.SS See Also +.RS 0 +.IP \(bu 2 +npm help run\-script +.IP \(bu 2 +npm help install +.IP \(bu 2 +npm help test +.IP \(bu 2 +npm help start + +.RE diff --git a/deps/npm/man/man1/npm-shrinkwrap.1 b/deps/npm/man/man1/npm-shrinkwrap.1 index aed1e8c575..71f8c4bd91 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 2020" "" "" +.TH "NPM\-SHRINKWRAP" "1" "December 2020" "" "" .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 2a5d196a94..412283276b 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 2020" "" "" +.TH "NPM\-STAR" "1" "December 2020" "" "" .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 9c16add7c1..bb62023991 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 2020" "" "" +.TH "NPM\-STARS" "1" "December 2020" "" "" .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 97cb2af187..fecca5eb08 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 2020" "" "" +.TH "NPM\-START" "1" "December 2020" "" "" .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 00b5ea1cdc..2653090795 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 2020" "" "" +.TH "NPM\-STOP" "1" "December 2020" "" "" .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 7ef02a93f7..0df7c41164 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 2020" "" "" +.TH "NPM\-TEAM" "1" "December 2020" "" "" .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 1affbbf3ce..fa5bf03c36 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 2020" "" "" +.TH "NPM\-TEST" "1" "December 2020" "" "" .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 94466a50ff..b679028282 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 2020" "" "" +.TH "NPM\-TOKEN" "1" "December 2020" "" "" .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 41682436f0..d098c88415 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 2020" "" "" +.TH "NPM\-UNINSTALL" "1" "December 2020" "" "" .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 556aea1f79..0c7d946a4d 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 2020" "" "" +.TH "NPM\-UNPUBLISH" "1" "December 2020" "" "" .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 1fb6177273..d3115ff7ab 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 2020" "" "" +.TH "NPM\-UNSTAR" "1" "December 2020" "" "" .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 d8a8fd2094..2df28cd28e 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 2020" "" "" +.TH "NPM\-UPDATE" "1" "December 2020" "" "" .SH "NAME" \fBnpm-update\fR \- Update a package .SS Synopsis diff --git a/deps/npm/man/man1/npm-version.1 b/deps/npm/man/man1/npm-version.1 index 59d21e8aa2..f6df51bfba 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 2020" "" "" +.TH "NPM\-VERSION" "1" "December 2020" "" "" .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 943bada0e6..7334357ccf 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 2020" "" "" +.TH "NPM\-VIEW" "1" "December 2020" "" "" .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 49fe4b2dfb..73de754036 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 2020" "" "" +.TH "NPM\-WHOAMI" "1" "December 2020" "" "" .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 c3d1eb8b47..a7c198206e 100644 --- a/deps/npm/man/man1/npm.1 +++ b/deps/npm/man/man1/npm.1 @@ -1,4 +1,4 @@ -.TH "NPM" "1" "November 2020" "" "" +.TH "NPM" "1" "December 2020" "" "" .SH "NAME" \fBnpm\fR \- javascript package manager .SS Synopsis @@ -10,7 +10,7 @@ npm <command> [args] .RE .SS Version .P -7\.0\.15 +7\.1\.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 d87c4a946d..c11f9600e1 100644 --- a/deps/npm/man/man1/npx.1 +++ b/deps/npm/man/man1/npx.1 @@ -1,4 +1,4 @@ -.TH "NPX" "1" "November 2020" "" "" +.TH "NPX" "1" "December 2020" "" "" .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 a41c3ea1d9..6d838019c6 100644 --- a/deps/npm/man/man5/folders.5 +++ b/deps/npm/man/man5/folders.5 @@ -1,4 +1,4 @@ -.TH "FOLDERS" "5" "November 2020" "" "" +.TH "FOLDERS" "5" "December 2020" "" "" .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 9b12559729..e827d11bdb 100644 --- a/deps/npm/man/man5/install.5 +++ b/deps/npm/man/man5/install.5 @@ -1,4 +1,4 @@ -.TH "INSTALL" "5" "November 2020" "" "" +.TH "INSTALL" "5" "December 2020" "" "" .SH "NAME" \fBinstall\fR \- Download and install node and npm .SS Description diff --git a/deps/npm/man/man5/npmrc.5 b/deps/npm/man/man5/npmrc.5 index 46575b7ae9..ea60e39a24 100644 --- a/deps/npm/man/man5/npmrc.5 +++ b/deps/npm/man/man5/npmrc.5 @@ -1,4 +1,4 @@ -.TH "NPMRC" "5" "November 2020" "" "" +.TH "NPMRC" "5" "December 2020" "" "" .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 83f3babc75..5b8b503763 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 2020" "" "" +.TH "PACKAGE\.JSON" "5" "December 2020" "" "" .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 2dabd65ecc..77d8ab1c3e 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 2020" "" "" +.TH "PACKAGE\-LOCK\.JSON" "5" "December 2020" "" "" .SH "NAME" \fBpackage-lock.json\fR \- A manifestation of the manifest .SS Description diff --git a/deps/npm/man/man5/package-locks.5 b/deps/npm/man/man5/package-locks.5 index 8159e90590..0fc35cfb5a 100644 --- a/deps/npm/man/man5/package-locks.5 +++ b/deps/npm/man/man5/package-locks.5 @@ -1,4 +1,4 @@ -.TH "PACKAGE\-LOCKS" "5" "November 2020" "" "" +.TH "PACKAGE\-LOCKS" "5" "December 2020" "" "" .SH "NAME" \fBpackage-locks\fR \- An explanation of npm lockfiles .SS Description diff --git a/deps/npm/man/man5/shrinkwrap-json.5 b/deps/npm/man/man5/shrinkwrap-json.5 index 17e23a7dcd..7457df20e4 100644 --- a/deps/npm/man/man5/shrinkwrap-json.5 +++ b/deps/npm/man/man5/shrinkwrap-json.5 @@ -1,4 +1,4 @@ -.TH "SHRINKWRAP\.JSON" "5" "November 2020" "" "" +.TH "SHRINKWRAP\.JSON" "5" "December 2020" "" "" .SH "NAME" \fBshrinkwrap.json\fR \- A publishable lockfile .SS Description diff --git a/deps/npm/man/man7/config.7 b/deps/npm/man/man7/config.7 index 5a77bec3d9..ebf2314e28 100644 --- a/deps/npm/man/man7/config.7 +++ b/deps/npm/man/man7/config.7 @@ -1,4 +1,4 @@ -.TH "CONFIG" "7" "November 2020" "" "" +.TH "CONFIG" "7" "December 2020" "" "" .SH "NAME" \fBconfig\fR \- More than you probably want to know about npm configuration .SS Description diff --git a/deps/npm/man/man7/developers.7 b/deps/npm/man/man7/developers.7 index 1af140b442..c6dac32f92 100644 --- a/deps/npm/man/man7/developers.7 +++ b/deps/npm/man/man7/developers.7 @@ -1,4 +1,4 @@ -.TH "DEVELOPERS" "7" "November 2020" "" "" +.TH "DEVELOPERS" "7" "December 2020" "" "" .SH "NAME" \fBdevelopers\fR \- Developer Guide .SS Description diff --git a/deps/npm/man/man7/disputes.7 b/deps/npm/man/man7/disputes.7 index 6fccaabf4a..8e95505991 100644 --- a/deps/npm/man/man7/disputes.7 +++ b/deps/npm/man/man7/disputes.7 @@ -1,4 +1,4 @@ -.TH "DISPUTES" "7" "November 2020" "" "" +.TH "DISPUTES" "7" "December 2020" "" "" .SH "NAME" \fBdisputes\fR \- Handling Module Name Disputes .P diff --git a/deps/npm/man/man7/orgs.7 b/deps/npm/man/man7/orgs.7 index 6d482bea3b..d496e4d4a9 100644 --- a/deps/npm/man/man7/orgs.7 +++ b/deps/npm/man/man7/orgs.7 @@ -1,4 +1,4 @@ -.TH "ORGS" "7" "November 2020" "" "" +.TH "ORGS" "7" "December 2020" "" "" .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 07e7711846..cf6b02faeb 100644 --- a/deps/npm/man/man7/registry.7 +++ b/deps/npm/man/man7/registry.7 @@ -1,4 +1,4 @@ -.TH "REGISTRY" "7" "November 2020" "" "" +.TH "REGISTRY" "7" "December 2020" "" "" .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 55e4d711dd..24f08abfff 100644 --- a/deps/npm/man/man7/removal.7 +++ b/deps/npm/man/man7/removal.7 @@ -1,4 +1,4 @@ -.TH "REMOVAL" "7" "November 2020" "" "" +.TH "REMOVAL" "7" "December 2020" "" "" .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 83c6cc2541..534b064c89 100644 --- a/deps/npm/man/man7/scope.7 +++ b/deps/npm/man/man7/scope.7 @@ -1,4 +1,4 @@ -.TH "SCOPE" "7" "November 2020" "" "" +.TH "SCOPE" "7" "December 2020" "" "" .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 35a34b43a0..d2ef4476ab 100644 --- a/deps/npm/man/man7/scripts.7 +++ b/deps/npm/man/man7/scripts.7 @@ -1,4 +1,4 @@ -.TH "SCRIPTS" "7" "November 2020" "" "" +.TH "SCRIPTS" "7" "December 2020" "" "" .SH "NAME" \fBscripts\fR \- How npm handles the "scripts" field .SS Description diff --git a/deps/npm/man/man7/semver.7 b/deps/npm/man/man7/semver.7 index 8e9478e721..0a08bf9abb 100644 --- a/deps/npm/man/man7/semver.7 +++ b/deps/npm/man/man7/semver.7 @@ -1,4 +1,4 @@ -.TH "SEMVER" "7" "November 2020" "" "" +.TH "SEMVER" "7" "December 2020" "" "" .SH "NAME" \fBsemver\fR \- The semantic versioner for npm .SH Install diff --git a/deps/npm/man/man7/workspaces.7 b/deps/npm/man/man7/workspaces.7 index 8c982f1253..ade7d238bd 100644 --- a/deps/npm/man/man7/workspaces.7 +++ b/deps/npm/man/man7/workspaces.7 @@ -1,4 +1,4 @@ -.TH "WORKSPACES" "7" "November 2020" "" "" +.TH "WORKSPACES" "7" "December 2020" "" "" .SH "NAME" \fBworkspaces\fR \- Working with workspaces .SS Description diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/node.js b/deps/npm/node_modules/@npmcli/arborist/lib/node.js index 7381211ae3..6a274bf92b 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/node.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/node.js @@ -107,13 +107,15 @@ class Node { this.name = name || nameFromFolder(path || pkg.name || realpath) || - pkg.name - - if (!this.name) - throw new TypeError('could not detect node name from path or package') + pkg.name || + null // should be equal if not a link this.path = path && resolve(path) + + if (!this.name && (!this.path || this.path !== dirname(this.path))) + throw new TypeError('could not detect node name from path or package') + this.realpath = !this.isLink ? this.path : resolve(realpath) this.resolved = resolved || null diff --git a/deps/npm/node_modules/@npmcli/arborist/package.json b/deps/npm/node_modules/@npmcli/arborist/package.json index a83ac1e43f..80d24c62c7 100644 --- a/deps/npm/node_modules/@npmcli/arborist/package.json +++ b/deps/npm/node_modules/@npmcli/arborist/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/arborist", - "version": "1.0.13", + "version": "1.0.14", "description": "Manage node_modules trees", "dependencies": { "@npmcli/installed-package-contents": "^1.0.5", diff --git a/deps/npm/node_modules/@npmcli/config/package.json b/deps/npm/node_modules/@npmcli/config/package.json index ef22e7bb0e..579acd5b28 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": "1.2.1", + "version": "1.2.3", "files": [ "lib" ], @@ -27,10 +27,11 @@ "tap": "^14.10.8" }, "dependencies": { - "walk-up-path": "^1.0.0", "ini": "^1.3.5", + "mkdirp-infer-owner": "^2.0.0", "nopt": "^5.0.0", - "mkdirp-infer-owner": "^2.0.0" + "semver": "^7.3.4", + "walk-up-path": "^1.0.0" }, "engines": { "node": ">=10" diff --git a/deps/npm/node_modules/semver/classes/comparator.js b/deps/npm/node_modules/semver/classes/comparator.js index 3595792d0e..dbbef2d8fe 100644 --- a/deps/npm/node_modules/semver/classes/comparator.js +++ b/deps/npm/node_modules/semver/classes/comparator.js @@ -5,12 +5,7 @@ class Comparator { return ANY } constructor (comp, options) { - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - } - } + options = parseOptions(options) if (comp instanceof Comparator) { if (comp.loose === !!options.loose) { @@ -132,6 +127,7 @@ class Comparator { module.exports = Comparator +const parseOptions = require('../internal/parse-options') const {re, t} = require('../internal/re') const cmp = require('../functions/cmp') const debug = require('../internal/debug') diff --git a/deps/npm/node_modules/semver/classes/range.js b/deps/npm/node_modules/semver/classes/range.js index 83f8967717..aa04f6bff9 100644 --- a/deps/npm/node_modules/semver/classes/range.js +++ b/deps/npm/node_modules/semver/classes/range.js @@ -1,12 +1,7 @@ // hoisted class for cyclic dependency class Range { constructor (range, options) { - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - } - } + options = parseOptions(options) if (range instanceof Range) { if ( @@ -46,6 +41,24 @@ class Range { throw new TypeError(`Invalid SemVer Range: ${range}`) } + // if we have any that are not the null set, throw out null sets. + if (this.set.length > 1) { + // keep the first one, in case they're all null sets + const first = this.set[0] + this.set = this.set.filter(c => !isNullSet(c[0])) + if (this.set.length === 0) + this.set = [first] + else if (this.set.length > 1) { + // if we have any that are *, then the range is just * + for (const c of this.set) { + if (c.length === 1 && isAny(c[0])) { + this.set = [c] + break + } + } + } + } + this.format() } @@ -64,8 +77,17 @@ class Range { } parseRange (range) { - const loose = this.options.loose range = range.trim() + + // memoize range parsing for performance. + // this is a very hot path, and fully deterministic. + const memoOpts = Object.keys(this.options).join(',') + const memoKey = `parseRange:${memoOpts}:${range}` + const cached = cache.get(memoKey) + if (cached) + return cached + + const loose = this.options.loose // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` const hr = loose ? re[t.HYPHENRANGELOOSE] : re[t.HYPHENRANGE] range = range.replace(hr, hyphenReplace(this.options.includePrerelease)) @@ -87,15 +109,33 @@ class Range { // ready to be split into comparators. const compRe = loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR] - return range + const rangeList = range .split(' ') .map(comp => parseComparator(comp, this.options)) .join(' ') .split(/\s+/) + // >=0.0.0 is equivalent to * .map(comp => replaceGTE0(comp, this.options)) // in loose mode, throw out any that are not valid comparators .filter(this.options.loose ? comp => !!comp.match(compRe) : () => true) .map(comp => new Comparator(comp, this.options)) + + // if any comparators are the null set, then replace with JUST null set + // if more than one comparator, remove any * comparators + // also, don't include the same comparator more than once + const l = rangeList.length + const rangeMap = new Map() + for (const comp of rangeList) { + if (isNullSet(comp)) + return [comp] + rangeMap.set(comp.value, comp) + } + if (rangeMap.size > 1 && rangeMap.has('')) + rangeMap.delete('') + + const result = [...rangeMap.values()] + cache.set(memoKey, result) + return result } intersects (range, options) { @@ -144,6 +184,10 @@ class Range { } module.exports = Range +const LRU = require('lru-cache') +const cache = new LRU({ max: 1000 }) + +const parseOptions = require('../internal/parse-options') const Comparator = require('./comparator') const debug = require('../internal/debug') const SemVer = require('./semver') @@ -155,6 +199,9 @@ const { caretTrimReplace } = require('../internal/re') +const isNullSet = c => c.value === '<0.0.0-0' +const isAny = c => c.value === '' + // take a set of comparators and determine whether there // exists a version which can satisfy it const isSatisfiable = (comparators, options) => { diff --git a/deps/npm/node_modules/semver/classes/semver.js b/deps/npm/node_modules/semver/classes/semver.js index 73247ad2b7..ed81a7ec6c 100644 --- a/deps/npm/node_modules/semver/classes/semver.js +++ b/deps/npm/node_modules/semver/classes/semver.js @@ -2,15 +2,12 @@ const debug = require('../internal/debug') const { MAX_LENGTH, MAX_SAFE_INTEGER } = require('../internal/constants') const { re, t } = require('../internal/re') +const parseOptions = require('../internal/parse-options') const { compareIdentifiers } = require('../internal/identifiers') class SemVer { constructor (version, options) { - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - } - } + options = parseOptions(options) + if (version instanceof SemVer) { if (version.loose === !!options.loose && version.includePrerelease === !!options.includePrerelease) { diff --git a/deps/npm/node_modules/semver/functions/parse.js b/deps/npm/node_modules/semver/functions/parse.js index 457fee04a9..11f20f0374 100644 --- a/deps/npm/node_modules/semver/functions/parse.js +++ b/deps/npm/node_modules/semver/functions/parse.js @@ -2,13 +2,9 @@ const {MAX_LENGTH} = require('../internal/constants') const { re, t } = require('../internal/re') const SemVer = require('../classes/semver') +const parseOptions = require('../internal/parse-options') const parse = (version, options) => { - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - } - } + options = parseOptions(options) if (version instanceof SemVer) { return version diff --git a/deps/npm/node_modules/semver/internal/parse-options.js b/deps/npm/node_modules/semver/internal/parse-options.js new file mode 100644 index 0000000000..42d2ebd6fa --- /dev/null +++ b/deps/npm/node_modules/semver/internal/parse-options.js @@ -0,0 +1,11 @@ +// parse out just the options we care about so we always get a consistent +// obj with keys in a consistent order. +const opts = ['includePrerelease', 'loose', 'rtl'] +const parseOptions = options => + !options ? {} + : typeof options !== 'object' ? { loose: true } + : opts.filter(k => options[k]).reduce((options, k) => { + options[k] = true + return options + }, {}) +module.exports = parseOptions diff --git a/deps/npm/node_modules/semver/package.json b/deps/npm/node_modules/semver/package.json index 07867975d1..d4043d38a1 100644 --- a/deps/npm/node_modules/semver/package.json +++ b/deps/npm/node_modules/semver/package.json @@ -1,6 +1,6 @@ { "name": "semver", - "version": "7.3.2", + "version": "7.3.4", "description": "The semantic version parser used by npm.", "main": "index.js", "scripts": { @@ -16,7 +16,7 @@ "license": "ISC", "repository": "https://github.com/npm/node-semver", "bin": { - "semver": "./bin/semver.js" + "semver": "bin/semver.js" }, "files": [ "bin/**/*.js", @@ -34,5 +34,8 @@ }, "engines": { "node": ">=10" + }, + "dependencies": { + "lru-cache": "^6.0.0" } } diff --git a/deps/npm/node_modules/semver/ranges/min-version.js b/deps/npm/node_modules/semver/ranges/min-version.js index 7118d237bf..2fac412914 100644 --- a/deps/npm/node_modules/semver/ranges/min-version.js +++ b/deps/npm/node_modules/semver/ranges/min-version.js @@ -19,6 +19,7 @@ const minVersion = (range, loose) => { for (let i = 0; i < range.set.length; ++i) { const comparators = range.set[i] + let setMin = null comparators.forEach((comparator) => { // Clone to avoid manipulating the comparator's semver object. const compver = new SemVer(comparator.semver.version) @@ -33,8 +34,8 @@ const minVersion = (range, loose) => { /* fallthrough */ case '': case '>=': - if (!minver || gt(minver, compver)) { - minver = compver + if (!setMin || gt(compver, setMin)) { + setMin = compver } break case '<': @@ -46,6 +47,8 @@ const minVersion = (range, loose) => { throw new Error(`Unexpected operation: ${comparator.operator}`) } }) + if (setMin && (!minver || gt(minver, setMin))) + minver = setMin } if (minver && range.test(minver)) { diff --git a/deps/npm/node_modules/semver/ranges/outside.js b/deps/npm/node_modules/semver/ranges/outside.js index e35ed1176c..2a4b0a13f9 100644 --- a/deps/npm/node_modules/semver/ranges/outside.js +++ b/deps/npm/node_modules/semver/ranges/outside.js @@ -32,7 +32,7 @@ const outside = (version, range, hilo, options) => { throw new TypeError('Must provide a hilo val of "<" or ">"') } - // If it satisifes the range it is not outside + // If it satisfies the range it is not outside if (satisfies(version, range, options)) { return false } diff --git a/deps/npm/node_modules/semver/ranges/subset.js b/deps/npm/node_modules/semver/ranges/subset.js index 6ae29a3c92..bb7d15fe26 100644 --- a/deps/npm/node_modules/semver/ranges/subset.js +++ b/deps/npm/node_modules/semver/ranges/subset.js @@ -21,15 +21,18 @@ const compare = require('../functions/compare.js') // - If EQ satisfies every C, return true // - Else return false // - If GT -// - If GT is lower than any > or >= comp in C, return false +// - If GT.semver is lower than any > or >= comp in C, return false // - If GT is >=, and GT.semver does not satisfy every C, return false // - If LT -// - If LT.semver is greater than that of any > comp in C, return false +// - If LT.semver is greater than any < or <= comp in C, return false // - If LT is <=, and LT.semver does not satisfy every C, return false // - If any C is a = range, and GT or LT are set, return false // - Else return true const subset = (sub, dom, options) => { + if (sub === dom) + return true + sub = new Range(sub, options) dom = new Range(dom, options) let sawNonNull = false @@ -52,6 +55,9 @@ const subset = (sub, dom, options) => { } const simpleSubset = (sub, dom, options) => { + if (sub === dom) + return true + if (sub.length === 1 && sub[0].semver === ANY) return dom.length === 1 && dom[0].semver === ANY @@ -90,6 +96,7 @@ const simpleSubset = (sub, dom, options) => { if (!satisfies(eq, String(c), options)) return false } + return true } @@ -101,7 +108,7 @@ const simpleSubset = (sub, dom, options) => { if (gt) { if (c.operator === '>' || c.operator === '>=') { higher = higherGT(gt, c, options) - if (higher === c) + if (higher === c && higher !== gt) return false } else if (gt.operator === '>=' && !satisfies(gt.semver, String(c), options)) return false @@ -109,7 +116,7 @@ const simpleSubset = (sub, dom, options) => { if (lt) { if (c.operator === '<' || c.operator === '<=') { lower = lowerLT(lt, c, options) - if (lower === c) + if (lower === c && lower !== lt) return false } else if (lt.operator === '<=' && !satisfies(lt.semver, String(c), options)) return false diff --git a/deps/npm/package.json b/deps/npm/package.json index 540ca1f1ad..393993f79e 100644 --- a/deps/npm/package.json +++ b/deps/npm/package.json @@ -1,5 +1,5 @@ { - "version": "7.0.15", + "version": "7.1.0", "name": "npm", "description": "a package manager for JavaScript", "keywords": [ @@ -42,9 +42,9 @@ "./package.json": "./package.json" }, "dependencies": { - "@npmcli/arborist": "^1.0.13", + "@npmcli/arborist": "^1.0.14", "@npmcli/ci-detect": "^1.2.0", - "@npmcli/config": "^1.2.1", + "@npmcli/config": "^1.2.3", "@npmcli/run-script": "^1.8.1", "abbrev": "~1.1.1", "ansicolors": "~0.3.2", @@ -99,7 +99,7 @@ "read-package-json": "^3.0.0", "read-package-json-fast": "^1.2.1", "rimraf": "^3.0.2", - "semver": "^7.3.2", + "semver": "^7.3.4", "sorted-object": "~2.0.1", "ssri": "^8.0.0", "tar": "^6.0.5", @@ -180,12 +180,12 @@ "write-file-atomic" ], "devDependencies": { - "cmark-gfm": "^0.8.4", - "eslint": "^7.13.0", + "cmark-gfm": "^0.8.5", + "eslint": "^7.14.0", "eslint-plugin-import": "^2.22.1", "eslint-plugin-node": "^11.1.0", "eslint-plugin-promise": "^4.2.1", - "eslint-plugin-standard": "^4.1.0", + "eslint-plugin-standard": "^5.0.0", "jsdom": "^16.4.0", "marked-man": "^0.7.0", "require-inject": "^1.4.4", diff --git a/deps/npm/tap-snapshots/test-lib-utils-cmd-list.js-TAP.test.js b/deps/npm/tap-snapshots/test-lib-utils-cmd-list.js-TAP.test.js index 36066b5763..68f0d8328a 100644 --- a/deps/npm/tap-snapshots/test-lib-utils-cmd-list.js-TAP.test.js +++ b/deps/npm/tap-snapshots/test-lib-utils-cmd-list.js-TAP.test.js @@ -162,6 +162,7 @@ Object { "start", "restart", "run-script", + "set-script", "completion", "doctor", "exec", diff --git a/deps/npm/test/coverage-map.js b/deps/npm/test/coverage-map.js index cb2670129e..6353109da2 100644 --- a/deps/npm/test/coverage-map.js +++ b/deps/npm/test/coverage-map.js @@ -9,9 +9,8 @@ const coverageMap = (filename) => { return glob.sync(`${dir}/**/*.js`) .map(f => relative(process.cwd(), f)) } - if (/^test\/(lib|bin)\//.test(filename)) { + if (/^test\/(lib|bin)\//.test(filename)) return filename.replace(/^test\//, '') - } return [] } diff --git a/deps/npm/test/lib/exec.js b/deps/npm/test/lib/exec.js index c65f916428..25c3fe4633 100644 --- a/deps/npm/test/lib/exec.js +++ b/deps/npm/test/lib/exec.js @@ -1,6 +1,8 @@ const t = require('tap') const requireInject = require('require-inject') const { resolve, delimiter } = require('path') +const OUTPUT = [] +const output = (...msg) => OUTPUT.push(msg) const ARB_CTOR = [] const ARB_ACTUAL_TREE = {} @@ -29,6 +31,7 @@ const npm = { call: '', package: [], legacyPeerDeps: false, + shell: 'shell-cmd', }, localPrefix: 'local-prefix', localBin: 'local-bin', @@ -91,6 +94,7 @@ const mocks = { pacote, read, 'mkdirp-infer-owner': mkdirp, + '../../lib/utils/output.js': output, } const exec = requireInject('../../lib/exec.js', mocks) @@ -123,7 +127,7 @@ t.test('npx foo, bin already exists locally', async t => { await exec(['foo'], er => { t.ifError(er, 'npm exec') }) - t.strictSame(RUN_SCRIPTS, [{ + t.match(RUN_SCRIPTS, [{ pkg: { scripts: { npx: 'foo' }}, banner: false, path: process.cwd(), @@ -147,7 +151,7 @@ t.test('npx foo, bin already exists globally', async t => { await exec(['foo'], er => { t.ifError(er, 'npm exec') }) - t.strictSame(RUN_SCRIPTS, [{ + t.match(RUN_SCRIPTS, [{ pkg: { scripts: { npx: 'foo' }}, banner: false, path: process.cwd(), @@ -193,6 +197,72 @@ t.test('npm exec foo, already present locally', async t => { }]) }) +t.test('npm exec <noargs>, run interactive shell', async t => { + CI_NAME = null + const { isTTY } = process.stdin + process.stdin.isTTY = true + t.teardown(() => process.stdin.isTTY = isTTY) + + const run = async (t, doRun = true) => { + LOG_WARN.length = 0 + ARB_CTOR.length = 0 + MKDIRPS.length = 0 + ARB_REIFY.length = 0 + OUTPUT.length = 0 + await exec([], er => { + if (er) + throw er + }) + t.strictSame(MKDIRPS, [], 'no need to make any dirs') + t.strictSame(ARB_CTOR, [], 'no need to instantiate arborist') + t.strictSame(ARB_REIFY, [], 'no need to reify anything') + t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') + if (doRun) { + t.match(RUN_SCRIPTS, [{ + pkg: { scripts: { npx: 'shell-cmd' } }, + banner: false, + path: process.cwd(), + stdioString: true, + event: 'npx', + env: { PATH: process.env.PATH }, + stdio: 'inherit', + }]) + } else + t.strictSame(RUN_SCRIPTS, []) + RUN_SCRIPTS.length = 0 + } + + t.test('print message when tty and not in CI', async t => { + CI_NAME = null + process.stdin.isTTY = true + await run(t) + t.strictSame(LOG_WARN, []) + t.strictSame(OUTPUT, [ + ['\nEntering npm script environment\nType \'exit\' or ^D when finished\n'], + ], 'printed message about interactive shell') + }) + + t.test('no message when not TTY', async t => { + CI_NAME = null + process.stdin.isTTY = false + await run(t) + t.strictSame(LOG_WARN, []) + t.strictSame(OUTPUT, [], 'no message about interactive shell') + }) + + t.test('print warning when in CI and interactive', async t => { + CI_NAME = 'travis-ci' + process.stdin.isTTY = true + await run(t, false) + t.strictSame(LOG_WARN, [ + ['exec', 'Interactive mode disabled in CI environment'], + ]) + t.strictSame(OUTPUT, [], 'no message about interactive shell') + }) + + t.end() +}) + t.test('npm exec foo, not present locally or in central loc', async t => { const path = t.testdir() const installDir = resolve('cache-dir/_npx/f7fbba6e0636f890') diff --git a/deps/npm/test/lib/explore.js b/deps/npm/test/lib/explore.js index 64c70bcce7..23eab1172a 100644 --- a/deps/npm/test/lib/explore.js +++ b/deps/npm/test/lib/explore.js @@ -1,53 +1,70 @@ const t = require('tap') const requireInject = require('require-inject') -let STAT_ERROR = null -let STAT_CALLED = '' -const mockStat = (path, cb) => { - STAT_CALLED = path - cb(STAT_ERROR, {}) +let RPJ_ERROR = null +let RPJ_CALLED = '' +const mockRPJ = async path => { + if (RPJ_ERROR) { + try { + throw RPJ_ERROR + } finally { + RPJ_ERROR = null + } + } + RPJ_CALLED = path + return {some: 'package'} } -let SPAWN_ERROR = null -let SPAWN_EXIT_CODE = 0 -let SPAWN_SHELL_EXEC = null -let SPAWN_SHELL_ARGS = null -const mockSpawn = (sh, shellArgs, opts) => { - if (sh !== 'shell-command') - throw new Error('got wrong shell command') +let RUN_SCRIPT_ERROR = null +let RUN_SCRIPT_EXIT_CODE = 0 +let RUN_SCRIPT_SIGNAL = null +let RUN_SCRIPT_EXEC = null +const mockRunScript = ({ pkg, banner, path, event, stdio }) => { + if (event !== '_explore') + throw new Error('got wrong event name') - if (SPAWN_ERROR) - return Promise.reject(SPAWN_ERROR) + RUN_SCRIPT_EXEC = pkg.scripts._explore - SPAWN_SHELL_EXEC = sh - SPAWN_SHELL_ARGS = shellArgs - return Promise.resolve({ code: SPAWN_EXIT_CODE }) + if (RUN_SCRIPT_ERROR) { + try { + return Promise.reject(RUN_SCRIPT_ERROR) + } finally { + RUN_SCRIPT_ERROR = null + } + } + + if (RUN_SCRIPT_EXIT_CODE || RUN_SCRIPT_SIGNAL) { + return Promise.reject(Object.assign(new Error('command failed'), { + code: RUN_SCRIPT_EXIT_CODE, + signal: RUN_SCRIPT_SIGNAL, + })) + } + + return Promise.resolve({ code: 0, signal: null }) } const output = [] let ERROR_HANDLER_CALLED = null +const logs = [] const getExplore = windows => requireInject('../../lib/explore.js', { '../../lib/utils/is-windows.js': windows, - '../../lib/utils/escape-arg.js': requireInject('../../lib/utils/escape-arg.js', { - '../../lib/utils/is-windows.js': windows, - }), path: require('path')[windows ? 'win32' : 'posix'], - '../../lib/utils/escape-exec-path.js': requireInject('../../lib/utils/escape-arg.js', { - '../../lib/utils/is-windows.js': windows, - }), '../../lib/utils/error-handler.js': er => { ERROR_HANDLER_CALLED = er }, - fs: { - stat: mockStat, - }, + 'read-package-json-fast': mockRPJ, '../../lib/npm.js': { dir: windows ? 'c:\\npm\\dir' : '/npm/dir', + log: { + error: (...msg) => logs.push(msg), + disableProgress: () => {}, + enableProgress: () => {}, + }, flatOptions: { shell: 'shell-command', }, }, - '@npmcli/promise-spawn': mockSpawn, + '@npmcli/run-script': mockRunScript, '../../lib/utils/output.js': out => { output.push(out) }, @@ -68,14 +85,12 @@ t.test('basic interactive', t => { t.strictSame({ ERROR_HANDLER_CALLED, - STAT_CALLED, - SPAWN_SHELL_EXEC, - SPAWN_SHELL_ARGS, + RPJ_CALLED, + RUN_SCRIPT_EXEC, }, { ERROR_HANDLER_CALLED: null, - STAT_CALLED: 'c:\\npm\\dir\\pkg', - SPAWN_SHELL_EXEC: 'shell-command', - SPAWN_SHELL_ARGS: [], + RPJ_CALLED: 'c:\\npm\\dir\\pkg\\package.json', + RUN_SCRIPT_EXEC: 'shell-command', }) t.strictSame(output, [ "\nExploring c:\\npm\\dir\\pkg\nType 'exit' or ^D when finished\n", @@ -88,14 +103,12 @@ t.test('basic interactive', t => { t.strictSame({ ERROR_HANDLER_CALLED, - STAT_CALLED, - SPAWN_SHELL_EXEC, - SPAWN_SHELL_ARGS, + RPJ_CALLED, + RUN_SCRIPT_EXEC, }, { ERROR_HANDLER_CALLED: null, - STAT_CALLED: '/npm/dir/pkg', - SPAWN_SHELL_EXEC: 'shell-command', - SPAWN_SHELL_ARGS: [], + RPJ_CALLED: '/npm/dir/pkg/package.json', + RUN_SCRIPT_EXEC: 'shell-command', }) t.strictSame(output, [ "\nExploring /npm/dir/pkg\nType 'exit' or ^D when finished\n", @@ -109,11 +122,11 @@ t.test('interactive tracks exit code', t => { const { exitCode } = process t.beforeEach((cb) => { process.exitCode = exitCode - SPAWN_EXIT_CODE = 99 + RUN_SCRIPT_EXIT_CODE = 99 cb() }) t.afterEach((cb) => { - SPAWN_EXIT_CODE = 0 + RUN_SCRIPT_EXIT_CODE = 0 output.length = 0 process.exitCode = exitCode cb() @@ -125,14 +138,12 @@ t.test('interactive tracks exit code', t => { t.strictSame({ ERROR_HANDLER_CALLED, - STAT_CALLED, - SPAWN_SHELL_EXEC, - SPAWN_SHELL_ARGS, + RPJ_CALLED, + RUN_SCRIPT_EXEC, }, { ERROR_HANDLER_CALLED: null, - STAT_CALLED: 'c:\\npm\\dir\\pkg', - SPAWN_SHELL_EXEC: 'shell-command', - SPAWN_SHELL_ARGS: [], + RPJ_CALLED: 'c:\\npm\\dir\\pkg\\package.json', + RUN_SCRIPT_EXEC: 'shell-command', }) t.strictSame(output, [ "\nExploring c:\\npm\\dir\\pkg\nType 'exit' or ^D when finished\n", @@ -146,14 +157,12 @@ t.test('interactive tracks exit code', t => { t.strictSame({ ERROR_HANDLER_CALLED, - STAT_CALLED, - SPAWN_SHELL_EXEC, - SPAWN_SHELL_ARGS, + RPJ_CALLED, + RUN_SCRIPT_EXEC, }, { ERROR_HANDLER_CALLED: null, - STAT_CALLED: '/npm/dir/pkg', - SPAWN_SHELL_EXEC: 'shell-command', - SPAWN_SHELL_ARGS: [], + RPJ_CALLED: '/npm/dir/pkg/package.json', + RUN_SCRIPT_EXEC: 'shell-command', }) t.strictSame(output, [ "\nExploring /npm/dir/pkg\nType 'exit' or ^D when finished\n", @@ -162,16 +171,11 @@ t.test('interactive tracks exit code', t => { })) t.test('posix spawn fail', t => { - t.teardown(() => { - SPAWN_ERROR = null - }) - SPAWN_ERROR = Object.assign(new Error('glorb'), { + RUN_SCRIPT_ERROR = Object.assign(new Error('glorb'), { code: 33, }) return posixExplore(['pkg'], er => { - if (er) - throw er - + t.match(er, { message: 'glorb', code: 33 }) t.strictSame(output, [ "\nExploring /npm/dir/pkg\nType 'exit' or ^D when finished\n", ]) @@ -179,6 +183,32 @@ t.test('interactive tracks exit code', t => { }) }) + t.test('posix spawn fail, 0 exit code', t => { + RUN_SCRIPT_ERROR = Object.assign(new Error('glorb'), { + code: 0, + }) + return posixExplore(['pkg'], er => { + t.match(er, { message: 'glorb', code: 0 }) + t.strictSame(output, [ + "\nExploring /npm/dir/pkg\nType 'exit' or ^D when finished\n", + ]) + t.equal(process.exitCode, 1) + }) + }) + + t.test('posix spawn fail, no exit code', t => { + RUN_SCRIPT_ERROR = Object.assign(new Error('command failed'), { + code: 'EPROBLEM', + }) + return posixExplore(['pkg'], er => { + t.match(er, { message: 'command failed', code: 'EPROBLEM' }) + t.strictSame(output, [ + "\nExploring /npm/dir/pkg\nType 'exit' or ^D when finished\n", + ]) + t.equal(process.exitCode, 1) + }) + }) + t.end() }) @@ -194,19 +224,12 @@ t.test('basic non-interactive', t => { t.strictSame({ ERROR_HANDLER_CALLED, - STAT_CALLED, - SPAWN_SHELL_EXEC, - SPAWN_SHELL_ARGS, + RPJ_CALLED, + RUN_SCRIPT_EXEC, }, { ERROR_HANDLER_CALLED: null, - STAT_CALLED: 'c:\\npm\\dir\\pkg', - SPAWN_SHELL_EXEC: 'shell-command', - SPAWN_SHELL_ARGS: [ - '/d', - '/s', - '/c', - '"ls"', - ], + RPJ_CALLED: 'c:\\npm\\dir\\pkg\\package.json', + RUN_SCRIPT_EXEC: 'ls', }) t.strictSame(output, []) })) @@ -217,14 +240,12 @@ t.test('basic non-interactive', t => { t.strictSame({ ERROR_HANDLER_CALLED, - STAT_CALLED, - SPAWN_SHELL_EXEC, - SPAWN_SHELL_ARGS, + RPJ_CALLED, + RUN_SCRIPT_EXEC, }, { ERROR_HANDLER_CALLED: null, - STAT_CALLED: '/npm/dir/pkg', - SPAWN_SHELL_EXEC: 'shell-command', - SPAWN_SHELL_ARGS: ['-c', 'ls'], + RPJ_CALLED: '/npm/dir/pkg/package.json', + RUN_SCRIPT_EXEC: 'ls', }) t.strictSame(output, []) })) @@ -232,33 +253,93 @@ t.test('basic non-interactive', t => { t.end() }) -t.test('usage if no pkg provided', t => { - t.teardown(() => { +t.test('signal fails non-interactive', t => { + const { exitCode } = process + t.afterEach((cb) => { output.length = 0 - ERROR_HANDLER_CALLED = null + logs.length = 0 + cb() }) - t.plan(1) - posixExplore([], er => { - if (er) - throw er + + t.beforeEach(cb => { + RUN_SCRIPT_SIGNAL = 'SIGPROBLEM' + RUN_SCRIPT_EXIT_CODE = null + process.exitCode = exitCode + cb() + }) + t.afterEach(cb => { + process.exitCode = exitCode + cb() + }) + + t.test('windows', t => windowsExplore(['pkg', 'ls'], er => { + t.match(er, { + message: 'command failed', + signal: 'SIGPROBLEM', + }) t.strictSame({ - ERROR_HANDLER_CALLED: null, - STAT_CALLED, - SPAWN_SHELL_EXEC, - SPAWN_SHELL_ARGS, + RPJ_CALLED, + RUN_SCRIPT_EXEC, }, { - ERROR_HANDLER_CALLED: null, - STAT_CALLED: '/npm/dir/pkg', - SPAWN_SHELL_EXEC: 'shell-command', - SPAWN_SHELL_ARGS: ['-c', 'ls'], + RPJ_CALLED: 'c:\\npm\\dir\\pkg\\package.json', + RUN_SCRIPT_EXEC: 'ls', + }) + t.strictSame(output, []) + })) + + t.test('posix', t => posixExplore(['pkg', 'ls'], er => { + t.match(er, { + message: 'command failed', + signal: 'SIGPROBLEM', }) - }).catch(er => t.equal(er, 'npm explore <pkg> [ -- <command>]')) + + t.strictSame({ + RPJ_CALLED, + RUN_SCRIPT_EXEC, + }, { + RPJ_CALLED: '/npm/dir/pkg/package.json', + RUN_SCRIPT_EXEC: 'ls', + }) + t.strictSame(output, []) + })) + + t.end() +}) + +t.test('usage if no pkg provided', t => { + t.teardown(() => { + output.length = 0 + ERROR_HANDLER_CALLED = null + }) + const noPkg = [ + [], + ['foo/../..'], + ['asdf/..'], + ['.'], + ['..'], + ['../..'], + ] + t.plan(noPkg.length) + for (const args of noPkg) { + t.test(JSON.stringify(args), t => posixExplore(args, er => { + t.equal(er, 'npm explore <pkg> [ -- <command>]') + t.strictSame({ + ERROR_HANDLER_CALLED: null, + RPJ_CALLED, + RUN_SCRIPT_EXEC, + }, { + ERROR_HANDLER_CALLED: null, + RPJ_CALLED: '/npm/dir/pkg/package.json', + RUN_SCRIPT_EXEC: 'ls', + }) + })) + } }) t.test('pkg not installed', t => { - STAT_ERROR = new Error('plurple') - t.plan(1) + RPJ_ERROR = new Error('plurple') + t.plan(2) posixExplore(['pkg', 'ls'], er => { if (er) @@ -266,17 +347,17 @@ t.test('pkg not installed', t => { t.strictSame({ ERROR_HANDLER_CALLED, - STAT_CALLED, - SPAWN_SHELL_EXEC, - SPAWN_SHELL_ARGS, + RPJ_CALLED, + RUN_SCRIPT_EXEC, }, { ERROR_HANDLER_CALLED: null, - STAT_CALLED: '/npm/dir/pkg', - SPAWN_SHELL_EXEC: 'shell-command', - SPAWN_SHELL_ARGS: ['-c', 'ls'], + RPJ_CALLED: '/npm/dir/pkg/package.json', + RUN_SCRIPT_EXEC: 'ls', }) t.strictSame(output, []) }).catch(er => { - t.match(er, { message: `It doesn't look like pkg is installed.` }) + t.match(er, { message: 'plurple' }) + t.match(logs, [['explore', `It doesn't look like pkg is installed.`]]) + logs.length = 0 }) }) diff --git a/deps/npm/test/lib/set-script.js b/deps/npm/test/lib/set-script.js new file mode 100644 index 0000000000..ab25ba968a --- /dev/null +++ b/deps/npm/test/lib/set-script.js @@ -0,0 +1,154 @@ +const test = require('tap') +const requireInject = require('require-inject') +const setScriptDefault = require('../../lib/set-script.js') +const parseJSON = require('json-parse-even-better-errors') + +test.type(setScriptDefault, 'function', 'command is function') +test.equal(setScriptDefault.completion, require('../../lib/utils/completion/none.js'), 'empty completion') +test.equal(setScriptDefault.usage, 'npm set-script [<script>] [<command>]', 'usage matches') +test.test('fails on invalid arguments', (t) => { + const setScript = requireInject('../../lib/set-script.js', { + fs: {}, + npmlog: {}, + }) + t.plan(3) + setScript(['arg1'], (fail) => t.match(fail, /Expected 2 arguments: got 1/)) + setScript(['arg1', 'arg2', 'arg3'], (fail) => t.match(fail, /Expected 2 arguments: got 3/)) + setScript(['arg1', 'arg2', 'arg3', 'arg4'], (fail) => t.match(fail, /Expected 2 arguments: got 4/)) +}) +test.test('fails if run in postinstall script', (t) => { + var originalVar = process.env.npm_lifecycle_event + process.env.npm_lifecycle_event = 'postinstall' + const setScript = requireInject('../../lib/set-script.js', { + fs: {}, + npmlog: {}, + }) + t.plan(1) + setScript(['arg1', 'arg2'], (fail) => t.equal(fail.toString(), 'Error: Scripts can’t set from the postinstall script')) + process.env.npm_lifecycle_event = originalVar +}) +test.test('fails when package.json not found', (t) => { + const setScript = requireInject('../../lib/set-script.js', { + '../../lib/npm.js': { + localPrefix: 'IDONTEXIST', + }, + }) + t.plan(1) + setScript(['arg1', 'arg2'], (fail) => t.match(fail, /package.json not found/)) +}) +test.test('fails on invalid JSON', (t) => { + const setScript = requireInject('../../lib/set-script.js', { + fs: { + readFileSync: (name, charcode) => { + return 'iamnotjson' + }, + }, + }) + t.plan(1) + setScript(['arg1', 'arg2'], (fail) => t.match(fail, /Invalid package.json: JSONParseError/)) +}) +test.test('creates scripts object', (t) => { + var mockFile = '' + const setScript = requireInject('../../lib/set-script.js', { + fs: { + readFileSync: (name, charcode) => { + return '{}' + }, + writeFileSync: (location, inner) => { + mockFile = inner + }, + }, + 'read-package-json-fast': async function (filename) { + return { + [Symbol.for('indent')]: ' ', + [Symbol.for('newline')]: '\n', + } + }, + }) + t.plan(2) + setScript(['arg1', 'arg2'], (error) => { + t.equal(error, undefined) + t.assert(parseJSON(mockFile), {scripts: {arg1: 'arg2'}}) + }) +}) +test.test('warns before overwriting', (t) => { + var warningListened = '' + const setScript = requireInject('../../lib/set-script.js', { + fs: { + readFileSync: (name, charcode) => { + return JSON.stringify({ + scripts: { + arg1: 'blah', + }, + }) + }, + writeFileSync: (name, content) => {}, + }, + 'read-package-json-fast': async function (filename) { + return { + [Symbol.for('indent')]: ' ', + [Symbol.for('newline')]: '\n', + } + }, + npmlog: { + warn: (prefix, message) => { + warningListened = message + }, + }, + }) + t.plan(2) + setScript(['arg1', 'arg2'], (error) => { + t.equal(error, undefined, 'no error') + t.equal(warningListened, 'Script "arg1" was overwritten') + }) +}) +test.test('provided indentation and eol is used', (t) => { + var mockFile = '' + const setScript = requireInject('../../lib/set-script.js', { + fs: { + readFileSync: (name, charcode) => { + return '{}' + }, + writeFileSync: (name, content) => { + mockFile = content + }, + }, + 'read-package-json-fast': async function (filename) { + return { + [Symbol.for('indent')]: ' '.repeat(6), + [Symbol.for('newline')]: '\r\n', + } + }, + }) + t.plan(3) + setScript(['arg1', 'arg2'], (error) => { + t.equal(error, undefined) + t.equal(mockFile.split('\r\n').length > 1, true) + t.equal(mockFile.split('\r\n').every((value) => !value.startsWith(' ') || value.startsWith(' '.repeat(6))), true) + }) +}) +test.test('goes to default when undefined indent and eol provided', (t) => { + var mockFile = '' + const setScript = requireInject('../../lib/set-script.js', { + fs: { + readFileSync: (name, charcode) => { + return '{}' + }, + writeFileSync: (name, content) => { + mockFile = content + }, + }, + 'read-package-json-fast': async function (filename) { + return { + [Symbol.for('indent')]: undefined, + [Symbol.for('newline')]: undefined, + } + }, + }) + t.plan(3) + setScript(['arg1', 'arg2'], (error) => { + t.equal(error, undefined) + t.equal(mockFile.split('\n').length > 1, true) + t.equal(mockFile.split('\n').every((value) => !value.startsWith(' ') || value.startsWith(' ')), true) + }) +}) diff --git a/deps/npm/test/lib/uninstall.js b/deps/npm/test/lib/uninstall.js new file mode 100644 index 0000000000..69040c0f25 --- /dev/null +++ b/deps/npm/test/lib/uninstall.js @@ -0,0 +1,253 @@ +const fs = require('fs') +const { resolve } = require('path') +const t = require('tap') +const requireInject = require('require-inject') + +const npm = { + globalDir: '', + flatOptions: { + global: false, + prefix: '', + }, + localPrefix: '', +} +const mocks = { + '../../lib/npm.js': npm, + '../../lib/utils/reify-finish.js': () => Promise.resolve(), + '../../lib/utils/usage.js': () => 'usage instructions', +} + +const uninstall = requireInject('../../lib/uninstall.js', mocks) + +t.afterEach(cb => { + npm.globalDir = '' + npm.prefix = '' + npm.flatOptions.global = false + npm.flatOptions.prefix = '' + cb() +}) + +t.test('remove single installed lib', t => { + const path = t.testdir({ + 'package.json': JSON.stringify({ + name: 'test-rm-single-lib', + version: '1.0.0', + dependencies: { + a: '*', + b: '*', + }, + }), + node_modules: { + a: { + 'package.json': JSON.stringify({ + name: 'a', + version: '1.0.0', + }), + }, + b: { + 'package.json': JSON.stringify({ + name: 'b', + version: '1.0.0', + }), + }, + }, + 'package-lock.json': JSON.stringify({ + name: 'test-rm-single-lib', + version: '1.0.0', + lockfileVersion: 2, + requires: true, + packages: { + '': { + name: 'test-rm-single-lib', + version: '1.0.0', + dependencies: { + a: '*', + }, + }, + 'node_modules/a': { + version: '1.0.0', + }, + 'node_modules/b': { + version: '1.0.0', + }, + }, + dependencies: { + a: { + version: '1.0.0', + }, + b: { + version: '1.0.0', + }, + }, + }), + }) + + const b = resolve(path, 'node_modules/b') + t.ok(() => fs.statSync(b)) + + npm.flatOptions.prefix = path + + uninstall(['b'], err => { + if (err) + throw err + + t.throws(() => fs.statSync(b), 'should have removed package from nm') + t.end() + }) +}) + +t.test('remove multiple installed libs', t => { + const path = t.testdir({ + node_modules: { + a: { + 'package.json': JSON.stringify({ + name: 'a', + version: '1.0.0', + }), + }, + b: { + 'package.json': JSON.stringify({ + name: 'b', + version: '1.0.0', + }), + }, + }, + 'package-lock.json': JSON.stringify({ + name: 'test-rm-single-lib', + version: '1.0.0', + lockfileVersion: 2, + requires: true, + packages: { + '': { + name: 'test-rm-single-lib', + version: '1.0.0', + dependencies: { + a: '*', + }, + }, + 'node_modules/a': { + version: '1.0.0', + }, + 'node_modules/b': { + version: '1.0.0', + }, + }, + dependencies: { + a: { + version: '1.0.0', + }, + b: { + version: '1.0.0', + }, + }, + }), + }) + + const a = resolve(path, 'node_modules/a') + const b = resolve(path, 'node_modules/b') + t.ok(() => fs.statSync(a)) + t.ok(() => fs.statSync(b)) + + npm.flatOptions.prefix = path + + uninstall(['b'], err => { + if (err) + throw err + + t.throws(() => fs.statSync(a), 'should have removed a package from nm') + t.throws(() => fs.statSync(b), 'should have removed b package from nm') + t.end() + }) +}) + +t.test('no args local', t => { + const path = t.testdir() + + npm.flatOptions.prefix = path + + uninstall([], err => { + t.match( + err, + /Must provide a package name to remove/, + 'should throw package name required error' + ) + + t.end() + }) +}) + +t.test('no args global', t => { + const path = t.testdir({ + lib: { + node_modules: { + a: t.fixture('symlink', '../../projects/a'), + }, + }, + projects: { + a: { + 'package.json': JSON.stringify({ + name: 'a', + version: '1.0.0', + }), + }, + }, + }) + + npm.localPrefix = resolve(path, 'projects', 'a') + npm.globalDir = resolve(path, 'lib', 'node_modules') + npm.flatOptions.global = true + npm.flatOptions.prefix = path + + const a = resolve(path, 'lib/node_modules/a') + t.ok(() => fs.statSync(a)) + + uninstall([], err => { + if (err) + throw err + + t.throws(() => fs.statSync(a), 'should have removed global nm symlink') + + t.end() + }) +}) + +t.test('no args global but no package.json', t => { + const path = t.testdir({}) + + npm.prefix = path + npm.localPrefix = path + npm.flatOptions.global = true + + uninstall([], err => { + t.match( + err, + 'usage instructions', + 'should throw usage instructions' + ) + + t.end() + }) +}) + +t.test('unknown error reading from localPrefix package.json', t => { + const path = t.testdir({}) + + const uninstall = requireInject('../../lib/uninstall.js', { + ...mocks, + 'read-package-json-fast': () => Promise.reject(new Error('ERR')), + }) + + npm.prefix = path + npm.localPrefix = path + npm.flatOptions.global = true + + uninstall([], err => { + t.match( + err, + /ERR/, + 'should throw unknown error' + ) + + t.end() + }) +}) diff --git a/deps/npm/test/lib/update.js b/deps/npm/test/lib/update.js new file mode 100644 index 0000000000..993fbbab56 --- /dev/null +++ b/deps/npm/test/lib/update.js @@ -0,0 +1,162 @@ +const { resolve } = require('path') +const t = require('tap') +const requireInject = require('require-inject') + +const noop = () => null +const npm = { + globalDir: '', + flatOptions: { + depth: 0, + global: false, + }, + prefix: '', +} +const mocks = { + npmlog: { warn () {} }, + '@npmcli/arborist': class { + reify () {} + }, + '../../lib/npm.js': npm, + '../../lib/utils/reify-finish.js': noop, + '../../lib/utils/usage.js': () => 'usage instructions', +} + +t.afterEach(cb => { + npm.prefix = '' + npm.flatOptions.global = false + npm.globalDir = '' + cb() +}) + +t.test('no args', t => { + t.plan(3) + + npm.prefix = '/project/a' + + class Arborist { + constructor (args) { + t.deepEqual( + args, + { ...npm.flatOptions, path: npm.prefix }, + 'should call arborist contructor with expected args' + ) + } + + reify ({ update }) { + t.equal(update, true, 'should update all deps') + } + } + + const update = requireInject('../../lib/update.js', { + ...mocks, + '../../lib/utils/reify-finish.js': (arb) => { + t.isLike(arb, Arborist, 'should reify-finish with arborist instance') + }, + '@npmcli/arborist': Arborist, + }) + + update([], err => { + if (err) + throw err + }) +}) + +t.test('with args', t => { + t.plan(3) + + npm.prefix = '/project/a' + + class Arborist { + constructor (args) { + t.deepEqual( + args, + { ...npm.flatOptions, path: npm.prefix }, + 'should call arborist contructor with expected args' + ) + } + + reify ({ update }) { + t.deepEqual(update, ['ipt'], 'should update listed deps') + } + } + + const update = requireInject('../../lib/update.js', { + ...mocks, + '../../lib/utils/reify-finish.js': (arb) => { + t.isLike(arb, Arborist, 'should reify-finish with arborist instance') + }, + '@npmcli/arborist': Arborist, + }) + + update(['ipt'], err => { + if (err) + throw err + }) +}) + +t.test('update --depth=<number>', t => { + t.plan(2) + + npm.prefix = '/project/a' + npm.flatOptions.depth = 1 + + const update = requireInject('../../lib/update.js', { + ...mocks, + npmlog: { + warn: (title, msg) => { + t.equal(title, 'update', 'should print expected title') + t.match( + msg, + /The --depth option no longer has any effect/, + 'should print expected warning message' + ) + }, + }, + }) + + update([], err => { + if (err) + throw err + }) +}) + +t.test('update --global', t => { + t.plan(2) + + const normalizePath = p => p.replace(/\\+/g, '/') + const redactCwd = (path) => normalizePath(path) + .replace(new RegExp(normalizePath(process.cwd()), 'g'), '{CWD}') + + npm.prefix = '/project/a' + npm.globalDir = resolve(process.cwd(), 'global/lib/node_modules') + npm.flatOptions.global = true + + class Arborist { + constructor (args) { + const { path, ...opts } = args + t.deepEqual( + opts, + npm.flatOptions, + 'should call arborist contructor with expected options' + ) + + t.equal( + redactCwd(path), + '{CWD}/global/lib', + 'should run with expected prefix' + ) + } + + reify () {} + } + + const update = requireInject('../../lib/update.js', { + ...mocks, + '@npmcli/arborist': Arborist, + }) + + update([], err => { + if (err) + throw err + }) +}) diff --git a/deps/npm/test/lib/utils/escape-arg.js b/deps/npm/test/lib/utils/escape-arg.js deleted file mode 100644 index b80a63f0b8..0000000000 --- a/deps/npm/test/lib/utils/escape-arg.js +++ /dev/null @@ -1,15 +0,0 @@ -const requireInject = require('require-inject') -const t = require('tap') -const getEscape = win => requireInject('../../../lib/utils/escape-arg.js', { - '../../../lib/utils/is-windows.js': win, - path: require('path')[win ? 'win32' : 'posix'], -}) - -const winEscape = getEscape(true) -const nixEscape = getEscape(false) - -t.equal(winEscape('hello/to the/world'), '"hello\\to the\\world"') -t.equal(nixEscape(`hello/to-the/world`), `hello/to-the/world`) -t.equal(nixEscape(`hello/to the/world`), `'hello/to the/world'`) -t.equal(nixEscape(`hello/to%the/world`), `'hello/to%the/world'`) -t.equal(nixEscape(`hello/to'the/world`), `'hello/to'"'"'the/world'`) diff --git a/deps/npm/test/lib/utils/escape-exec-path.js b/deps/npm/test/lib/utils/escape-exec-path.js deleted file mode 100644 index f16c576ec5..0000000000 --- a/deps/npm/test/lib/utils/escape-exec-path.js +++ /dev/null @@ -1,15 +0,0 @@ -const requireInject = require('require-inject') -const t = require('tap') -const getEscape = win => requireInject('../../../lib/utils/escape-exec-path.js', { - '../../../lib/utils/is-windows.js': win, - path: require('path')[win ? 'win32' : 'posix'], -}) - -const winEscape = getEscape(true) -const nixEscape = getEscape(false) - -t.equal(winEscape('hello/to the/world'), 'hello\\"to the"\\world') -t.equal(nixEscape(`hello/to-the/world`), `hello/to-the/world`) -t.equal(nixEscape(`hello/to the/world`), `'hello/to the/world'`) -t.equal(nixEscape(`hello/to%the/world`), `'hello/to%the/world'`) -t.equal(nixEscape(`hello/to'the/world`), `'hello/to'"'"'the/world'`) |