From c984fb59c5af087b91acd927cbbacad7c6a46576 Mon Sep 17 00:00:00 2001 From: Gar Date: Tue, 15 Jun 2021 14:23:00 -0700 Subject: [PATCH] feat(pack): add pack-destination config This will allow users to specify a folder in which to save their tarballs. PR-URL: https://github.com/npm/cli/pull/3420 Credit: @wraithgar Close: #3420 Reviewed-by: @ruyadorno --- docs/content/commands/npm-pack.md | 7 +++ docs/content/using-npm/config.md | 7 +++ lib/pack.js | 12 ++++- lib/utils/config/definitions.js | 8 ++++ .../test/lib/load-all-commands.js.test.cjs | 2 +- .../lib/utils/config/definitions.js.test.cjs | 1 + .../lib/utils/config/describe-all.js.test.cjs | 7 +++ .../test/lib/utils/npm-usage.js.test.cjs | 2 +- test/lib/pack.js | 44 ++++++++++++++++--- 9 files changed, 81 insertions(+), 9 deletions(-) diff --git a/docs/content/commands/npm-pack.md b/docs/content/commands/npm-pack.md index 04a22a5d854b4..9507026278437 100644 --- a/docs/content/commands/npm-pack.md +++ b/docs/content/commands/npm-pack.md @@ -36,6 +36,13 @@ Whether or not to output JSON data, rather than the normal output. Not supported by all npm commands. +#### `pack-destination` + +* Default: "." +* Type: String + +Directory in which `npm pack` will save tarballs. + #### `workspace` * Default: diff --git a/docs/content/using-npm/config.md b/docs/content/using-npm/config.md index 95f89a5848d23..a33c66e145cd9 100644 --- a/docs/content/using-npm/config.md +++ b/docs/content/using-npm/config.md @@ -867,6 +867,13 @@ when publishing or changing package permissions with `npm access`. If not set, and a registry response fails with a challenge for a one-time password, npm will prompt on the command line for one. +#### `pack-destination` + +* Default: "." +* Type: String + +Directory in which `npm pack` will save tarballs. + #### `package` * Default: diff --git a/lib/pack.js b/lib/pack.js index f4364d29033c4..8fc89db1a0b2b 100644 --- a/lib/pack.js +++ b/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 path = require('path') const { getContents, logTar } = require('./utils/tar.js') @@ -23,7 +24,13 @@ class Pack extends BaseCommand { /* istanbul ignore next - see test/lib/load-all-commands.js */ static get params () { - return ['dry-run', 'json', 'workspace', 'workspaces'] + return [ + 'dry-run', + 'json', + 'pack-destination', + 'workspace', + 'workspaces', + ] } /* istanbul ignore next - see test/lib/load-all-commands.js */ @@ -67,9 +74,10 @@ class Pack extends BaseCommand { for (const { arg, filename, manifest } of manifests) { const tarballData = await libpack(arg, this.npm.flatOptions) const pkgContents = await getContents(manifest, tarballData) + const tarballFilename = path.resolve(this.npm.config.get('pack-destination'), filename) if (!dryRun) - await writeFile(filename, tarballData) + await writeFile(tarballFilename, tarballData) tarballs.push(pkgContents) } diff --git a/lib/utils/config/definitions.js b/lib/utils/config/definitions.js index 40120498aa2bf..d540b0fc67e82 100644 --- a/lib/utils/config/definitions.js +++ b/lib/utils/config/definitions.js @@ -1336,6 +1336,14 @@ define('package-lock-only', { flatten, }) +define('pack-destination', { + default: '.', + type: String, + description: ` + Directory in which \`npm pack\` will save tarballs. + `, +}) + define('parseable', { default: false, type: Boolean, diff --git a/tap-snapshots/test/lib/load-all-commands.js.test.cjs b/tap-snapshots/test/lib/load-all-commands.js.test.cjs index 70902ba10cf33..3575783a644b2 100644 --- a/tap-snapshots/test/lib/load-all-commands.js.test.cjs +++ b/tap-snapshots/test/lib/load-all-commands.js.test.cjs @@ -657,7 +657,7 @@ Usage: npm pack [[<@scope>/]...] Options: -[--dry-run] [--json] +[--dry-run] [--json] [--pack-destination ] [-w|--workspace [-w|--workspace ...]] [-ws|--workspaces] diff --git a/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs b/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs index 32443c57af35b..35942fea64683 100644 --- a/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs +++ b/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs @@ -98,6 +98,7 @@ Array [ "package", "package-lock", "package-lock-only", + "pack-destination", "parseable", "prefer-offline", "prefer-online", diff --git a/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs b/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs index 9e3ba4d1af050..daa071b642e94 100644 --- a/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs +++ b/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs @@ -746,6 +746,13 @@ when publishing or changing package permissions with \`npm access\`. If not set, and a registry response fails with a challenge for a one-time password, npm will prompt on the command line for one. +#### \`pack-destination\` + +* Default: "." +* Type: String + +Directory in which \`npm pack\` will save tarballs. + #### \`package\` * Default: 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 dc10b43739b15..3987f6a732da5 100644 --- a/tap-snapshots/test/lib/utils/npm-usage.js.test.cjs +++ b/tap-snapshots/test/lib/utils/npm-usage.js.test.cjs @@ -744,7 +744,7 @@ All commands: npm pack [[<@scope>/]...] Options: - [--dry-run] [--json] + [--dry-run] [--json] [--pack-destination ] [-w|--workspace [-w|--workspace ...]] [-ws|--workspaces] diff --git a/test/lib/pack.js b/test/lib/pack.js index ad5bbf3359182..523ba5d6b535d 100644 --- a/test/lib/pack.js +++ b/test/lib/pack.js @@ -1,6 +1,7 @@ const t = require('tap') const mockNpm = require('../fixtures/mock-npm') const pacote = require('pacote') +const path = require('path') const OUTPUT = [] const output = (...msg) => OUTPUT.push(msg) @@ -27,6 +28,7 @@ const mockPacote = { t.afterEach(() => OUTPUT.length = 0) t.test('should pack current directory with no arguments', (t) => { + let tarballFileName const Pack = t.mock('../../lib/pack.js', { libnpmpack, npmlog: { @@ -35,14 +37,46 @@ t.test('should pack current directory with no arguments', (t) => { clearProgress: () => {}, }, fs: { - writeFile: (file, data, cb) => cb(), + writeFile: (file, data, cb) => { + tarballFileName = file + cb() + }, + }, + }) + const npm = mockNpm({ + output, + }) + const pack = new Pack(npm) + + pack.exec([], err => { + t.error(err, { bail: true }) + + const filename = `npm-${require('../../package.json').version}.tgz` + t.strictSame(OUTPUT, [[filename]]) + t.strictSame(tarballFileName, path.resolve(filename)) + t.end() + }) +}) + +t.test('follows pack-destination config', (t) => { + let tarballFileName + const Pack = t.mock('../../lib/pack.js', { + libnpmpack, + npmlog: { + notice: () => {}, + showProgress: () => {}, + clearProgress: () => {}, + }, + fs: { + writeFile: (file, data, cb) => { + tarballFileName = file + cb() + }, }, }) const npm = mockNpm({ config: { - unicode: false, - json: false, - 'dry-run': false, + 'pack-destination': '/tmp/test', }, output, }) @@ -53,10 +87,10 @@ t.test('should pack current directory with no arguments', (t) => { const filename = `npm-${require('../../package.json').version}.tgz` t.strictSame(OUTPUT, [[filename]]) + t.strictSame(tarballFileName, path.resolve('/tmp/test', filename)) t.end() }) }) - t.test('should pack given directory', (t) => { const testDir = t.testdir({ 'package.json': JSON.stringify({