diff options
author | Ruy Adorno <ruyadorno@hotmail.com> | 2021-05-13 23:18:53 +0300 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2021-05-17 10:11:38 +0300 |
commit | 608d0e11f3007648276520e81d6d9672a434f10b (patch) | |
tree | 551f98341331d56460d346b8d1dc70a6c4bd6933 /deps | |
parent | 1765e32c45a3904cc250bc1bdb2333afb970b5e8 (diff) |
deps: upgrade npm to 7.13.0
PR-URL: https://github.com/nodejs/node/pull/38682
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Danielle Adams <adamzdanielle@gmail.com>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Diffstat (limited to 'deps')
28 files changed, 846 insertions, 99 deletions
diff --git a/deps/npm/CHANGELOG.md b/deps/npm/CHANGELOG.md index bed0f87c2b8..1c36c70875f 100644 --- a/deps/npm/CHANGELOG.md +++ b/deps/npm/CHANGELOG.md @@ -1,3 +1,21 @@ +## v7.13.0 (2021-05-13) + +* [`076420c14`](https://github.com/npm/cli/commit/076420c149d097056f687e44e21744b743b86e4e) + [#3231](https://github.com/npm/cli/issues/3231) + feat(publish): add workspace support + ([@wraithgar](https://github.com/wraithgar)) +* [`370b36a36`](https://github.com/npm/cli/commit/370b36a36ca226840761e4214cbccaf2a1a90e3c) + [#3241](https://github.com/npm/cli/issues/3241) + feat(fund): add workspaces support + ([@ruyadorno](https://github.com/ruyadorno)) + +### DEPENDENCIES + +* [`0c18e4f77`](https://github.com/npm/cli/commit/0c18e4f774562fa054fedf323bea25805ebf39b3) + `@npmcli/arborist@2.5.0` +* [`b551c6811`](https://github.com/npm/cli/commit/b551c6811251dbc901f47fea3c137f93e205a9e4) + `libnpmfund@1.1.0` + ## v7.12.1 (2021-05-10) ### BUG FIXES diff --git a/deps/npm/docs/content/commands/npm-fund.md b/deps/npm/docs/content/commands/npm-fund.md index aa1b26b9a89..45c5dfaac2a 100644 --- a/deps/npm/docs/content/commands/npm-fund.md +++ b/deps/npm/docs/content/commands/npm-fund.md @@ -8,6 +8,7 @@ description: Retrieve funding information ```bash npm fund [<pkg>] +npm fund [-w <workspace-name>] ``` ### Description @@ -24,6 +25,43 @@ The list will avoid duplicated entries and will stack all packages that share the same url as a single entry. Thus, the list does not have the same shape of the output from `npm ls`. +#### Example + +### Workspaces support + +It's possible to filter the results to only include a single workspace and its +dependencies using the `workspace` config option. + +#### Example: + +Here's an example running `npm fund` in a project with a configured +workspace `a`: + +```bash +$ npm fund +test-workspaces-fund@1.0.0 ++-- https://example.com/a +| | `-- a@1.0.0 +| `-- https://example.com/maintainer +| `-- foo@1.0.0 ++-- https://example.com/npmcli-funding +| `-- @npmcli/test-funding +`-- https://example.com/org + `-- bar@2.0.0 +``` + +And here is an example of the expected result when filtering only by +a specific workspace `a` in the same project: + +```bash +$ npm fund -w a +test-workspaces-fund@1.0.0 +`-- https://example.com/a + | `-- a@1.0.0 + `-- https://example.com/maintainer + `-- foo@2.0.0 +``` + ### Configuration #### browser @@ -48,6 +86,23 @@ Show information in JSON format. Whether to represent the tree structure using unicode characters. Set it to `false` in order to use all-ansi output. +#### `workspace` + +* Default: +* Type: String (can be set multiple times) + +Enable running a command in the context of the configured workspaces of the +current project while filtering by running only the workspaces defined by +this configuration option. + +Valid values for the `workspace` config are either: +* Workspace names +* Path to a workspace directory +* Path to a parent workspace directory (will result to selecting all of the +nested workspaces) + +This value is not exported to the environment for child processes. + #### which * Type: Number @@ -61,3 +116,4 @@ If there are multiple funding sources, which 1-indexed source URL to open. * [npm docs](/commands/npm-docs) * [npm ls](/commands/npm-ls) * [npm config](/commands/npm-config) +* [npm workspaces](/using-npm/workspaces) diff --git a/deps/npm/docs/content/commands/npm-publish.md b/deps/npm/docs/content/commands/npm-publish.md index fc13e672223..10e65f895ec 100644 --- a/deps/npm/docs/content/commands/npm-publish.md +++ b/deps/npm/docs/content/commands/npm-publish.md @@ -47,6 +47,13 @@ by specifying a different default registry or using a actually publishing to the registry. Reports the details of what would have been published. +* `[--workspaces]`: Enables workspace context while publishing. All + workspace packages will be published. + +* `[--workspace]`: Enables workspaces context and limits results to only + those specified by this config item. Only the packages in the + workspaces given will be published. + The publish will fail if the package name and version combination already exists in the specified registry. diff --git a/deps/npm/docs/output/commands/npm-fund.html b/deps/npm/docs/output/commands/npm-fund.html index bd9118fe326..16539cfd998 100644 --- a/deps/npm/docs/output/commands/npm-fund.html +++ b/deps/npm/docs/output/commands/npm-fund.html @@ -146,6 +146,7 @@ npm command-line interface <div id="_content"><h3 id="synopsis">Synopsis</h3> <pre lang="bash"><code>npm fund [<pkg>] +npm fund [-w <workspace-name>] </code></pre> <h3 id="description">Description</h3> <p>This command retrieves information on how to fund the dependencies of a @@ -158,6 +159,33 @@ to pass the <code>--which</code> option to disambiguate.</p> <p>The list will avoid duplicated entries and will stack all packages that share the same url as a single entry. Thus, the list does not have the same shape of the output from <code>npm ls</code>.</p> +<h4 id="example">Example</h4> +<h3 id="workspaces-support">Workspaces support</h3> +<p>It’s possible to filter the results to only include a single workspace and its +dependencies using the <code>workspace</code> config option.</p> +<h4 id="example2">Example:</h4> +<p>Here’s an example running <code>npm fund</code> in a project with a configured +workspace <code>a</code>:</p> +<pre lang="bash"><code>$ npm fund +test-workspaces-fund@1.0.0 ++-- https://example.com/a +| | `-- a@1.0.0 +| `-- https://example.com/maintainer +| `-- foo@1.0.0 ++-- https://example.com/npmcli-funding +| `-- @npmcli/test-funding +`-- https://example.com/org + `-- bar@2.0.0 +</code></pre> +<p>And here is an example of the expected result when filtering only by +a specific workspace <code>a</code> in the same project:</p> +<pre lang="bash"><code>$ npm fund -w a +test-workspaces-fund@1.0.0 +`-- https://example.com/a + | `-- a@1.0.0 + `-- https://example.com/maintainer + `-- foo@2.0.0 +</code></pre> <h3 id="configuration">Configuration</h3> <h4 id="browser">browser</h4> <ul> @@ -178,6 +206,22 @@ shape of the output from <code>npm ls</code>.</p> </ul> <p>Whether to represent the tree structure using unicode characters. Set it to <code>false</code> in order to use all-ansi output.</p> +<h4 id="workspace"><code>workspace</code></h4> +<ul> +<li>Default:</li> +<li>Type: String (can be set multiple times)</li> +</ul> +<p>Enable running a command in the context of the configured workspaces of the +current project while filtering by running only the workspaces defined by +this configuration option.</p> +<p>Valid values for the <code>workspace</code> config are either:</p> +<ul> +<li>Workspace names</li> +<li>Path to a workspace directory</li> +<li>Path to a parent workspace directory (will result to selecting all of the +nested workspaces)</li> +</ul> +<p>This value is not exported to the environment for child processes.</p> <h4 id="which">which</h4> <ul> <li>Type: Number</li> @@ -190,6 +234,7 @@ Set it to <code>false</code> in order to use all-ansi output.</p> <li><a href="../commands/npm-docs.html">npm docs</a></li> <li><a href="../commands/npm-ls.html">npm ls</a></li> <li><a href="../commands/npm-config.html">npm config</a></li> +<li><a href="../using-npm/workspaces.html">npm workspaces</a></li> </ul> </div> diff --git a/deps/npm/docs/output/commands/npm-ls.html b/deps/npm/docs/output/commands/npm-ls.html index 3d60f2baecd..be1f7cd94a6 100644 --- a/deps/npm/docs/output/commands/npm-ls.html +++ b/deps/npm/docs/output/commands/npm-ls.html @@ -159,7 +159,7 @@ tree at all, use <a href="../commands/npm-explain.html"><code>npm explain</code> the results to only the paths to the packages named. Note that nested packages will <em>also</em> show the paths to the specified packages. For example, running <code>npm ls promzard</code> in npm’s source tree will show:</p> -<pre lang="bash"><code>npm@7.12.1 /path/to/npm +<pre lang="bash"><code>npm@7.13.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-publish.html b/deps/npm/docs/output/commands/npm-publish.html index fc9136d356b..159566e09a0 100644 --- a/deps/npm/docs/output/commands/npm-publish.html +++ b/deps/npm/docs/output/commands/npm-publish.html @@ -188,6 +188,15 @@ from a TTY then you’ll be prompted.</p> actually publishing to the registry. Reports the details of what would have been published.</p> </li> +<li> +<p><code>[--workspaces]</code>: Enables workspace context while publishing. All +workspace packages will be published.</p> +</li> +<li> +<p><code>[--workspace]</code>: Enables workspaces context and limits results to only +those specified by this config item. Only the packages in the +workspaces given will be published.</p> +</li> </ul> <p>The publish will fail if the package name and version combination already exists in the specified registry.</p> diff --git a/deps/npm/docs/output/commands/npm.html b/deps/npm/docs/output/commands/npm.html index 445abd0d5ce..1adcb07e046 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.12.1</p> +<p>7.13.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/fund.js b/deps/npm/lib/fund.js index 25d3462f638..55d2f65dc4b 100644 --- a/deps/npm/lib/fund.js +++ b/deps/npm/lib/fund.js @@ -13,15 +13,14 @@ const { const completion = require('./utils/completion/installed-deep.js') const openUrl = require('./utils/open-url.js') +const ArboristWorkspaceCmd = require('./workspaces/arborist-cmd.js') const getPrintableName = ({ name, version }) => { const printableVersion = version ? `@${version}` : '' return `${name}${printableVersion}` } -const BaseCommand = require('./base-command.js') - -class Fund extends BaseCommand { +class Fund extends ArboristWorkspaceCmd { /* istanbul ignore next - see test/lib/load-all-commands.js */ static get description () { return 'Retrieve funding information' @@ -38,6 +37,7 @@ class Fund extends BaseCommand { 'json', 'browser', 'unicode', + 'workspace', 'which', ] } @@ -92,10 +92,16 @@ class Fund extends BaseCommand { return } + const fundingInfo = getFundingInfo(tree, { + ...this.flatOptions, + log: this.npm.log, + workspaces: this.workspaces, + }) + if (this.npm.config.get('json')) - this.npm.output(this.printJSON(getFundingInfo(tree))) + this.npm.output(this.printJSON(fundingInfo)) else - this.npm.output(this.printHuman(getFundingInfo(tree))) + this.npm.output(this.printHuman(fundingInfo)) } printJSON (fundingInfo) { diff --git a/deps/npm/lib/publish.js b/deps/npm/lib/publish.js index b121cb3d367..b33839903a2 100644 --- a/deps/npm/lib/publish.js +++ b/deps/npm/lib/publish.js @@ -8,13 +8,19 @@ const pacote = require('pacote') const npa = require('npm-package-arg') const npmFetch = require('npm-registry-fetch') -const flatten = require('./utils/config/flatten.js') const otplease = require('./utils/otplease.js') const { getContents, logTar } = require('./utils/tar.js') +const getWorkspaces = require('./workspaces/get-workspaces.js') + +// for historical reasons, publishConfig in package.json can contain ANY config +// keys that npm supports in .npmrc files and elsewhere. We *may* want to +// revisit this at some point, and have a minimal set that's a SemVer-major +// change that ought to get a RFC written on it. +const flatten = require('./utils/config/flatten.js') -// this is the only case in the CLI where we use the old full slow -// 'read-package-json' module, because we want to pull in all the -// defaults and metadata, like git sha's and default scripts and all that. +// this is the only case in the CLI where we want to use the old full slow +// 'read-package-json' module, because we want to pull in all the defaults and +// metadata, like git sha's and default scripts and all that. const readJson = util.promisify(require('read-package-json')) const BaseCommand = require('./base-command.js') @@ -30,7 +36,7 @@ class Publish extends BaseCommand { /* istanbul ignore next - see test/lib/load-all-commands.js */ static get params () { - return ['tag', 'access', 'dry-run'] + return ['tag', 'access', 'dry-run', 'workspace', 'workspaces'] } /* istanbul ignore next - see test/lib/load-all-commands.js */ @@ -44,6 +50,10 @@ class Publish extends BaseCommand { this.publish(args).then(() => cb()).catch(cb) } + execWorkspaces (args, filters, cb) { + this.publishWorkspaces(args, filters).then(() => cb()).catch(cb) + } + async publish (args) { if (args.length === 0) args = ['.'] @@ -56,6 +66,7 @@ class Publish extends BaseCommand { const dryRun = this.npm.config.get('dry-run') const json = this.npm.config.get('json') const defaultTag = this.npm.config.get('tag') + const silent = log.level === 'silent' if (semver.validRange(defaultTag)) throw new Error('Tag name must not be a valid SemVer range: ' + defaultTag.trim()) @@ -68,7 +79,7 @@ class Publish extends BaseCommand { let manifest = await this.getManifest(spec, opts) if (manifest.publishConfig) - Object.assign(opts, this.publishConfigToOpts(manifest.publishConfig)) + flatten(manifest.publishConfig, opts) // only run scripts for directory type publishes if (spec.type === 'directory') { @@ -77,7 +88,7 @@ class Publish extends BaseCommand { path: spec.fetchSpec, stdio: 'inherit', pkg: manifest, - banner: log.level !== 'silent', + banner: !silent, }) } @@ -89,7 +100,7 @@ class Publish extends BaseCommand { // note that publishConfig might have changed as well! manifest = await this.getManifest(spec, opts) if (manifest.publishConfig) - Object.assign(opts, this.publishConfigToOpts(manifest.publishConfig)) + flatten(manifest.publishConfig, opts) // note that logTar calls npmlog.notice(), so if we ARE in silent mode, // this will do nothing, but we still want it in the debuglog if it fails. @@ -114,7 +125,7 @@ class Publish extends BaseCommand { path: spec.fetchSpec, stdio: 'inherit', pkg: manifest, - banner: log.level !== 'silent', + banner: !silent, }) await runScript({ @@ -122,19 +133,43 @@ class Publish extends BaseCommand { path: spec.fetchSpec, stdio: 'inherit', pkg: manifest, - banner: log.level !== 'silent', + banner: !silent, }) } - const silent = log.level === 'silent' - if (!silent && json) - this.npm.output(JSON.stringify(pkgContents, null, 2)) - else if (!silent) - this.npm.output(`+ ${pkgContents.id}`) + if (!this.workspaces) { + if (!silent && json) + this.npm.output(JSON.stringify(pkgContents, null, 2)) + else if (!silent) + this.npm.output(`+ ${pkgContents.id}`) + } return pkgContents } + async publishWorkspaces (args, filters) { + // Suppresses JSON output in publish() so we can handle it here + this.workspaces = true + + const results = {} + const json = this.npm.config.get('json') + const silent = log.level === 'silent' + const workspaces = + await getWorkspaces(filters, { path: this.npm.localPrefix }) + for (const [name, workspace] of workspaces.entries()) { + const pkgContents = await this.publish([workspace]) + // This needs to be in-line w/ the rest of the output that non-JSON + // publish generates + if (!silent && !json) + this.npm.output(`+ ${pkgContents.id}`) + else + results[name] = pkgContents + } + + if (!silent && json) + this.npm.output(JSON.stringify(results, null, 2)) + } + // if it's a directory, read it from the file system // otherwise, get the full metadata from whatever it is getManifest (spec, opts) { @@ -142,16 +177,5 @@ class Publish extends BaseCommand { return readJson(`${spec.fetchSpec}/package.json`) return pacote.manifest(spec, { ...opts, fullMetadata: true }) } - - // for historical reasons, publishConfig in package.json can contain - // ANY config keys that npm supports in .npmrc files and elsewhere. - // We *may* want to revisit this at some point, and have a minimal set - // that's a SemVer-major change that ought to get a RFC written on it. - publishConfigToOpts (publishConfig) { - // create a new object that inherits from the config stack - // then squash the css-case into camelCase opts, like we do - // this is Object.assign()'ed onto the base npm.flatOptions - return flatten(publishConfig, {}) - } } module.exports = Publish diff --git a/deps/npm/lib/workspaces/arborist-cmd.js b/deps/npm/lib/workspaces/arborist-cmd.js new file mode 100644 index 00000000000..f08843bd9ea --- /dev/null +++ b/deps/npm/lib/workspaces/arborist-cmd.js @@ -0,0 +1,24 @@ +// This is the base for all commands whose execWorkspaces just gets +// a list of workspace names and passes it on to new Arborist() to +// be able to run a filtered Arborist.reify() at some point. + +const BaseCommand = require('../base-command.js') +const getWorkspaces = require('../workspaces/get-workspaces.js') +class ArboristCmd extends BaseCommand { + /* istanbul ignore next - see test/lib/load-all-commands.js */ + static get params () { + return [ + 'workspace', + ] + } + + execWorkspaces (args, filters, cb) { + getWorkspaces(filters, { path: this.npm.localPrefix }) + .then(workspaces => { + this.workspaces = [...workspaces.keys()] + this.exec(args, cb) + }) + } +} + +module.exports = ArboristCmd diff --git a/deps/npm/man/man1/npm-fund.1 b/deps/npm/man/man1/npm-fund.1 index 81a277bb008..aa21dad2318 100644 --- a/deps/npm/man/man1/npm-fund.1 +++ b/deps/npm/man/man1/npm-fund.1 @@ -6,6 +6,7 @@ .RS 2 .nf npm fund [<pkg>] +npm fund [\-w <workspace\-name>] .fi .RE .SS Description @@ -21,6 +22,44 @@ to pass the \fB\-\-which\fP option to disambiguate\. The list will avoid duplicated entries and will stack all packages that share the same url as a single entry\. Thus, the list does not have the same shape of the output from \fBnpm ls\fP\|\. +.SS Example +.SS Workspaces support +.P +It's possible to filter the results to only include a single workspace and its +dependencies using the \fBworkspace\fP config option\. +.SS Example: +.P +Here's an example running \fBnpm fund\fP in a project with a configured +workspace \fBa\fP: +.P +.RS 2 +.nf +$ npm fund +test\-workspaces\-fund@1\.0\.0 ++\-\- https://example\.com/a +| | `\-\- a@1\.0\.0 +| `\-\- https://example\.com/maintainer +| `\-\- foo@1\.0\.0 ++\-\- https://example\.com/npmcli\-funding +| `\-\- @npmcli/test\-funding +`\-\- https://example\.com/org + `\-\- bar@2\.0\.0 +.fi +.RE +.P +And here is an example of the expected result when filtering only by +a specific workspace \fBa\fP in the same project: +.P +.RS 2 +.nf +$ npm fund \-w a +test\-workspaces\-fund@1\.0\.0 +`\-\- https://example\.com/a + | `\-\- a@1\.0\.0 + `\-\- https://example\.com/maintainer + `\-\- foo@2\.0\.0 +.fi +.RE .SS Configuration .SS browser .RS 0 @@ -53,6 +92,32 @@ Default: true .P Whether to represent the tree structure using unicode characters\. Set it to \fBfalse\fP in order to use all\-ansi output\. +.SS \fBworkspace\fP +.RS 0 +.IP \(bu 2 +Default: +.IP \(bu 2 +Type: String (can be set multiple times) + +.RE +.P +Enable running a command in the context of the configured workspaces of the +current project while filtering by running only the workspaces defined by +this configuration option\. +.P +Valid values for the \fBworkspace\fP config are either: +.RS 0 +.IP \(bu 2 +Workspace names +.IP \(bu 2 +Path to a workspace directory +.IP \(bu 2 +Path to a parent workspace directory (will result to selecting all of the +nested workspaces) + +.RE +.P +This value is not exported to the environment for child processes\. .SS which .RS 0 .IP \(bu 2 @@ -73,5 +138,7 @@ npm help docs npm help ls .IP \(bu 2 npm help config +.IP \(bu 2 +npm help workspaces .RE diff --git a/deps/npm/man/man1/npm-ls.1 b/deps/npm/man/man1/npm-ls.1 index c47da918754..d7013b29644 100644 --- a/deps/npm/man/man1/npm-ls.1 +++ b/deps/npm/man/man1/npm-ls.1 @@ -26,7 +26,7 @@ example, running \fBnpm ls promzard\fP in npm's source tree will show: .P .RS 2 .nf -npm@7\.12\.1 /path/to/npm +npm@7\.13\.0 /path/to/npm └─┬ init\-package\-json@0\.0\.4 └── promzard@0\.1\.5 .fi diff --git a/deps/npm/man/man1/npm-publish.1 b/deps/npm/man/man1/npm-publish.1 index c405f64f27e..906c5a36e19 100644 --- a/deps/npm/man/man1/npm-publish.1 +++ b/deps/npm/man/man1/npm-publish.1 @@ -45,6 +45,13 @@ from a TTY then you'll be prompted\. \fB[\-\-dry\-run]\fP: As of \fBnpm@6\fP, does everything publish would do except actually publishing to the registry\. Reports the details of what would have been published\. +.IP \(bu 2 +\fB[\-\-workspaces]\fP: Enables workspace context while publishing\. All +workspace packages will be published\. +.IP \(bu 2 +\fB[\-\-workspace]\fP: Enables workspaces context and limits results to only +those specified by this config item\. Only the packages in the +workspaces given will be published\. .RE .P diff --git a/deps/npm/man/man1/npm.1 b/deps/npm/man/man1/npm.1 index 4562527e1b5..4921bcc656a 100644 --- a/deps/npm/man/man1/npm.1 +++ b/deps/npm/man/man1/npm.1 @@ -10,7 +10,7 @@ npm <command> [args] .RE .SS Version .P -7\.12\.1 +7\.13\.0 .SS Description .P npm is the package manager for the Node JavaScript platform\. It puts diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/index.js b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/index.js index 3578d50389e..cd39df01af6 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/index.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/index.js @@ -45,6 +45,7 @@ const mixins = [ ] const Base = mixins.reduce((a, b) => b(a), require('events')) +const getWorkspaceNodes = require('../get-workspace-nodes.js') class Arborist extends Base { constructor (options = {}) { @@ -64,6 +65,28 @@ class Arborist extends Base { this.path = resolve(this.options.path) process.emit('timeEnd', 'arborist:ctor') } + + // returns an array of the actual nodes for all the workspaces + workspaceNodes (tree, workspaces) { + return getWorkspaceNodes(tree, workspaces, this.log) + } + + // returns a set of workspace nodes and all their deps + workspaceDependencySet (tree, workspaces) { + const wsNodes = this.workspaceNodes(tree, workspaces) + const set = new Set(wsNodes) + for (const node of set) { + for (const edge of node.edgesOut.values()) { + const dep = edge.to + if (dep) { + set.add(dep) + if (dep.target) + set.add(dep.target) + } + } + } + return set + } } module.exports = Arborist diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/get-workspace-nodes.js b/deps/npm/node_modules/@npmcli/arborist/lib/get-workspace-nodes.js new file mode 100644 index 00000000000..6db489f69c5 --- /dev/null +++ b/deps/npm/node_modules/@npmcli/arborist/lib/get-workspace-nodes.js @@ -0,0 +1,33 @@ +// Get the actual nodes corresponding to a root node's child workspaces, +// given a list of workspace names. +const relpath = require('./relpath.js') +const getWorkspaceNodes = (tree, workspaces, log) => { + const wsMap = tree.workspaces + if (!wsMap) { + log.warn('workspaces', 'filter set, but no workspaces present') + return [] + } + + const nodes = [] + for (const name of workspaces) { + const path = wsMap.get(name) + if (!path) { + log.warn('workspaces', `${name} in filter set, but not in workspaces`) + continue + } + + const loc = relpath(tree.realpath, path) + const node = tree.inventory.get(loc) + + if (!node) { + log.warn('workspaces', `${name} in filter set, but no workspace folder present`) + continue + } + + nodes.push(node) + } + + return nodes +} + +module.exports = getWorkspaceNodes diff --git a/deps/npm/node_modules/@npmcli/arborist/package.json b/deps/npm/node_modules/@npmcli/arborist/package.json index bbe87d8bf97..fd579cbf27f 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": "2.4.4", + "version": "2.5.0", "description": "Manage node_modules trees", "dependencies": { "@npmcli/installed-package-contents": "^1.0.7", diff --git a/deps/npm/node_modules/libnpmfund/CHANGELOG.md b/deps/npm/node_modules/libnpmfund/CHANGELOG.md deleted file mode 100644 index b890b58e140..00000000000 --- a/deps/npm/node_modules/libnpmfund/CHANGELOG.md +++ /dev/null @@ -1,6 +0,0 @@ -# Changelog - -## 0.0.0-pre.0 - -- Initial pre-release. - diff --git a/deps/npm/node_modules/libnpmfund/README.md b/deps/npm/node_modules/libnpmfund/README.md index c373a9ceb7d..8ab663f634d 100644 --- a/deps/npm/node_modules/libnpmfund/README.md +++ b/deps/npm/node_modules/libnpmfund/README.md @@ -73,7 +73,10 @@ Options: - `countOnly`: Uses the tree-traversal logic from **npm fund** but skips over any obj definition and just returns an obj containing `{ length }` - useful for things such as printing a `6 packages are looking for funding` msg. -- `path`: Location to current working directory +- `workspaces`: `Array<String>` List of workspaces names to filter for, +the result will only include a subset of the resulting tree that includes +only the nodes that are children of the listed workspaces names. +- `path`, `registry` and more [Arborist](https://github.com/npm/arborist/) options. ##### <a name="fund.readTree"></a> `> fund.readTree(tree, [opts]) -> Promise<Object>` diff --git a/deps/npm/node_modules/libnpmfund/index.js b/deps/npm/node_modules/libnpmfund/index.js index 58aba028e36..37bc1dd0b79 100644 --- a/deps/npm/node_modules/libnpmfund/index.js +++ b/deps/npm/node_modules/libnpmfund/index.js @@ -15,11 +15,11 @@ function normalizeFunding (funding) { // Is the value of a `funding` property of a `package.json` // a valid type+url for `npm fund` to display? function isValidFunding (funding) { - if (!funding) return false + if (!funding) + return false - if (Array.isArray(funding)) { + if (Array.isArray(funding)) return funding.every(f => !Array.isArray(f) && isValidFunding(f)) - } try { var parsed = new URL(funding.url || funding) @@ -30,7 +30,8 @@ function isValidFunding (funding) { if ( parsed.protocol !== 'https:' && parsed.protocol !== 'http:' - ) return false + ) + return false return Boolean(parsed.host) } @@ -43,11 +44,18 @@ function readTree (tree, opts) { const { countOnly } = opts || {} const _trailingDependencies = Symbol('trailingDependencies') + let filterSet + + if (opts && opts.workspaces && opts.workspaces.length) { + const arb = new Arborist(opts) + filterSet = arb.workspaceDependencySet(tree, opts.workspaces) + } + function tracked (name, version) { const key = String(name) + String(version) - if (seen.has(key)) { + if (seen.has(key)) return true - } + seen.add(key) } @@ -81,30 +89,36 @@ function readTree (tree, opts) { function getFundingDependencies (tree) { const edges = tree && tree.edgesOut && tree.edgesOut.values() - if (!edges) return empty() + if (!edges) + return empty() const directDepsWithFunding = Array.from(edges).map(edge => { - if (!edge || !edge.to) return empty() + if (!edge || !edge.to) + return empty() const node = edge.to.target || edge.to - if (!node.package) return empty() + if (!node.package) + return empty() + + if (filterSet && filterSet.size > 0 && !filterSet.has(node)) + return empty() const { name, funding, version } = node.package // avoids duplicated items within the funding tree - if (tracked(name, version)) return empty() + if (tracked(name, version)) + return empty() const fundingItem = {} - if (version) { + if (version) fundingItem.version = version - } attachFundingInfo(fundingItem, funding) return { node, - fundingItem + fundingItem, } }) @@ -112,7 +126,8 @@ function readTree (tree, opts) { (res, { node, fundingItem }, i) => { if (!fundingItem || fundingItem.length === 0 || - !node) return res + !node) + return res // recurse const transitiveDependencies = node.edgesOut && @@ -121,16 +136,17 @@ function readTree (tree, opts) { // if we're only counting items there's no need // to add all the data to the resulting object - if (countOnly) return null + if (countOnly) + return null if (hasDependencies(transitiveDependencies)) { fundingItem.dependencies = retrieveDependencies(transitiveDependencies) } - if (isValidFunding(fundingItem.funding)) { + if (isValidFunding(fundingItem.funding)) res[node.package.name] = fundingItem - } else if (hasDependencies(fundingItem.dependencies)) { + else if (hasDependencies(fundingItem.dependencies)) { res[_trailingDependencies] = Object.assign( empty(), @@ -145,7 +161,7 @@ function readTree (tree, opts) { const treeDependencies = getFundingDependencies(tree) const result = { - length: packageWithFundingCount + length: packageWithFundingCount, } if (!countOnly) { @@ -154,13 +170,11 @@ function readTree (tree, opts) { (tree && tree.name) result.name = name || (tree && tree.path) - if (tree && tree.package && tree.package.version) { + if (tree && tree.package && tree.package.version) result.version = tree.package.version - } - if (tree && tree.package && tree.package.funding) { + if (tree && tree.package && tree.package.funding) result.funding = normalizeFunding(tree.package.funding) - } result.dependencies = retrieveDependencies(treeDependencies) } @@ -170,8 +184,7 @@ function readTree (tree, opts) { async function read (opts) { const arb = new Arborist(opts) - const tree = await arb.loadActual() - + const tree = await arb.loadActual(opts) return readTree(tree, opts) } @@ -179,5 +192,5 @@ module.exports = { read, readTree, normalizeFunding, - isValidFunding + isValidFunding, } diff --git a/deps/npm/node_modules/libnpmfund/package.json b/deps/npm/node_modules/libnpmfund/package.json index b25d3aa6b52..7f4acad383b 100644 --- a/deps/npm/node_modules/libnpmfund/package.json +++ b/deps/npm/node_modules/libnpmfund/package.json @@ -1,6 +1,6 @@ { "name": "libnpmfund", - "version": "1.0.2", + "version": "1.1.0", "files": [ "index.js" ], @@ -25,8 +25,10 @@ ], "license": "ISC", "scripts": { - "lint": "standard", - "pretest": "npm run lint", + "eslint": "eslint", + "lint": "npm run eslint -- index.js test.js", + "lintfix": "npm run lint -- --fix", + "posttest": "npm run lint", "test": "tap", "snap": "tap", "preversion": "npm test", @@ -42,11 +44,14 @@ ] }, "devDependencies": { - "require-inject": "^1.4.4", - "standard": "^14.3.4", - "tap": "^14.10.7" + "eslint": "^7.26.0", + "eslint-plugin-import": "^2.22.1", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^5.1.0", + "eslint-plugin-standard": "^5.0.0", + "tap": "^15.0.9" }, "dependencies": { - "@npmcli/arborist": "^2.0.0" + "@npmcli/arborist": "^2.5.0" } } diff --git a/deps/npm/package.json b/deps/npm/package.json index 70f94838882..f939dacadf2 100644 --- a/deps/npm/package.json +++ b/deps/npm/package.json @@ -1,5 +1,5 @@ { - "version": "7.12.1", + "version": "7.13.0", "name": "npm", "description": "a package manager for JavaScript", "keywords": [ @@ -42,7 +42,7 @@ "./package.json": "./package.json" }, "dependencies": { - "@npmcli/arborist": "^2.4.4", + "@npmcli/arborist": "^2.5.0", "@npmcli/ci-detect": "^1.2.0", "@npmcli/config": "^2.2.0", "@npmcli/run-script": "^1.8.5", @@ -68,7 +68,7 @@ "libnpmaccess": "^4.0.2", "libnpmdiff": "^2.0.4", "libnpmexec": "^1.1.1", - "libnpmfund": "^1.0.2", + "libnpmfund": "^1.1.0", "libnpmhook": "^6.0.2", "libnpmorg": "^2.0.2", "libnpmpack": "^2.0.1", @@ -205,7 +205,7 @@ "sudotest:nocleanup": "sudo NO_TEST_CLEANUP=1 npm run test --", "posttest": "npm run lint", "eslint": "eslint", - "lint": "npm run eslint -- test/lib test/bin \"lib/**/*.js\"", + "lint": "npm run eslint -- test/lib test/bin lib", "lintfix": "npm run lint -- --fix", "prelint": "rimraf test/npm_cache*", "resetdeps": "bash scripts/resetdeps.sh", diff --git a/deps/npm/tap-snapshots/test/lib/fund.js.test.cjs b/deps/npm/tap-snapshots/test/lib/fund.js.test.cjs index 7ad86ebeea7..c078beb7d98 100644 --- a/deps/npm/tap-snapshots/test/lib/fund.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/fund.js.test.cjs @@ -92,3 +92,23 @@ test-multiple-funding-sources@1.0.0 ` + +exports[`test/lib/fund.js TAP workspaces filter funding info by a specific workspace > should display only filtered workspace name and its deps 1`] = ` +workspaces-support@1.0.0 +\`-- https://example.com/a + | \`-- a@1.0.0 + \`-- http://example.com/c + \`-- c@1.0.0 + + +` + +exports[`test/lib/fund.js TAP workspaces filter funding info by a specific workspace > should display only filtered workspace path and its deps 1`] = ` +workspaces-support@1.0.0 +\`-- https://example.com/a + | \`-- a@1.0.0 + \`-- http://example.com/c + \`-- c@1.0.0 + + +` diff --git a/deps/npm/tap-snapshots/test/lib/publish.js.test.cjs b/deps/npm/tap-snapshots/test/lib/publish.js.test.cjs index 172ed5b29f4..0d652e289a8 100644 --- a/deps/npm/tap-snapshots/test/lib/publish.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/publish.js.test.cjs @@ -15,6 +15,109 @@ npm publish [<folder>] Options: [--tag <tag>] [--access <restricted|public>] [--dry-run] +[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] +[-ws|--workspaces] Run "npm help publish" for more info ` + +exports[`test/lib/publish.js TAP workspaces all workspaces > should output all publishes 1`] = ` +Array [ + "+ workspace-a@1.2.3-a", + "+ workspace-b@1.2.3-n", +] +` + +exports[`test/lib/publish.js TAP workspaces all workspaces > should publish all workspaces 1`] = ` +Array [ + Object { + "_id": "workspace-a@1.2.3-a", + "name": "workspace-a", + "readme": "ERROR: No README data found!", + "repository": Object { + "type": "git", + "url": "http://repo.workspace-a/", + }, + "version": "1.2.3-a", + }, + Object { + "_id": "workspace-b@1.2.3-n", + "bugs": Object { + "url": "https://github.com/npm/workspace-b/issues", + }, + "homepage": "https://github.com/npm/workspace-b#readme", + "name": "workspace-b", + "readme": "ERROR: No README data found!", + "repository": Object { + "type": "git", + "url": "git+https://github.com/npm/workspace-b.git", + }, + "version": "1.2.3-n", + }, +] +` + +exports[`test/lib/publish.js TAP workspaces json > should output all publishes as json 1`] = ` +Array [ + String( + { + "workspace-a": { + "id": "workspace-a@1.2.3-a" + }, + "workspace-b": { + "id": "workspace-b@1.2.3-n" + } + } + ), +] +` + +exports[`test/lib/publish.js TAP workspaces json > should publish all workspaces 1`] = ` +Array [ + Object { + "_id": "workspace-a@1.2.3-a", + "name": "workspace-a", + "readme": "ERROR: No README data found!", + "repository": Object { + "type": "git", + "url": "http://repo.workspace-a/", + }, + "version": "1.2.3-a", + }, + Object { + "_id": "workspace-b@1.2.3-n", + "bugs": Object { + "url": "https://github.com/npm/workspace-b/issues", + }, + "homepage": "https://github.com/npm/workspace-b#readme", + "name": "workspace-b", + "readme": "ERROR: No README data found!", + "repository": Object { + "type": "git", + "url": "git+https://github.com/npm/workspace-b.git", + }, + "version": "1.2.3-n", + }, +] +` + +exports[`test/lib/publish.js TAP workspaces one workspace > should output one publish 1`] = ` +Array [ + "+ workspace-a@1.2.3-a", +] +` + +exports[`test/lib/publish.js TAP workspaces one workspace > should publish given workspace 1`] = ` +Array [ + Object { + "_id": "workspace-a@1.2.3-a", + "name": "workspace-a", + "readme": "ERROR: No README data found!", + "repository": Object { + "type": "git", + "url": "http://repo.workspace-a/", + }, + "version": "1.2.3-a", + }, +] +` diff --git a/deps/npm/tap-snapshots/test/lib/utils/npm-usage.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/npm-usage.js.test.cjs index c0cb3241d93..3b007a83c95 100644 --- a/deps/npm/tap-snapshots/test/lib/utils/npm-usage.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/utils/npm-usage.js.test.cjs @@ -422,6 +422,7 @@ All commands: Options: [--json] [--browser|--browser <browser>] [--unicode] + [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] [--which <fundingSourceNumber>] Run "npm help fund" for more info @@ -697,6 +698,8 @@ All commands: Options: [--tag <tag>] [--access <restricted|public>] [--dry-run] + [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] + [-ws|--workspaces] Run "npm help publish" for more info diff --git a/deps/npm/test/lib/fund.js b/deps/npm/test/lib/fund.js index 41754d51f35..65778fca50b 100644 --- a/deps/npm/test/lib/fund.js +++ b/deps/npm/test/lib/fund.js @@ -839,3 +839,89 @@ t.test('sub dep with fund info and a parent with no funding info', t => { t.end() }) }) + +t.test('workspaces', t => { + t.test('filter funding info by a specific workspace', async t => { + npm.localPrefix = npm.prefix = t.testdir({ + 'package.json': JSON.stringify({ + name: 'workspaces-support', + version: '1.0.0', + workspaces: ['packages/*'], + dependencies: { + d: '^1.0.0', + }, + }), + node_modules: { + a: t.fixture('symlink', '../packages/a'), + b: t.fixture('symlink', '../packages/b'), + c: { + 'package.json': JSON.stringify({ + name: 'c', + version: '1.0.0', + funding: [ + 'http://example.com/c', + 'http://example.com/c-other', + ], + }), + }, + d: { + 'package.json': JSON.stringify({ + name: 'd', + version: '1.0.0', + funding: 'http://example.com/d', + }), + }, + }, + packages: { + a: { + 'package.json': JSON.stringify({ + name: 'a', + version: '1.0.0', + funding: 'https://example.com/a', + dependencies: { + c: '^1.0.0', + }, + }), + }, + b: { + 'package.json': JSON.stringify({ + name: 'b', + version: '1.0.0', + funding: 'http://example.com/b', + dependencies: { + d: '^1.0.0', + }, + }), + }, + }, + }) + + await new Promise((res, rej) => { + fund.execWorkspaces([], ['a'], (err) => { + if (err) + rej(err) + + t.matchSnapshot(result, + 'should display only filtered workspace name and its deps') + + result = '' + res() + }) + }) + + await new Promise((res, rej) => { + fund.execWorkspaces([], ['./packages/a'], (err) => { + if (err) + rej(err) + + t.matchSnapshot(result, + 'should display only filtered workspace path and its deps') + + result = '' + res() + }) + }) + }) + + t.end() +}) diff --git a/deps/npm/test/lib/publish.js b/deps/npm/test/lib/publish.js index 57574b22a56..7aff7b08c19 100644 --- a/deps/npm/test/lib/publish.js +++ b/deps/npm/test/lib/publish.js @@ -9,15 +9,12 @@ const fs = require('fs') const log = require('npmlog') log.level = 'silent' -// mock config const {definitions} = require('../../lib/utils/config') const defaults = Object.entries(definitions).reduce((defaults, [key, def]) => { defaults[key] = def.default return defaults }, {}) -const config = defaults - t.afterEach(() => log.level = 'silent') t.test('should publish with libnpmpublish, passing through flatOptions and respecting publishConfig.registry', (t) => { @@ -54,7 +51,6 @@ t.test('should publish with libnpmpublish, passing through flatOptions and respe }, }) const npm = mockNpm({ - config, flatOptions: { customValue: true, }, @@ -102,7 +98,7 @@ t.test('re-loads publishConfig.registry if added during script process', (t) => }, }, }) - const npm = mockNpm({ config }) + const npm = mockNpm() npm.config.getCredentialsByURI = (uri) => { t.same(uri, registry, 'gets credentials for expected registry') return { token: 'some.registry.token' } @@ -144,13 +140,13 @@ t.test('if loglevel=info and json, should not output package contents', (t) => { }, }) const npm = mockNpm({ - config: { ...config, json: true }, + config: { json: true }, output: () => { t.pass('output is called') }, }) npm.config.getCredentialsByURI = (uri) => { - t.same(uri, defaults.registry, 'gets credentials for expected registry') + t.same(uri, npm.config.get('registry'), 'gets credentials for expected registry') return { token: 'some.registry.token' } } const publish = new Publish(npm) @@ -190,7 +186,7 @@ t.test('if loglevel=silent and dry-run, should not output package contents or pu }, }) const npm = mockNpm({ - config: { ...config, 'dry-run': true }, + config: { 'dry-run': true }, output: () => { throw new Error('should not output in dry run mode') }, @@ -236,7 +232,7 @@ t.test('if loglevel=info and dry-run, should not publish, should log package con }, }) const npm = mockNpm({ - config: { ...config, 'dry-run': true }, + config: { 'dry-run': true }, output: () => { t.pass('output fn is called') }, @@ -270,7 +266,7 @@ t.test('throws when invalid tag', (t) => { const Publish = t.mock('../../lib/publish.js') const npm = mockNpm({ - config: { ...config, tag: '0.0.13' }, + config: { tag: '0.0.13' }, }) const publish = new Publish(npm) @@ -313,9 +309,9 @@ t.test('can publish a tarball', t => { }, }, }) - const npm = mockNpm({ config }) + const npm = mockNpm() npm.config.getCredentialsByURI = (uri) => { - t.same(uri, defaults.registry, 'gets credentials for expected registry') + t.same(uri, npm.config.get('registry'), 'gets credentials for expected registry') return { token: 'some.registry.token' } } const publish = new Publish(npm) @@ -331,9 +327,9 @@ t.test('can publish a tarball', t => { t.test('should check auth for default registry', t => { t.plan(2) const Publish = t.mock('../../lib/publish.js') - const npm = mockNpm({ config }) + const npm = mockNpm() npm.config.getCredentialsByURI = (uri) => { - t.same(uri, defaults.registry, 'gets credentials for expected registry') + t.same(uri, npm.config.get('registry'), 'gets credentials for expected registry') return {} } const publish = new Publish(npm) @@ -352,7 +348,6 @@ t.test('should check auth for configured registry', t => { const registry = 'https://some.registry' const Publish = t.mock('../../lib/publish.js') const npm = mockNpm({ - config, flatOptions: { registry }, }) npm.config.getCredentialsByURI = (uri) => { @@ -382,7 +377,6 @@ t.test('should check auth for scope specific registry', t => { const Publish = t.mock('../../lib/publish.js') const npm = mockNpm({ - config, flatOptions: { '@npm:registry': registry }, }) npm.config.getCredentialsByURI = (uri) => { @@ -419,7 +413,6 @@ t.test('should use auth for scope specific registry', t => { }, }) const npm = mockNpm({ - config, flatOptions: { '@npm:registry': registry }, }) npm.config.getCredentialsByURI = (uri) => { @@ -457,9 +450,7 @@ t.test('read registry only from publishConfig', t => { }, }, }) - const npm = mockNpm({ - config, - }) + const npm = mockNpm() npm.config.getCredentialsByURI = (uri) => { t.same(uri, registry, 'gets credentials for expected registry') return { token: 'some.registry.token' } @@ -525,3 +516,104 @@ t.test('able to publish after if encountered multiple configs', t => { t.end() }) }) + +t.test('workspaces', (t) => { + const testDir = t.testdir({ + 'package.json': JSON.stringify({ + name: 'my-cool-pkg', + version: '1.0.0', + workspaces: ['workspace-a', 'workspace-b', 'workspace-c'], + }, null, 2), + 'workspace-a': { + 'package.json': JSON.stringify({ + name: 'workspace-a', + version: '1.2.3-a', + repository: 'http://repo.workspace-a/', + }), + }, + 'workspace-b': { + 'package.json': JSON.stringify({ + name: 'workspace-b', + version: '1.2.3-n', + repository: 'https://github.com/npm/workspace-b', + }), + }, + 'workspace-c': JSON.stringify({ + 'package.json': { + name: 'workspace-n', + version: '1.2.3-n', + }, + }), + }) + + const publishes = [] + const outputs = [] + t.beforeEach(() => { + npm.config.set('json', false) + outputs.length = 0 + publishes.length = 0 + }) + const Publish = t.mock('../../lib/publish.js', { + '../../lib/utils/tar.js': { + getContents: (manifest) => ({ + id: manifest._id, + }), + logTar: () => {}, + }, + libnpmpublish: { + publish: (manifest, tarballData, opts) => { + publishes.push(manifest) + }, + }, + }) + const npm = mockNpm({ + output: (o) => { + outputs.push(o) + }, + }) + npm.localPrefix = testDir + npm.config.getCredentialsByURI = (uri) => { + return { token: 'some.registry.token' } + } + const publish = new Publish(npm) + + t.test('all workspaces', (t) => { + log.level = 'info' + publish.execWorkspaces([], [], (err) => { + t.notOk(err) + t.matchSnapshot(publishes, 'should publish all workspaces') + t.matchSnapshot(outputs, 'should output all publishes') + t.end() + }) + }) + + t.test('one workspace', t => { + log.level = 'info' + publish.execWorkspaces([], ['workspace-a'], (err) => { + t.notOk(err) + t.matchSnapshot(publishes, 'should publish given workspace') + t.matchSnapshot(outputs, 'should output one publish') + t.end() + }) + }) + + t.test('invalid workspace', t => { + publish.execWorkspaces([], ['workspace-x'], (err) => { + t.match(err, /No workspaces found/) + t.match(err, /workspace-x/) + t.end() + }) + }) + + t.test('json', t => { + log.level = 'info' + npm.config.set('json', true) + publish.execWorkspaces([], [], (err) => { + t.notOk(err) + t.matchSnapshot(publishes, 'should publish all workspaces') + t.matchSnapshot(outputs, 'should output all publishes as json') + t.end() + }) + }) + t.end() +}) diff --git a/deps/npm/test/lib/workspaces/arborist-cmd.js b/deps/npm/test/lib/workspaces/arborist-cmd.js new file mode 100644 index 00000000000..cceeb68dbd4 --- /dev/null +++ b/deps/npm/test/lib/workspaces/arborist-cmd.js @@ -0,0 +1,109 @@ +const { resolve } = require('path') +const t = require('tap') +const ArboristCmd = require('../../../lib/workspaces/arborist-cmd.js') + +t.test('arborist-cmd', async t => { + const path = t.testdir({ + 'package.json': JSON.stringify({ + name: 'simple-workspaces-list', + version: '1.1.1', + workspaces: [ + 'a', + 'b', + 'group/*', + ], + }), + node_modules: { + abbrev: { + 'package.json': JSON.stringify({ name: 'abbrev', version: '1.1.1' }), + }, + a: t.fixture('symlink', '../a'), + b: t.fixture('symlink', '../b'), + }, + a: { + 'package.json': JSON.stringify({ name: 'a', version: '1.0.0' }), + }, + b: { + 'package.json': JSON.stringify({ name: 'b', version: '1.0.0' }), + }, + group: { + c: { + 'package.json': JSON.stringify({ + name: 'c', + version: '1.0.0', + dependencies: { + abbrev: '^1.1.1', + }, + }), + }, + d: { + 'package.json': JSON.stringify({ name: 'd', version: '1.0.0' }), + }, + }, + }) + + class TestCmd extends ArboristCmd {} + + const cmd = new TestCmd() + cmd.npm = { localPrefix: path } + + // check filtering for a single workspace name + cmd.exec = function (args, cb) { + t.same(this.workspaces, ['a'], 'should set array with single ws name') + t.same(args, ['foo'], 'should get received args') + cb() + } + await new Promise(res => { + cmd.execWorkspaces(['foo'], ['a'], res) + }) + + // check filtering single workspace by path + cmd.exec = function (args, cb) { + t.same(this.workspaces, ['a'], + 'should set array with single ws name from path') + cb() + } + await new Promise(res => { + cmd.execWorkspaces([], ['./a'], res) + }) + + // check filtering single workspace by full path + cmd.exec = function (args, cb) { + t.same(this.workspaces, ['a'], + 'should set array with single ws name from full path') + cb() + } + await new Promise(res => { + cmd.execWorkspaces([], [resolve(path, './a')], res) + }) + + // filtering multiple workspaces by name + cmd.exec = function (args, cb) { + t.same(this.workspaces, ['a', 'c'], + 'should set array with multiple listed ws names') + cb() + } + await new Promise(res => { + cmd.execWorkspaces([], ['a', 'c'], res) + }) + + // filtering multiple workspaces by path names + cmd.exec = function (args, cb) { + t.same(this.workspaces, ['a', 'c'], + 'should set array with multiple ws names from paths') + cb() + } + await new Promise(res => { + cmd.execWorkspaces([], ['./a', 'group/c'], res) + }) + + // filtering multiple workspaces by parent path name + cmd.exec = function (args, cb) { + t.same(this.workspaces, ['c', 'd'], + 'should set array with multiple ws names from a parent folder name') + cb() + } + await new Promise(res => { + cmd.execWorkspaces([], ['./group'], res) + }) +}) |