diff --git a/deps/npm/CHANGELOG.md b/deps/npm/CHANGELOG.md index 9e696a7c3e942c..8155d019159f5b 100644 --- a/deps/npm/CHANGELOG.md +++ b/deps/npm/CHANGELOG.md @@ -1,4 +1,23 @@ +## v7.9.0 (2021-04-08) + +### FEATURES + +* [`1f3e88eba`](https://github.com/npm/cli/commit/1f3e88ebaf4901d8f9f07b43404d824fef7e5ff5) + [#3032](https://github.com/npm/cli/issues/3032) + feat(dist-tag): add workspace support + ([@nlf](https://github.com/nlf)) +* [`6e31df4e7`](https://github.com/npm/cli/commit/6e31df4e7957337962fd3d93e495931e3592bb9e) + [#3033](https://github.com/npm/cli/issues/3033) + feat(pack): add workspace support + ([@wraithgar](https://github.com/wraithgar)) + +### DEPENDENCIES + +* [`ba4f7fea8`](https://github.com/npm/cli/commit/ba4f7fea8fca8e3509469a218f094fe69095888b) + `licensee@8.2.0` + ## v7.8.0 (2021-04-01) + ### FEATURES diff --git a/deps/npm/docs/content/commands/npm-dist-tag.md b/deps/npm/docs/content/commands/npm-dist-tag.md index 585da16ad2d2c4..158c3417e7cba3 100644 --- a/deps/npm/docs/content/commands/npm-dist-tag.md +++ b/deps/npm/docs/content/commands/npm-dist-tag.md @@ -88,6 +88,18 @@ semver as `>=1.4.0 <1.5.0`. See . The simplest way to avoid semver problems with tags is to use tags that do not begin with a number or the letter `v`. +### Configuration + +#### workspaces + +Only supported by `ls`. Enables listing dist-tags of all workspace +contexts defined in the current `package.json`. + +#### workspace + +Only supported by `ls`. Enables listing dist-tags of workspace contexts +limiting results to only those specified by this config item. + ### See Also * [npm publish](/commands/npm-publish) diff --git a/deps/npm/docs/content/commands/npm-pack.md b/deps/npm/docs/content/commands/npm-pack.md index cc6b669efb1ef6..de3eeb731a9e33 100644 --- a/deps/npm/docs/content/commands/npm-pack.md +++ b/deps/npm/docs/content/commands/npm-pack.md @@ -10,6 +10,25 @@ description: Create a tarball from a package npm pack [[<@scope>/]...] [--dry-run] ``` +### Configuration + +#### dry-run + +Do everything that pack usually does without actually packing anything. +That is, report on what would have gone into the tarball, but nothing +else. + +#### workspaces + +Enables workspaces context while creating tarballs. Tarballs for each +workspaces will be generated. + +#### workspace + +Enables workspaces context and limits results to only those specified by +this config item. Tarballs will only be generated for the packages +named in the workspaces given here. + ### Description For anything that's installable (that is, a package folder, tarball, @@ -23,10 +42,6 @@ overwritten the second time. If no arguments are supplied, then npm packs the current package folder. -The `--dry-run` argument will do everything that pack usually does without -actually packing anything. That is, it reports on what would have gone -into the tarball, but nothing else. - ### See Also * [npm-packlist package](http://npm.im/npm-packlist) diff --git a/deps/npm/docs/output/commands/npm-dist-tag.html b/deps/npm/docs/output/commands/npm-dist-tag.html index 41d39176fabd47..df397d0a120b93 100644 --- a/deps/npm/docs/output/commands/npm-dist-tag.html +++ b/deps/npm/docs/output/commands/npm-dist-tag.html @@ -141,7 +141,7 @@

npm-dist-tag

Table of contents

- +

Synopsis

@@ -208,6 +208,13 @@

Caveats

semver as >=1.4.0 <1.5.0. See https://github.com/npm/npm/issues/6082.

The simplest way to avoid semver problems with tags is to use tags that do not begin with a number or the letter v.

+

Configuration

+

workspaces

+

Only supported by ls. Enables listing dist-tags of all workspace +contexts defined in the current package.json.

+

workspace

+

Only supported by ls. Enables listing dist-tags of workspace contexts +limiting results to only those specified by this config item.

