feat: add --allow-build=<pkg> to add command (#9086)

This commit is contained in:
Zoltan Kochan
2025-02-13 00:43:44 +01:00
committed by GitHub
parent 31d15ff757
commit 91d46eecd4
3 changed files with 43 additions and 0 deletions

View File

@@ -0,0 +1,14 @@
---
"@pnpm/plugin-commands-installation": minor
"pnpm": minor
---
The `pnpm add` command now supports a new flag, `--allow-build`, which allows building the specified dependencies. For instance, if you want to install a package called `bundle` that has `esbuild` as a dependency and want to allow `esbuild` to run postinstall scripts, you can run:
```
pnpm --allow-build=esbuild add bundle
```
This will run `esbuild`'s postinstall script and also add it to the `pnpm.onlyBuiltDependencies` field of `package.json`. So, `esbuild` will always be allowed to run its scripts in the future.
Related PR: [#9086](https://github.com/pnpm/pnpm/pull/9086).

View File

@@ -5,6 +5,7 @@ import { PnpmError } from '@pnpm/error'
import { prepareExecutionEnv } from '@pnpm/plugin-commands-env'
import pick from 'ramda/src/pick'
import renderHelp from 'render-help'
import { createProjectManifestWriter } from './createProjectManifestWriter'
import { type InstallCommandOptions } from './install'
import { installDeps } from './installDeps'
@@ -75,6 +76,7 @@ export function rcOptionsTypes (): Record<string, unknown> {
export function cliOptionsTypes (): Record<string, unknown> {
return {
...rcOptionsTypes(),
'allow-build': [String, Array],
recursive: Boolean,
save: Boolean,
workspace: Boolean,
@@ -142,6 +144,10 @@ For options that may be used with `-r`, see "pnpm help recursive"',
OPTIONS.virtualStoreDir,
OPTIONS.globalDir,
...UNIVERSAL_OPTIONS,
{
description: 'A list of package names that are allowed to run postinstall scripts during installation',
name: '--allow-build',
},
],
},
FILTERING,
@@ -162,6 +168,7 @@ For options that may be used with `-r`, see "pnpm help recursive"',
}
export type AddCommandOptions = InstallCommandOptions & {
allowBuild?: string[]
allowNew?: boolean
ignoreWorkspaceRootCheck?: boolean
save?: boolean
@@ -209,6 +216,16 @@ export async function handler (
devDependencies: opts.dev !== false,
optionalDependencies: opts.optional !== false,
}
if (opts.allowBuild?.length) {
opts.rootProjectManifest = opts.rootProjectManifest ?? {}
opts.rootProjectManifest.pnpm = opts.rootProjectManifest.pnpm ?? {}
opts.rootProjectManifest.pnpm.onlyBuiltDependencies = Array.from(new Set([
...(opts.rootProjectManifest.pnpm.onlyBuiltDependencies ?? []),
...opts.allowBuild,
])).sort((a, b) => a.localeCompare(b))
const writeProjectManifest = await createProjectManifestWriter(opts.rootProjectManifestDir)
await writeProjectManifest(opts.rootProjectManifest)
}
return installDeps({
...opts,
include,

View File

@@ -174,6 +174,18 @@ test('selectively allow scripts in some dependencies by onlyBuiltDependenciesFil
expect(fs.existsSync('node_modules/@pnpm.e2e/install-script-example/generated-by-install.js')).toBeTruthy()
})
test('selectively allow scripts in some dependencies by --allow-build flag', async () => {
prepare({})
execPnpmSync(['add', '--allow-build=@pnpm.e2e/install-script-example', '@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0', '@pnpm.e2e/install-script-example'])
expect(fs.existsSync('node_modules/@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-preinstall.js')).toBeFalsy()
expect(fs.existsSync('node_modules/@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-postinstall.js')).toBeFalsy()
expect(fs.existsSync('node_modules/@pnpm.e2e/install-script-example/generated-by-install.js')).toBeTruthy()
const manifest = loadJsonFile.sync<ProjectManifest>('package.json')
expect(manifest.pnpm?.onlyBuiltDependencies).toStrictEqual(['@pnpm.e2e/install-script-example'])
})
test('use node versions specified by pnpm.executionEnv.nodeVersion in workspace packages', async () => {
const projects = preparePackages([
{