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/test/lib/pack.js b/test/lib/pack.js index 6706042b4c82e..89585e21cdded 100644 --- a/test/lib/pack.js +++ b/test/lib/pack.js @@ -1,5 +1,6 @@ const t = require('tap') const mockNpm = require('../fixtures/mock-npm') +const pkgDirPack = require('libnpmpack') const pacote = require('pacote') const OUTPUT = [] @@ -73,7 +74,7 @@ t.test('should pack given directory', (t) => { const npm = mockNpm({ config: { unicode: true, - json: true, + json: false, 'dry-run': true, }, output, @@ -108,7 +109,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 +159,45 @@ 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', + }, null, 2), + }) + + const Pack = t.mock('../../lib/pack.js', { + libnpmpack: () => pkgDirPack(testDir), + 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.similar(JSON.parse(OUTPUT), [{ + filename: 'my-cool-pkg-1.0.0.tgz', + files: [{path: 'package.json'}], + entryCount: 1, + }], 'pack details output as valid json') + + t.end() + }) +}) + t.test('invalid packument', (t) => { const mockPacote = { manifest: () => { @@ -176,7 +216,7 @@ t.test('invalid packument', (t) => { const npm = mockNpm({ config: { unicode: true, - json: true, + json: false, 'dry-run': true, }, output,