See Also

  • npm publish
  • diff --git a/deps/npm/docs/output/commands/npm-ls.html b/deps/npm/docs/output/commands/npm-ls.html index 63b71a203dffa9..25a2850561a253 100644 --- a/deps/npm/docs/output/commands/npm-ls.html +++ b/deps/npm/docs/output/commands/npm-ls.html @@ -159,7 +159,7 @@

    Description

    the results to only the paths to the packages named. Note that nested packages will also show the paths to the specified packages. For example, running npm ls promzard in npm’s source tree will show:

    -
    npm@7.8.0 /path/to/npm
    +
    npm@7.9.0 /path/to/npm
     └─┬ init-package-json@0.0.4
       └── promzard@0.1.5
     
    diff --git a/deps/npm/docs/output/commands/npm-pack.html b/deps/npm/docs/output/commands/npm-pack.html index 5c1d8f8df01d58..9b7ff1e8eb93d0 100644 --- a/deps/npm/docs/output/commands/npm-pack.html +++ b/deps/npm/docs/output/commands/npm-pack.html @@ -141,12 +141,24 @@

    npm-pack

    Table of contents

    - +

    Synopsis

    npm pack [[<@scope>/]<pkg>...] [--dry-run]
     
    +

    Configuration

    +

    dry-run

    +

    Do everything that pack usually does without actually packing anything. +That is, report on what would have gone into the tarball, but nothing +else.

    +

    workspaces

    +

    Enables workspaces context while creating tarballs. Tarballs for each +workspaces will be generated.

    +

    workspace

    +

    Enables workspaces context and limits results to only those specified by +this config item. Tarballs will only be generated for the packages +named in the workspaces given here.

    Description

    For anything that’s installable (that is, a package folder, tarball, tarball url, git url, name@tag, name@version, name, or scoped name), this @@ -156,9 +168,6 @@

    Description

    If the same package is specified multiple times, then the file will be overwritten the second time.

    If no arguments are supplied, then npm packs the current package folder.

    -

    The --dry-run argument will do everything that pack usually does without -actually packing anything. That is, it reports on what would have gone -into the tarball, but nothing else.

    See Also

    • npm-packlist package
    • diff --git a/deps/npm/docs/output/commands/npm.html b/deps/npm/docs/output/commands/npm.html index 77a88b62fabfc1..7290e4f8ef6138 100644 --- a/deps/npm/docs/output/commands/npm.html +++ b/deps/npm/docs/output/commands/npm.html @@ -148,7 +148,7 @@

      Table of contents

      npm <command> [args]
       

      Version

      -

      7.8.0

      +

      7.9.0

      Description

      npm is the package manager for the Node JavaScript platform. It puts modules in place so that node can find them, and manages dependency diff --git a/deps/npm/lib/dist-tag.js b/deps/npm/lib/dist-tag.js index 13ec37fd8cb1d4..64e8abc0137454 100644 --- a/deps/npm/lib/dist-tag.js +++ b/deps/npm/lib/dist-tag.js @@ -5,6 +5,7 @@ const semver = require('semver') const otplease = require('./utils/otplease.js') const readLocalPkgName = require('./utils/read-local-package.js') +const getWorkspaces = require('./workspaces/get-workspaces.js') const BaseCommand = require('./base-command.js') class DistTag extends BaseCommand { @@ -12,6 +13,11 @@ class DistTag extends BaseCommand { return 'Modify package distribution tags' } + /* istanbul ignore next - see test/lib/load-all-commands.js */ + static get params () { + return ['workspace', 'workspaces'] + } + /* istanbul ignore next - see test/lib/load-all-commands.js */ static get name () { return 'dist-tag' @@ -43,15 +49,14 @@ class DistTag extends BaseCommand { async distTag ([cmdName, pkg, tag]) { const opts = this.npm.flatOptions - const has = (items) => new Set(items).has(cmdName) - if (has(['add', 'a', 'set', 's'])) + if (['add', 'a', 'set', 's'].includes(cmdName)) return this.add(pkg, tag, opts) - if (has(['rm', 'r', 'del', 'd', 'remove'])) + if (['rm', 'r', 'del', 'd', 'remove'].includes(cmdName)) return this.remove(pkg, tag, opts) - if (has(['ls', 'l', 'sl', 'list'])) + if (['ls', 'l', 'sl', 'list'].includes(cmdName)) return this.list(pkg, opts) if (!pkg) { @@ -62,6 +67,33 @@ class DistTag extends BaseCommand { throw this.usage } + execWorkspaces (args, filters, cb) { + this.distTagWorkspaces(args, filters).then(() => cb()).catch(cb) + } + + async distTagWorkspaces ([cmdName, pkg, tag], filters) { + // cmdName is some form of list + // pkg is one of: + // - unset + // - . + // - .@version + if (['ls', 'l', 'sl', 'list'].includes(cmdName) && (!pkg || pkg === '.' || /^\.@/.test(pkg))) + return this.listWorkspaces(filters) + + // pkg is unset + // cmdName is one of: + // - unset + // - . + // - .@version + if (!pkg && (!cmdName || cmdName === '.' || /^\.@/.test(cmdName))) + return this.listWorkspaces(filters) + + // anything else is just a regular dist-tag command + // so we fallback to the non-workspaces implementation + log.warn('Ignoring workspaces for specified package') + return this.distTag([cmdName, pkg, tag]) + } + async add (spec, tag, opts) { spec = npa(spec || '') const version = spec.rawSpec @@ -145,6 +177,22 @@ class DistTag extends BaseCommand { } } + async listWorkspaces (filters) { + const workspaces = + await getWorkspaces(filters, { path: this.npm.localPrefix }) + + for (const [name] of workspaces) { + try { + this.npm.output(`${name}:`) + await this.list(npa(name), this.npm.flatOptions) + } catch (err) { + // set the exitCode directly, but ignore the error + // since it will have already been logged by this.list() + process.exitCode = 1 + } + } + } + async fetchTags (spec, opts) { const data = await regFetch.json( `/-/package/${spec.escapedName}/dist-tags`, diff --git a/deps/npm/lib/pack.js b/deps/npm/lib/pack.js index 92a2fbd7ac33ce..8e61efabb36e4d 100644 --- a/deps/npm/lib/pack.js +++ b/deps/npm/lib/pack.js @@ -3,6 +3,7 @@ const log = require('npmlog') const pacote = require('pacote') const libpack = require('libnpmpack') const npa = require('npm-package-arg') +const getWorkspaces = require('./workspaces/get-workspaces.js') const { getContents, logTar } = require('./utils/tar.js') @@ -23,7 +24,7 @@ class Pack extends BaseCommand { /* istanbul ignore next - see test/lib/load-all-commands.js */ static get params () { - return ['dry-run'] + return ['dry-run', 'workspace', 'workspaces'] } /* istanbul ignore next - see test/lib/load-all-commands.js */ @@ -35,6 +36,10 @@ class Pack extends BaseCommand { this.pack(args).then(() => cb()).catch(cb) } + execWorkspaces (args, filters, cb) { + this.packWorkspaces(args, filters).then(() => cb()).catch(cb) + } + async pack (args) { if (args.length === 0) args = ['.'] @@ -62,5 +67,21 @@ class Pack extends BaseCommand { this.npm.output(tar.filename.replace(/^@/, '').replace(/\//, '-')) } } + + async packWorkspaces (args, filters) { + // If they either ask for nothing, or explicitly include '.' in the args, + // we effectively translate that into each workspace requested + + const useWorkspaces = args.length === 0 || args.includes('.') + + if (!useWorkspaces) { + this.npm.log.warn('Ignoring workspaces for specified package(s)') + return this.pack(args) + } + + const workspaces = + await getWorkspaces(filters, { path: this.npm.localPrefix }) + return this.pack([...workspaces.values(), ...args.filter(a => a !== '.')]) + } } module.exports = Pack diff --git a/deps/npm/lib/view.js b/deps/npm/lib/view.js index fb280f0d58248d..91b32e2fd38fa3 100644 --- a/deps/npm/lib/view.js +++ b/deps/npm/lib/view.js @@ -151,7 +151,7 @@ class View extends BaseCommand { const local = /^\.@/.test(pkg) || pkg === '.' if (!local) { - this.npm.log.warn('Ignoring workspaces for remote package') + this.npm.log.warn('Ignoring workspaces for specified package(s)') return this.view([pkg, ...args]) } let wholePackument = false diff --git a/deps/npm/man/man1/npm-dist-tag.1 b/deps/npm/man/man1/npm-dist-tag.1 index 707f1ddbc23788..6be3351be3cf5b 100644 --- a/deps/npm/man/man1/npm-dist-tag.1 +++ b/deps/npm/man/man1/npm-dist-tag.1 @@ -90,6 +90,15 @@ semver as \fB>=1\.4\.0 <1\.5\.0\fP\|\. See https://github\.com/npm/npm/issues/6 .P The simplest way to avoid semver problems with tags is to use tags that do not begin with a number or the letter \fBv\fP\|\. +.SS Configuration +.SS workspaces +.P +Only supported by \fBls\fP\|\. Enables listing dist\-tags of all workspace +contexts defined in the current \fBpackage\.json\fP\|\. +.SS workspace +.P +Only supported by \fBls\fP\|\. Enables listing dist\-tags of workspace contexts +limiting results to only those specified by this config item\. .SS See Also .RS 0 .IP \(bu 2 diff --git a/deps/npm/man/man1/npm-ls.1 b/deps/npm/man/man1/npm-ls.1 index 8d5910f0dc2fd3..67cd6f1b1618b1 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\.8\.0 /path/to/npm +npm@7\.9\.0 /path/to/npm └─┬ init\-package\-json@0\.0\.4 └── promzard@0\.1\.5 .fi diff --git a/deps/npm/man/man1/npm-pack.1 b/deps/npm/man/man1/npm-pack.1 index ea2225d60651dc..adedbef0c1f56c 100644 --- a/deps/npm/man/man1/npm-pack.1 +++ b/deps/npm/man/man1/npm-pack.1 @@ -8,6 +8,21 @@ npm pack [[<@scope>/]\.\.\.] [\-\-dry\-run] .fi .RE +.SS Configuration +.SS dry\-run +.P +Do everything that pack usually does without actually packing anything\. +That is, report on what would have gone into the tarball, but nothing +else\. +.SS workspaces +.P +Enables workspaces context while creating tarballs\. Tarballs for each +workspaces will be generated\. +.SS workspace +.P +Enables workspaces context and limits results to only those specified by +this config item\. Tarballs will only be generated for the packages +named in the workspaces given here\. .SS Description .P For anything that's installable (that is, a package folder, tarball, @@ -20,10 +35,6 @@ If the same package is specified multiple times, then the file will be overwritten the second time\. .P If no arguments are supplied, then npm packs the current package folder\. -.P -The \fB\-\-dry\-run\fP argument will do everything that pack usually does without -actually packing anything\. That is, it reports on what would have gone -into the tarball, but nothing else\. .SS See Also .RS 0 .IP \(bu 2 diff --git a/deps/npm/man/man1/npm.1 b/deps/npm/man/man1/npm.1 index 2a373de484a5ad..94bca15adbf3f8 100644 --- a/deps/npm/man/man1/npm.1 +++ b/deps/npm/man/man1/npm.1 @@ -10,7 +10,7 @@ npm [args] .RE .SS Version .P -7\.8\.0 +7\.9\.0 .SS Description .P npm is the package manager for the Node JavaScript platform\. It puts diff --git a/deps/npm/package.json b/deps/npm/package.json index b6f2e0be7efcdc..965f029aaab1ab 100644 --- a/deps/npm/package.json +++ b/deps/npm/package.json @@ -1,5 +1,5 @@ { - "version": "7.8.0", + "version": "7.9.0", "name": "npm", "description": "a package manager for JavaScript", "keywords": [ diff --git a/deps/npm/tap-snapshots/test-lib-dist-tag.js-TAP.test.js b/deps/npm/tap-snapshots/test-lib-dist-tag.js-TAP.test.js index 06936795bcf035..ea25b568b06626 100644 --- a/deps/npm/tap-snapshots/test-lib-dist-tag.js-TAP.test.js +++ b/deps/npm/tap-snapshots/test-lib-dist-tag.js-TAP.test.js @@ -15,6 +15,9 @@ npm dist-tag add @ [] npm dist-tag rm npm dist-tag ls [] +Options: +[-w|--workspace [-w|--workspace ...]] [-ws|--workspaces] + alias: dist-tags Run "npm help dist-tag" for more info @@ -30,6 +33,9 @@ npm dist-tag add @ [] npm dist-tag rm npm dist-tag ls [] +Options: +[-w|--workspace [-w|--workspace ...]] [-ws|--workspaces] + alias: dist-tags Run "npm help dist-tag" for more info @@ -54,6 +60,9 @@ npm dist-tag add @ [] npm dist-tag rm npm dist-tag ls [] +Options: +[-w|--workspace [-w|--workspace ...]] [-ws|--workspaces] + alias: dist-tags Run "npm help dist-tag" for more info @@ -75,6 +84,9 @@ npm dist-tag add @ [] npm dist-tag rm npm dist-tag ls [] +Options: +[-w|--workspace [-w|--workspace ...]] [-ws|--workspaces] + alias: dist-tags Run "npm help dist-tag" for more info @@ -126,6 +138,9 @@ npm dist-tag add @ [] npm dist-tag rm npm dist-tag ls [] +Options: +[-w|--workspace [-w|--workspace ...]] [-ws|--workspaces] + alias: dist-tags Run "npm help dist-tag" for more info @@ -142,3 +157,100 @@ dist-tag add b to @scoped/another@0.6.0 dist-tag add b is already set to version 0.6.0 ` + +exports[`test/lib/dist-tag.js TAP workspaces no args > printed the expected output 1`] = ` +workspace-a: +latest-a: 1.0.0 +latest: 1.0.0 +workspace-b: +latest-b: 2.0.0 +latest: 2.0.0 +workspace-c: +latest-c: 3.0.0 +latest: 3.0.0 +` + +exports[`test/lib/dist-tag.js TAP workspaces no args, one failing workspace sets exitCode to 1 > printed the expected output 1`] = ` +workspace-a: +latest-a: 1.0.0 +latest: 1.0.0 +workspace-b: +latest-b: 2.0.0 +latest: 2.0.0 +workspace-c: +latest-c: 3.0.0 +latest: 3.0.0 +workspace-d: +` + +exports[`test/lib/dist-tag.js TAP workspaces no args, one workspace > printed the expected output 1`] = ` +workspace-a: +latest-a: 1.0.0 +latest: 1.0.0 +` + +exports[`test/lib/dist-tag.js TAP workspaces one arg -- . > printed the expected output 1`] = ` +workspace-a: +latest-a: 1.0.0 +latest: 1.0.0 +workspace-b: +latest-b: 2.0.0 +latest: 2.0.0 +workspace-c: +latest-c: 3.0.0 +latest: 3.0.0 +` + +exports[`test/lib/dist-tag.js TAP workspaces one arg -- .@1, ignores version spec > printed the expected output 1`] = ` +workspace-a: +latest-a: 1.0.0 +latest: 1.0.0 +workspace-b: +latest-b: 2.0.0 +latest: 2.0.0 +workspace-c: +latest-c: 3.0.0 +latest: 3.0.0 +` + +exports[`test/lib/dist-tag.js TAP workspaces one arg -- list > printed the expected output 1`] = ` +workspace-a: +latest-a: 1.0.0 +latest: 1.0.0 +workspace-b: +latest-b: 2.0.0 +latest: 2.0.0 +workspace-c: +latest-c: 3.0.0 +latest: 3.0.0 +` + +exports[`test/lib/dist-tag.js TAP workspaces two args -- list, . > printed the expected output 1`] = ` +workspace-a: +latest-a: 1.0.0 +latest: 1.0.0 +workspace-b: +latest-b: 2.0.0 +latest: 2.0.0 +workspace-c: +latest-c: 3.0.0 +latest: 3.0.0 +` + +exports[`test/lib/dist-tag.js TAP workspaces two args -- list, .@1, ignores version spec > printed the expected output 1`] = ` +workspace-a: +latest-a: 1.0.0 +latest: 1.0.0 +workspace-b: +latest-b: 2.0.0 +latest: 2.0.0 +workspace-c: +latest-c: 3.0.0 +latest: 3.0.0 +` + +exports[`test/lib/dist-tag.js TAP workspaces two args -- list, @scoped/pkg, logs a warning and ignores workspaces > printed the expected output 1`] = ` +a: 0.0.1 +b: 0.5.0 +latest: 1.0.0 +` diff --git a/deps/npm/tap-snapshots/test-lib-utils-npm-usage.js-TAP.test.js b/deps/npm/tap-snapshots/test-lib-utils-npm-usage.js-TAP.test.js index f9e1d78e58f405..2f5a479dbc4700 100644 --- a/deps/npm/tap-snapshots/test-lib-utils-npm-usage.js-TAP.test.js +++ b/deps/npm/tap-snapshots/test-lib-utils-npm-usage.js-TAP.test.js @@ -323,6 +323,9 @@ All commands: npm dist-tag rm npm dist-tag ls [] + Options: + [-w|--workspace [-w|--workspace ...]] [-ws|--workspaces] + alias: dist-tags Run "npm help dist-tag" for more info @@ -622,7 +625,7 @@ All commands: npm pack [[<@scope>/]...] Options: - [--dry-run] + [--dry-run] [-w|--workspace [-w|--workspace ...]] [-ws|--workspaces] Run "npm help pack" for more info diff --git a/deps/npm/tap-snapshots/test-lib-view.js-TAP.test.js b/deps/npm/tap-snapshots/test-lib-view.js-TAP.test.js index 02810e31a5087d..1cdf356356af98 100644 --- a/deps/npm/tap-snapshots/test-lib-view.js-TAP.test.js +++ b/deps/npm/tap-snapshots/test-lib-view.js-TAP.test.js @@ -450,7 +450,7 @@ dist-tags: ` exports[`test/lib/view.js TAP workspaces remote package name > must match snapshot 1`] = ` -Ignoring workspaces for remote package +Ignoring workspaces for specified package(s) ` exports[`test/lib/view.js TAP workspaces remote package name > must match snapshot 2`] = ` diff --git a/deps/npm/test/fixtures/mock-npm.js b/deps/npm/test/fixtures/mock-npm.js index c47758111fd40a..01f482bde291b9 100644 --- a/deps/npm/test/fixtures/mock-npm.js +++ b/deps/npm/test/fixtures/mock-npm.js @@ -2,10 +2,24 @@ // npm.config You still need a separate flatOptions but this is the first step // to eventually just using npm itself +const mockLog = { + clearProgress: () => {}, + disableProgress: () => {}, + enableProgress: () => {}, + http: () => {}, + info: () => {}, + levels: [], + notice: () => {}, + pause: () => {}, + silly: () => {}, + verbose: () => {}, + warn: () => {}, +} const mockNpm = (base = {}) => { const config = base.config || {} const flatOptions = base.flatOptions || {} return { + log: mockLog, ...base, flatOptions, config: { diff --git a/deps/npm/test/lib/dist-tag.js b/deps/npm/test/lib/dist-tag.js index 9415dacbe47564..5e54c8f991cfdb 100644 --- a/deps/npm/test/lib/dist-tag.js +++ b/deps/npm/test/lib/dist-tag.js @@ -1,10 +1,16 @@ const requireInject = require('require-inject') const mockNpm = require('../fixtures/mock-npm') -const { test } = require('tap') +const { afterEach, test } = require('tap') let result = '' let log = '' +afterEach((cb) => { + result = '' + log = '' + cb() +}) + const routeMap = { '/-/package/@scoped%2fpkg/dist-tags': { latest: '1.0.0', @@ -22,6 +28,18 @@ const routeMap = { b: '0.6.0', c: '7.7.7', }, + '/-/package/workspace-a/dist-tags': { + latest: '1.0.0', + 'latest-a': '1.0.0', + }, + '/-/package/workspace-b/dist-tags': { + latest: '2.0.0', + 'latest-b': '2.0.0', + }, + '/-/package/workspace-c/dist-tags': { + latest: '3.0.0', + 'latest-c': '3.0.0', + }, } let npmRegistryFetchMock = (url, opts) => { @@ -57,7 +75,7 @@ const npm = mockNpm({ global: false, }, output: msg => { - result = msg + result = result ? [result, msg].join('\n') : msg }, }) const distTag = new DistTag(npm) @@ -74,8 +92,6 @@ test('ls in current package', (t) => { result, 'should list available tags for current package' ) - result = '' - log = '' t.end() }) }) @@ -92,8 +108,6 @@ test('no args in current package', (t) => { result, 'should default to listing available tags for current package' ) - result = '' - log = '' t.end() }) }) @@ -102,8 +116,6 @@ test('borked cmd usage', (t) => { npm.prefix = t.testdir({}) distTag.exec(['borked', '@scoped/pkg'], (err) => { t.matchSnapshot(err, 'should show usage error') - result = '' - log = '' t.end() }) }) @@ -116,8 +128,6 @@ test('ls on named package', (t) => { result, 'should list tags for the specified package' ) - result = '' - log = '' t.end() }) }) @@ -133,8 +143,6 @@ test('ls on missing package', (t) => { err, 'should throw error message' ) - result = '' - log = '' t.end() }) }) @@ -150,8 +158,6 @@ test('ls on missing name in current package', (t) => { err, 'should throw usage error message' ) - result = '' - log = '' t.end() }) }) @@ -164,14 +170,154 @@ test('only named package arg', (t) => { result, 'should default to listing tags for the specified package' ) - result = '' - log = '' t.end() }) }) +test('workspaces', (t) => { + npm.localPrefix = t.testdir({ + 'package.json': JSON.stringify({ + name: 'root', + version: '1.0.0', + workspaces: ['workspace-a', 'workspace-b', 'workspace-c'], + }), + 'workspace-a': { + 'package.json': JSON.stringify({ + name: 'workspace-a', + version: '1.0.0', + }), + }, + 'workspace-b': { + 'package.json': JSON.stringify({ + name: 'workspace-b', + version: '1.0.0', + }), + }, + 'workspace-c': { + 'package.json': JSON.stringify({ + name: 'workspace-c', + version: '1.0.0', + }), + }, + }) + + t.test('no args', t => { + distTag.execWorkspaces([], [], (err) => { + t.ifError(err) + t.matchSnapshot(result, 'printed the expected output') + t.end() + }) + }) + + t.test('no args, one workspace', t => { + distTag.execWorkspaces([], ['workspace-a'], (err) => { + t.ifError(err) + t.matchSnapshot(result, 'printed the expected output') + t.end() + }) + }) + + t.test('one arg -- .', t => { + distTag.execWorkspaces(['.'], [], (err) => { + t.ifError(err) + t.matchSnapshot(result, 'printed the expected output') + t.end() + }) + }) + + t.test('one arg -- .@1, ignores version spec', t => { + distTag.execWorkspaces(['.@'], [], (err) => { + t.ifError(err) + t.matchSnapshot(result, 'printed the expected output') + t.end() + }) + }) + + t.test('one arg -- list', t => { + distTag.execWorkspaces(['list'], [], (err) => { + t.ifError(err) + t.matchSnapshot(result, 'printed the expected output') + t.end() + }) + }) + + t.test('two args -- list, .', t => { + distTag.execWorkspaces(['list', '.'], [], (err) => { + t.ifError(err) + t.matchSnapshot(result, 'printed the expected output') + t.end() + }) + }) + + t.test('two args -- list, .@1, ignores version spec', t => { + distTag.execWorkspaces(['list', '.@'], [], (err) => { + t.ifError(err) + t.matchSnapshot(result, 'printed the expected output') + t.end() + }) + }) + + t.test('two args -- list, @scoped/pkg, logs a warning and ignores workspaces', t => { + distTag.execWorkspaces(['list', '@scoped/pkg'], [], (err) => { + t.ifError(err) + t.match(log, 'Ignoring workspaces for specified package', 'logs a warning') + t.matchSnapshot(result, 'printed the expected output') + t.end() + }) + }) + + t.test('no args, one failing workspace sets exitCode to 1', t => { + npm.localPrefix = t.testdir({ + 'package.json': JSON.stringify({ + name: 'root', + version: '1.0.0', + workspaces: ['workspace-a', 'workspace-b', 'workspace-c', 'workspace-d'], + }), + 'workspace-a': { + 'package.json': JSON.stringify({ + name: 'workspace-a', + version: '1.0.0', + }), + }, + 'workspace-b': { + 'package.json': JSON.stringify({ + name: 'workspace-b', + version: '1.0.0', + }), + }, + 'workspace-c': { + 'package.json': JSON.stringify({ + name: 'workspace-c', + version: '1.0.0', + }), + }, + 'workspace-d': { + 'package.json': JSON.stringify({ + name: 'workspace-d', + version: '1.0.0', + }), + }, + }) + + distTag.execWorkspaces([], [], (err) => { + t.ifError(err) + t.equal(process.exitCode, 1, 'set the error status') + process.exitCode = 0 + t.match(log, 'dist-tag ls Couldn\'t get dist-tag data for workspace-d@latest', 'logs the error') + t.matchSnapshot(result, 'printed the expected output') + t.end() + }) + }) + + t.end() +}) + test('add new tag', (t) => { const _nrf = npmRegistryFetchMock + t.teardown(() => { + npmRegistryFetchMock = _nrf + }) + npmRegistryFetchMock = async (url, opts) => { t.equal(opts.method, 'PUT', 'should trigger request to add new tag') t.equal(opts.body, '7.7.7', 'should point to expected version') @@ -183,9 +329,6 @@ test('add new tag', (t) => { result, 'should return success msg' ) - result = '' - log = '' - npmRegistryFetchMock = _nrf t.end() }) }) @@ -202,8 +345,6 @@ test('add using valid semver range as name', (t) => { log, 'should return success msg' ) - result = '' - log = '' t.end() }) }) @@ -212,8 +353,6 @@ test('add missing args', (t) => { npm.prefix = t.testdir({}) distTag.exec(['add', '@scoped/another@7.7.7'], (err) => { t.matchSnapshot(err, 'should exit usage error message') - result = '' - log = '' t.end() }) }) @@ -222,8 +361,6 @@ test('add missing pkg name', (t) => { npm.prefix = t.testdir({}) distTag.exec(['add', null], (err) => { t.matchSnapshot(err, 'should exit usage error message') - result = '' - log = '' t.end() }) }) @@ -236,13 +373,16 @@ test('set existing version', (t) => { log, 'should log warn msg' ) - log = '' t.end() }) }) test('remove existing tag', (t) => { const _nrf = npmRegistryFetchMock + t.teardown(() => { + npmRegistryFetchMock = _nrf + }) + npmRegistryFetchMock = async (url, opts) => { t.equal(opts.method, 'DELETE', 'should trigger request to remove tag') } @@ -251,9 +391,6 @@ test('remove existing tag', (t) => { t.ifError(err, 'npm dist-tags rm') t.matchSnapshot(log, 'should log remove info') t.matchSnapshot(result, 'should return success msg') - result = '' - log = '' - npmRegistryFetchMock = _nrf t.end() }) }) @@ -267,8 +404,6 @@ test('remove non-existing tag', (t) => { 'should exit with error' ) t.matchSnapshot(log, 'should log error msg') - result = '' - log = '' t.end() }) }) @@ -277,8 +412,6 @@ test('remove missing pkg name', (t) => { npm.prefix = t.testdir({}) distTag.exec(['rm', null], (err) => { t.matchSnapshot(err, 'should exit usage error message') - result = '' - log = '' t.end() }) }) diff --git a/deps/npm/test/lib/pack.js b/deps/npm/test/lib/pack.js index a5163acfdc49b1..4bcfe8ae3fd9c5 100644 --- a/deps/npm/test/lib/pack.js +++ b/deps/npm/test/lib/pack.js @@ -1,6 +1,7 @@ const t = require('tap') const requireInject = require('require-inject') const mockNpm = require('../fixtures/mock-npm') +const pacote = require('pacote') const OUTPUT = [] const output = (...msg) => OUTPUT.push(msg) @@ -11,6 +12,16 @@ const libnpmpack = async (spec, opts) => { return '' } +const mockPacote = { + manifest: (spec) => { + if (spec.type === 'directory') + return pacote.manifest(spec) + return { + name: spec.name || 'test-package', + version: spec.version || '1.0.0-test', + } + }, +} t.afterEach(cb => { OUTPUT.length = 0 @@ -152,3 +163,95 @@ t.test('should log pack contents', (t) => { t.end() }) }) + +t.test('workspaces', (t) => { + const testDir = t.testdir({ + 'package.json': JSON.stringify({ + name: 'workspaces-test', + version: '1.0.0', + workspaces: ['workspace-a', 'workspace-b'], + }, null, 2), + 'workspace-a': { + 'package.json': JSON.stringify({ + name: 'workspace-a', + version: '1.0.0', + }), + }, + 'workspace-b': { + 'package.json': JSON.stringify({ + name: 'workspace-b', + version: '1.0.0', + }), + }, + }) + const Pack = requireInject('../../lib/pack.js', { + libnpmpack, + pacote: mockPacote, + npmlog: { + notice: () => {}, + showProgress: () => {}, + clearProgress: () => {}, + }, + }) + const npm = mockNpm({ + localPrefix: testDir, + config: { + unicode: false, + json: false, + 'dry-run': false, + }, + output, + }) + const pack = new Pack(npm) + + t.test('all workspaces', (t) => { + pack.execWorkspaces([], [], er => { + if (er) + throw er + + t.strictSame(OUTPUT, [ + ['workspace-a-1.0.0.tgz'], + ['workspace-b-1.0.0.tgz'], + ]) + t.end() + }) + }) + + t.test('all workspaces, `.` first arg', (t) => { + pack.execWorkspaces(['.'], [], er => { + if (er) + throw er + + t.strictSame(OUTPUT, [ + ['workspace-a-1.0.0.tgz'], + ['workspace-b-1.0.0.tgz'], + ]) + t.end() + }) + }) + + t.test('one workspace', (t) => { + pack.execWorkspaces([], ['workspace-a'], er => { + if (er) + throw er + + t.strictSame(OUTPUT, [ + ['workspace-a-1.0.0.tgz'], + ]) + t.end() + }) + }) + + t.test('specific package', (t) => { + pack.execWorkspaces(['abbrev'], [], er => { + if (er) + throw er + + t.strictSame(OUTPUT, [ + ['abbrev-1.0.0-test.tgz'], + ]) + t.end() + }) + }) + t.end() +})