Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(pack): add --json support #3217

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/content/commands/npm-pack.md
Expand Up @@ -7,7 +7,7 @@ description: Create a tarball from a package
### Synopsis

```bash
npm pack [[<@scope>/]<pkg>...] [--dry-run]
npm pack [[<@scope>/]<pkg>...] [--dry-run] [--json]
```

### Configuration
Expand Down
8 changes: 7 additions & 1 deletion lib/pack.js
Expand Up @@ -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 */
Expand All @@ -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
Expand Down Expand Up @@ -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(/\//, '-'))
Expand Down
2 changes: 1 addition & 1 deletion tap-snapshots/test/lib/load-all-commands.js.test.cjs
Expand Up @@ -653,7 +653,7 @@ Usage:
npm pack [[<@scope>/]<pkg>...]

Options:
[--dry-run]
[--dry-run] [--json]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces]

Expand Down
2 changes: 1 addition & 1 deletion tap-snapshots/test/lib/utils/npm-usage.js.test.cjs
Expand Up @@ -740,7 +740,7 @@ All commands:
npm pack [[<@scope>/]<pkg>...]

Options:
[--dry-run]
[--dry-run] [--json]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces]

Expand Down
93 changes: 90 additions & 3 deletions test/lib/pack.js
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -158,6 +158,93 @@ t.test('should log pack contents', (t) => {
})
})

t.test('should log output as valid json', (t) => {
const testDir = t.testdir({
mrmlnc marked this conversation as resolved.
Show resolved Hide resolved
'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 () => ({
id: '@ruyadorno/redact@1.0.0',
name: '@ruyadorno/redact',
version: '1.0.0',
size: 2450,
unpackedSize: 4911,
shasum: '044c7574639b923076069d6e801e2d1866430f17',
// mocks exactly how ssri Integrity works:
integrity: {
sha512: [
{
source: 'sha512-JSdyskeR2qonBUaQ4vdlU/vQGSfgCxSq5O+vH+d2yVWRqzso4O3gUzd6QX/V7OWV//zU7kA5o63Zf433jUnOtQ==',
digest: 'JSdyskeR2qonBUaQ4vdlU/vQGSfgCxSq5O+vH+d2yVWRqzso4O3gUzd6QX/V7OWV//zU7kA5o63Zf433jUnOtQ==',
algorithm: 'sha512',
options: [],
},
],
toJSON () {
return 'sha512-JSdyskeR2qonBUaQ4vdlU/vQGSfgCxSq5O+vH+d2yVWRqzso4O3gUzd6QX/V7OWV//zU7kA5o63Zf433jUnOtQ=='
},
},
filename: '@ruyadorno/redact-1.0.0.tgz',
files: [
{ path: 'LICENSE', size: 1113, mode: 420 },
{ path: 'README.md', size: 2639, mode: 420 },
{ path: 'index.js', size: 719, mode: 493 },
{ path: 'package.json', size: 440, mode: 420 },
],
entryCount: 4,
bundled: [],
}),
},
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), [{
id: '@ruyadorno/redact@1.0.0',
name: '@ruyadorno/redact',
version: '1.0.0',
size: 2450,
unpackedSize: 4911,
shasum: '044c7574639b923076069d6e801e2d1866430f17',
integrity: 'sha512-JSdyskeR2qonBUaQ4vdlU/vQGSfgCxSq5O+vH+d2yVWRqzso4O3gUzd6QX/V7OWV//zU7kA5o63Zf433jUnOtQ==',
filename: '@ruyadorno/redact-1.0.0.tgz',
files: [
{ path: 'LICENSE' },
{ path: 'README.md' },
{ path: 'index.js' },
{ path: 'package.json' },
],
entryCount: 4,
}], 'pack details output as valid json')

t.end()
})
})

t.test('invalid packument', (t) => {
const mockPacote = {
manifest: () => {
Expand All @@ -176,7 +263,7 @@ t.test('invalid packument', (t) => {
const npm = mockNpm({
config: {
unicode: true,
json: true,
json: false,
'dry-run': true,
},
output,
Expand Down