diff --git a/docs/content/commands/npm-pack.md b/docs/content/commands/npm-pack.md index de3eeb731a9e3..4bf05fa60aceb 100644 --- a/docs/content/commands/npm-pack.md +++ b/docs/content/commands/npm-pack.md @@ -7,7 +7,7 @@ description: Create a tarball from a package ### Synopsis ```bash -npm pack [[<@scope>/]...] [--dry-run] +npm pack [[<@scope>/]...] [--dry-run] [--json] ``` ### Configuration diff --git a/lib/pack.js b/lib/pack.js index 5c0da6be7b6e0..52d4c3e7f900a 100644 --- a/lib/pack.js +++ b/lib/pack.js @@ -24,7 +24,7 @@ class Pack extends BaseCommand { /* istanbul ignore next - see test/lib/load-all-commands.js */ static get params () { - return ['dry-run', 'workspace', 'workspaces'] + return ['dry-run', 'json', 'workspace', 'workspaces'] } /* istanbul ignore next - see test/lib/load-all-commands.js */ @@ -46,6 +46,7 @@ class Pack extends BaseCommand { const unicode = this.npm.config.get('unicode') const dryRun = this.npm.config.get('dry-run') + const json = this.npm.config.get('json') // Get the manifests and filenames first so we can bail early on manifest // errors before making any tarballs @@ -74,6 +75,11 @@ class Pack extends BaseCommand { tarballs.push(pkgContents) } + if (json) { + this.npm.output(JSON.stringify(tarballs, null, 2)) + return + } + for (const tar of tarballs) { logTar(tar, { log, unicode }) this.npm.output(tar.filename.replace(/^@/, '').replace(/\//, '-')) diff --git a/tap-snapshots/test/lib/utils/npm-usage.js.test.cjs b/tap-snapshots/test/lib/utils/npm-usage.js.test.cjs index ad61dc7969ac4..71f2ae63570b4 100644 --- a/tap-snapshots/test/lib/utils/npm-usage.js.test.cjs +++ b/tap-snapshots/test/lib/utils/npm-usage.js.test.cjs @@ -637,7 +637,7 @@ All commands: npm pack [[<@scope>/]...] Options: - [--dry-run] + [--dry-run] [--json] [-w|--workspace [-w|--workspace ...]] [-ws|--workspaces] diff --git a/test/lib/pack.js b/test/lib/pack.js index 6706042b4c82e..50894caaa3ed0 100644 --- a/test/lib/pack.js +++ b/test/lib/pack.js @@ -73,7 +73,7 @@ t.test('should pack given directory', (t) => { const npm = mockNpm({ config: { unicode: true, - json: true, + json: false, 'dry-run': true, }, output, @@ -108,7 +108,7 @@ t.test('should pack given directory for scoped package', (t) => { const npm = mockNpm({ config: { unicode: true, - json: true, + json: false, 'dry-run': true, }, output, @@ -158,6 +158,55 @@ t.test('should log pack contents', (t) => { }) }) +t.test('should log output as valid json', (t) => { + const testDir = t.testdir({ + 'package.json': JSON.stringify({ + name: 'my-cool-pkg', + version: '1.0.0', + main: './index.js', + }, null, 2), + 'README.md': 'text', + 'index.js': 'void', + }) + + const Pack = t.mock('../../lib/pack.js', { + libnpmpack, + '../../lib/utils/tar.js': { + getContents: async () => ({ + filename: 'my-cool-pkg-1.0.0.tgz', + files: [{ path: 'README.md' }, { path: 'index.js' }, { path: 'package.json' }], + entryCount: 3, + }), + }, + npmlog: { + notice: () => {}, + showProgress: () => {}, + clearProgress: () => {}, + }, + }) + const npm = mockNpm({ + config: { + unicode: true, + json: true, + 'dry-run': true, + }, + output, + }) + const pack = new Pack(npm) + + pack.exec([testDir], err => { + t.error(err, { bail: true }) + + t.match(JSON.parse(OUTPUT), [{ + filename: 'my-cool-pkg-1.0.0.tgz', + files: [{ path: 'README.md' }, { path: 'index.js' }, { path: 'package.json' }], + entryCount: 3, + }], 'pack details output as valid json') + + t.end() + }) +}) + t.test('invalid packument', (t) => { const mockPacote = { manifest: () => { @@ -176,7 +225,7 @@ t.test('invalid packument', (t) => { const npm = mockNpm({ config: { unicode: true, - json: true, + json: false, 'dry-run': true, }, output,