feat(pack): add support for --dry-run (#10306)

close #10301
This commit is contained in:
Dasa Paddock
2025-12-12 05:00:54 -08:00
committed by GitHub
parent e0f0a7d85f
commit 144d76f15f
4 changed files with 48 additions and 15 deletions

View File

@@ -0,0 +1,6 @@
---
"@pnpm/plugin-commands-publishing": minor
"pnpm": minor
---
Added support for `--dry-run` to the `pack` command [#10301](https://github.com/pnpm/pnpm/issues/10301).

View File

@@ -38,6 +38,7 @@ export function cliOptionsTypes (): Record<string, unknown> {
out: String,
recursive: Boolean,
...pick([
'dry-run',
'pack-destination',
'pack-gzip-level',
'json',
@@ -57,6 +58,10 @@ export function help (): string {
title: 'Options',
list: [
{
description: 'Does everything `pnpm pack` would do except actually writing the tarball to disk.',
name: '--dry-run',
},
{
description: 'Directory in which `pnpm pack` will save tarballs. The default is the current working directory.',
name: '--pack-destination <dir>',
@@ -101,6 +106,7 @@ export type PackOptions = Pick<UniversalOptions, 'dir'> & Pick<Config, 'catalogs
argv: {
original: string[]
}
dryRun?: boolean
engineStrict?: boolean
packDestination?: string
out?: string
@@ -250,21 +256,23 @@ export async function api (opts: PackOptions): Promise<PackResult> {
const destDir = packDestination
? (path.isAbsolute(packDestination) ? packDestination : path.join(dir, packDestination ?? '.'))
: dir
await fs.promises.mkdir(destDir, { recursive: true })
await packPkg({
destFile: path.join(destDir, tarballName),
filesMap,
modulesDir: path.join(opts.dir, 'node_modules'),
packGzipLevel: opts.packGzipLevel,
manifest: publishManifest,
bins: [
...(await getBinsFromPackageManifest(publishManifest as DependencyManifest, dir)).map(({ path }) => path),
...(manifest.publishConfig?.executableFiles ?? [])
.map((executableFile) => path.join(dir, executableFile)),
],
})
if (!opts.ignoreScripts) {
await _runScriptsIfPresent(['postpack'], entryManifest)
if (!opts.dryRun) {
await fs.promises.mkdir(destDir, { recursive: true })
await packPkg({
destFile: path.join(destDir, tarballName),
filesMap,
modulesDir: path.join(opts.dir, 'node_modules'),
packGzipLevel: opts.packGzipLevel,
manifest: publishManifest,
bins: [
...(await getBinsFromPackageManifest(publishManifest as DependencyManifest, dir)).map(({ path }) => path),
...(manifest.publishConfig?.executableFiles ?? [])
.map((executableFile) => path.join(dir, executableFile)),
],
})
if (!opts.ignoreScripts) {
await _runScriptsIfPresent(['postpack'], entryManifest)
}
}
let packedTarballPath
if (opts.dir !== destDir) {

View File

@@ -272,6 +272,7 @@ Do you want to continue?`,
...opts,
dir,
packDestination,
dryRun: false,
})
await copyNpmrc({ dir, workspaceDir: opts.workspaceDir, packDestination })
const { status } = runNpm(opts.npmPath, ['publish', '--ignore-scripts', path.basename(tarballPath), ...args], {

View File

@@ -78,6 +78,24 @@ test('pack a package with scoped name', async () => {
expect(fs.existsSync('pnpm-test-scope-0.0.0.tgz')).toBeTruthy()
})
test('pack: with dry-run', async () => {
prepare({
name: 'test-publish-package.json',
version: '0.0.0',
})
await pack.handler({
...DEFAULT_OPTS,
argv: { original: [] },
dir: process.cwd(),
extraBinPaths: [],
dryRun: true,
})
expect(fs.existsSync('test-publish-package.json-0.0.0.tgz')).toBeFalsy()
expect(fs.existsSync('package.json')).toBeTruthy()
})
test('pack when there is bundledDependencies but without node-linker=hoisted', async () => {
prepare({
name: 'bundled-deps-without-node-linker-hoisted',