mirror of
https://github.com/pnpm/pnpm.git
synced 2026-05-19 06:07:59 -04:00
feat: add --allow-build=<pkg> to add command (#9086)
This commit is contained in:
14
.changeset/shy-kangaroos-argue.md
Normal file
14
.changeset/shy-kangaroos-argue.md
Normal 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).
|
||||||
@@ -5,6 +5,7 @@ import { PnpmError } from '@pnpm/error'
|
|||||||
import { prepareExecutionEnv } from '@pnpm/plugin-commands-env'
|
import { prepareExecutionEnv } from '@pnpm/plugin-commands-env'
|
||||||
import pick from 'ramda/src/pick'
|
import pick from 'ramda/src/pick'
|
||||||
import renderHelp from 'render-help'
|
import renderHelp from 'render-help'
|
||||||
|
import { createProjectManifestWriter } from './createProjectManifestWriter'
|
||||||
import { type InstallCommandOptions } from './install'
|
import { type InstallCommandOptions } from './install'
|
||||||
import { installDeps } from './installDeps'
|
import { installDeps } from './installDeps'
|
||||||
|
|
||||||
@@ -75,6 +76,7 @@ export function rcOptionsTypes (): Record<string, unknown> {
|
|||||||
export function cliOptionsTypes (): Record<string, unknown> {
|
export function cliOptionsTypes (): Record<string, unknown> {
|
||||||
return {
|
return {
|
||||||
...rcOptionsTypes(),
|
...rcOptionsTypes(),
|
||||||
|
'allow-build': [String, Array],
|
||||||
recursive: Boolean,
|
recursive: Boolean,
|
||||||
save: Boolean,
|
save: Boolean,
|
||||||
workspace: Boolean,
|
workspace: Boolean,
|
||||||
@@ -142,6 +144,10 @@ For options that may be used with `-r`, see "pnpm help recursive"',
|
|||||||
OPTIONS.virtualStoreDir,
|
OPTIONS.virtualStoreDir,
|
||||||
OPTIONS.globalDir,
|
OPTIONS.globalDir,
|
||||||
...UNIVERSAL_OPTIONS,
|
...UNIVERSAL_OPTIONS,
|
||||||
|
{
|
||||||
|
description: 'A list of package names that are allowed to run postinstall scripts during installation',
|
||||||
|
name: '--allow-build',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
FILTERING,
|
FILTERING,
|
||||||
@@ -162,6 +168,7 @@ For options that may be used with `-r`, see "pnpm help recursive"',
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type AddCommandOptions = InstallCommandOptions & {
|
export type AddCommandOptions = InstallCommandOptions & {
|
||||||
|
allowBuild?: string[]
|
||||||
allowNew?: boolean
|
allowNew?: boolean
|
||||||
ignoreWorkspaceRootCheck?: boolean
|
ignoreWorkspaceRootCheck?: boolean
|
||||||
save?: boolean
|
save?: boolean
|
||||||
@@ -209,6 +216,16 @@ export async function handler (
|
|||||||
devDependencies: opts.dev !== false,
|
devDependencies: opts.dev !== false,
|
||||||
optionalDependencies: opts.optional !== 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({
|
return installDeps({
|
||||||
...opts,
|
...opts,
|
||||||
include,
|
include,
|
||||||
|
|||||||
@@ -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()
|
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 () => {
|
test('use node versions specified by pnpm.executionEnv.nodeVersion in workspace packages', async () => {
|
||||||
const projects = preparePackages([
|
const projects = preparePackages([
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user