mirror of
https://github.com/pnpm/pnpm.git
synced 2026-04-10 18:18:56 -04:00
6
.changeset/pink-chefs-attack.md
Normal file
6
.changeset/pink-chefs-attack.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@pnpm/core": minor
|
||||
"pnpm": minor
|
||||
---
|
||||
|
||||
Added support for a new lifecycle script: `pnpm:devPreinstall`. This script works only in the root `package.json` file, only during local development, and runs before installation happens.
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
import PnpmError from '@pnpm/error'
|
||||
import getContext, { PnpmContext, ProjectOptions } from '@pnpm/get-context'
|
||||
import headless from '@pnpm/headless'
|
||||
import {
|
||||
import runLifecycleHook, {
|
||||
makeNodeRequireOption,
|
||||
runLifecycleHooksConcurrently,
|
||||
RunLifecycleHooksConcurrentlyOptions,
|
||||
@@ -82,6 +82,8 @@ const BROKEN_LOCKFILE_INTEGRITY_ERRORS = new Set([
|
||||
'ERR_PNPM_TARBALL_INTEGRITY',
|
||||
])
|
||||
|
||||
const DEV_PREINSTALL = 'pnpm:devPreinstall'
|
||||
|
||||
export type DependenciesMutation = (
|
||||
{
|
||||
buildIndex: number
|
||||
@@ -200,6 +202,28 @@ export async function mutateModules (
|
||||
return result
|
||||
|
||||
async function _install (): Promise<Array<{ rootDir: string, manifest: ProjectManifest }>> {
|
||||
const scriptsOpts: RunLifecycleHooksConcurrentlyOptions = {
|
||||
extraBinPaths: opts.extraBinPaths,
|
||||
rawConfig: opts.rawConfig,
|
||||
scriptShell: opts.scriptShell,
|
||||
shellEmulator: opts.shellEmulator,
|
||||
stdio: opts.ownLifecycleHooksStdio,
|
||||
storeController: opts.storeController,
|
||||
unsafePerm: opts.unsafePerm || false,
|
||||
}
|
||||
|
||||
if (!opts.ignoreScripts && !opts.ignorePackageManifest && rootProjectManifest?.scripts?.[DEV_PREINSTALL]) {
|
||||
await runLifecycleHook(
|
||||
DEV_PREINSTALL,
|
||||
rootProjectManifest,
|
||||
{
|
||||
...scriptsOpts,
|
||||
depPath: opts.lockfileDir,
|
||||
pkgRoot: opts.lockfileDir,
|
||||
rootModulesDir: ctx.rootModulesDir,
|
||||
}
|
||||
)
|
||||
}
|
||||
const packageExtensionsChecksum = isEmpty(packageExtensions ?? {}) ? undefined : createObjectChecksum(packageExtensions!)
|
||||
let needsFullResolution = !maybeOpts.ignorePackageManifest && (
|
||||
!equals(ctx.wantedLockfile.overrides ?? {}, overrides ?? {}) ||
|
||||
@@ -321,16 +345,6 @@ export async function mutateModules (
|
||||
const projectsToInstall = [] as ImporterToUpdate[]
|
||||
|
||||
const projectsToBeInstalled = ctx.projects.filter(({ mutation }) => mutation === 'install') as ProjectToBeInstalled[]
|
||||
const scriptsOpts: RunLifecycleHooksConcurrentlyOptions = {
|
||||
extraBinPaths: opts.extraBinPaths,
|
||||
rawConfig: opts.rawConfig,
|
||||
scriptShell: opts.scriptShell,
|
||||
shellEmulator: opts.shellEmulator,
|
||||
stdio: opts.ownLifecycleHooksStdio,
|
||||
storeController: opts.storeController,
|
||||
unsafePerm: opts.unsafePerm || false,
|
||||
}
|
||||
|
||||
let preferredSpecs: Record<string, string> | null = null
|
||||
|
||||
// TODO: make it concurrent
|
||||
|
||||
@@ -97,6 +97,7 @@ test('run install scripts in the current project', async () => {
|
||||
prepareEmpty()
|
||||
const manifest = await addDependenciesToPackage({
|
||||
scripts: {
|
||||
'pnpm:devPreinstall': 'node -e "require(\'fs\').writeFileSync(\'test.txt\', \'\', \'utf-8\')"',
|
||||
install: 'node -e "process.stdout.write(\'install\')" | json-append output.json',
|
||||
postinstall: 'node -e "process.stdout.write(\'postinstall\')" | json-append output.json',
|
||||
preinstall: 'node -e "process.stdout.write(\'preinstall\')" | json-append output.json',
|
||||
@@ -107,6 +108,7 @@ test('run install scripts in the current project', async () => {
|
||||
const output = await loadJsonFile<string[]>('output.json')
|
||||
|
||||
expect(output).toStrictEqual(['preinstall', 'install', 'postinstall'])
|
||||
expect(await exists('test.txt')).toBeTruthy()
|
||||
})
|
||||
|
||||
test('run install scripts in the current project when its name is different than its directory', async () => {
|
||||
|
||||
Reference in New Issue
Block a user