mirror of
https://github.com/pnpm/pnpm.git
synced 2026-05-19 14:20:36 -04:00
feat!: deprecate old settings that were replaced by allowBuilds (#10382)
This commit is contained in:
5
.changeset/deploy-preserve-allow-builds.md
Normal file
5
.changeset/deploy-preserve-allow-builds.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@pnpm/plugin-commands-deploy": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Preserve `allowBuilds` settings when deploying a project. The `allowBuilds` configuration is now written to `pnpm-workspace.yaml` in the deploy directory.
|
||||||
6
.changeset/global-install-allow-builds.md
Normal file
6
.changeset/global-install-allow-builds.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
"@pnpm/config": minor
|
||||||
|
"pnpm": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Support reading `allowBuilds` from `pnpm-workspace.yaml` in the global package directory for global installs.
|
||||||
30
.changeset/remove-deprecated-build-settings.md
Normal file
30
.changeset/remove-deprecated-build-settings.md
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
"pnpm": major
|
||||||
|
---
|
||||||
|
|
||||||
|
Remove deprecated build dependency settings: `onlyBuiltDependencies`, `onlyBuiltDependenciesFile`, `neverBuiltDependencies`, and `ignoredBuiltDependencies`.
|
||||||
|
|
||||||
|
Use the `allowBuilds` setting instead. It is a map where keys are package name patterns and values are booleans:
|
||||||
|
- `true` means the package is allowed to run build scripts
|
||||||
|
- `false` means the package is explicitly denied from running build scripts
|
||||||
|
|
||||||
|
Same as before, by default, none of the packages in the dependencies are allowed to run scripts. If a package has postinstall scripts and it isn't declared in `allowBuilds`, an error is printed.
|
||||||
|
|
||||||
|
Before:
|
||||||
|
```yaml
|
||||||
|
onlyBuiltDependencies:
|
||||||
|
- electron
|
||||||
|
onlyBuiltDependenciesFile: 'allowed-builds.json'
|
||||||
|
neverBuiltDependencies:
|
||||||
|
- core-js
|
||||||
|
ignoredBuiltDependencies:
|
||||||
|
- esbuild
|
||||||
|
```
|
||||||
|
|
||||||
|
After:
|
||||||
|
```yaml
|
||||||
|
allowBuilds:
|
||||||
|
electron: true
|
||||||
|
core-js: false
|
||||||
|
esbuild: false
|
||||||
|
```
|
||||||
13
.changeset/remove-deprecated-build-settings0.md
Normal file
13
.changeset/remove-deprecated-build-settings0.md
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
"@pnpm/types": major
|
||||||
|
"@pnpm/config": major
|
||||||
|
"@pnpm/core": major
|
||||||
|
"@pnpm/headless": major
|
||||||
|
"@pnpm/builder.policy": major
|
||||||
|
"@pnpm/exec.build-commands": major
|
||||||
|
"@pnpm/plugin-commands-installation": major
|
||||||
|
"@pnpm/plugin-commands-rebuild": major
|
||||||
|
"@pnpm/workspace.manifest-writer": major
|
||||||
|
---
|
||||||
|
|
||||||
|
Remove deprecated build dependency settings: `onlyBuiltDependencies`, `onlyBuiltDependenciesFile`, `neverBuiltDependencies`, and `ignoredBuiltDependencies`.
|
||||||
@@ -1,27 +1,16 @@
|
|||||||
import { type AllowBuild } from '@pnpm/types'
|
import { type AllowBuild } from '@pnpm/types'
|
||||||
import { expandPackageVersionSpecs } from '@pnpm/config.version-policy'
|
import { expandPackageVersionSpecs } from '@pnpm/config.version-policy'
|
||||||
import fs from 'fs'
|
|
||||||
|
|
||||||
export function createAllowBuildFunction (
|
export function createAllowBuildFunction (
|
||||||
opts: {
|
opts: {
|
||||||
dangerouslyAllowAllBuilds?: boolean
|
dangerouslyAllowAllBuilds?: boolean
|
||||||
neverBuiltDependencies?: string[]
|
|
||||||
onlyBuiltDependencies?: string[]
|
onlyBuiltDependencies?: string[]
|
||||||
onlyBuiltDependenciesFile?: string
|
|
||||||
}
|
}
|
||||||
): undefined | AllowBuild {
|
): undefined | AllowBuild {
|
||||||
if (opts.dangerouslyAllowAllBuilds) return () => true
|
if (opts.dangerouslyAllowAllBuilds) return () => true
|
||||||
if (opts.onlyBuiltDependenciesFile != null || opts.onlyBuiltDependencies != null) {
|
if (opts.onlyBuiltDependencies != null) {
|
||||||
const onlyBuiltDeps = opts.onlyBuiltDependencies ?? []
|
const onlyBuiltDependencies = expandPackageVersionSpecs(opts.onlyBuiltDependencies)
|
||||||
if (opts.onlyBuiltDependenciesFile) {
|
|
||||||
onlyBuiltDeps.push(...JSON.parse(fs.readFileSync(opts.onlyBuiltDependenciesFile, 'utf8')))
|
|
||||||
}
|
|
||||||
const onlyBuiltDependencies = expandPackageVersionSpecs(onlyBuiltDeps)
|
|
||||||
return (pkgName, version) => onlyBuiltDependencies.has(pkgName) || onlyBuiltDependencies.has(`${pkgName}@${version}`)
|
return (pkgName, version) => onlyBuiltDependencies.has(pkgName) || onlyBuiltDependencies.has(`${pkgName}@${version}`)
|
||||||
}
|
}
|
||||||
if (opts.neverBuiltDependencies != null && opts.neverBuiltDependencies.length > 0) {
|
|
||||||
const neverBuiltDependencies = new Set(opts.neverBuiltDependencies)
|
|
||||||
return (pkgName) => !neverBuiltDependencies.has(pkgName)
|
|
||||||
}
|
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,5 @@
|
|||||||
import path from 'path'
|
|
||||||
import { createAllowBuildFunction } from '@pnpm/builder.policy'
|
import { createAllowBuildFunction } from '@pnpm/builder.policy'
|
||||||
|
|
||||||
it('should neverBuiltDependencies', () => {
|
|
||||||
const allowBuild = createAllowBuildFunction({
|
|
||||||
neverBuiltDependencies: ['foo'],
|
|
||||||
})
|
|
||||||
expect(typeof allowBuild).toBe('function')
|
|
||||||
expect(allowBuild!('foo', '1.0.0')).toBeFalsy()
|
|
||||||
expect(allowBuild!('bar', '1.0.0')).toBeTruthy()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should onlyBuiltDependencies', () => {
|
it('should onlyBuiltDependencies', () => {
|
||||||
const allowBuild = createAllowBuildFunction({
|
const allowBuild = createAllowBuildFunction({
|
||||||
onlyBuiltDependencies: ['foo', 'qar@1.0.0 || 2.0.0'],
|
onlyBuiltDependencies: ['foo', 'qar@1.0.0 || 2.0.0'],
|
||||||
@@ -30,28 +20,6 @@ it('should not allow patterns in onlyBuiltDependencies', () => {
|
|||||||
expect(allowBuild!('is-odd', '1.0.0')).toBeFalsy()
|
expect(allowBuild!('is-odd', '1.0.0')).toBeFalsy()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should onlyBuiltDependencies set via a file', () => {
|
|
||||||
const allowBuild = createAllowBuildFunction({
|
|
||||||
onlyBuiltDependenciesFile: path.join(import.meta.dirname, 'onlyBuild.json'),
|
|
||||||
})
|
|
||||||
expect(typeof allowBuild).toBe('function')
|
|
||||||
expect(allowBuild!('zoo', '1.0.0')).toBeTruthy()
|
|
||||||
expect(allowBuild!('qar', '1.0.0')).toBeTruthy()
|
|
||||||
expect(allowBuild!('bar', '1.0.0')).toBeFalsy()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should onlyBuiltDependencies set via a file and config', () => {
|
|
||||||
const allowBuild = createAllowBuildFunction({
|
|
||||||
onlyBuiltDependencies: ['bar'],
|
|
||||||
onlyBuiltDependenciesFile: path.join(import.meta.dirname, 'onlyBuild.json'),
|
|
||||||
})
|
|
||||||
expect(typeof allowBuild).toBe('function')
|
|
||||||
expect(allowBuild!('zoo', '1.0.0')).toBeTruthy()
|
|
||||||
expect(allowBuild!('qar', '1.0.0')).toBeTruthy()
|
|
||||||
expect(allowBuild!('bar', '1.0.0')).toBeTruthy()
|
|
||||||
expect(allowBuild!('esbuild', '1.0.0')).toBeFalsy()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should return undefined if no policy is set', () => {
|
it('should return undefined if no policy is set', () => {
|
||||||
expect(createAllowBuildFunction({})).toBeUndefined()
|
expect(createAllowBuildFunction({})).toBeUndefined()
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ import { type Config } from './Config.js'
|
|||||||
export const DEPS_BUILD_CONFIG_KEYS = [
|
export const DEPS_BUILD_CONFIG_KEYS = [
|
||||||
'dangerouslyAllowAllBuilds',
|
'dangerouslyAllowAllBuilds',
|
||||||
'onlyBuiltDependencies',
|
'onlyBuiltDependencies',
|
||||||
'onlyBuiltDependenciesFile',
|
|
||||||
'neverBuiltDependencies',
|
|
||||||
'allowBuilds',
|
'allowBuilds',
|
||||||
] as const satisfies Array<keyof Config>
|
] as const satisfies Array<keyof Config>
|
||||||
|
|
||||||
|
|||||||
@@ -17,9 +17,7 @@ export type OptionsFromRootManifest = {
|
|||||||
allowUnusedPatches?: boolean
|
allowUnusedPatches?: boolean
|
||||||
ignorePatchFailures?: boolean
|
ignorePatchFailures?: boolean
|
||||||
overrides?: Record<string, string>
|
overrides?: Record<string, string>
|
||||||
neverBuiltDependencies?: string[]
|
|
||||||
onlyBuiltDependencies?: string[]
|
onlyBuiltDependencies?: string[]
|
||||||
onlyBuiltDependenciesFile?: string
|
|
||||||
ignoredBuiltDependencies?: string[]
|
ignoredBuiltDependencies?: string[]
|
||||||
packageExtensions?: Record<string, PackageExtension>
|
packageExtensions?: Record<string, PackageExtension>
|
||||||
ignoredOptionalDependencies?: string[]
|
ignoredOptionalDependencies?: string[]
|
||||||
@@ -37,15 +35,9 @@ export function getOptionsFromRootManifest (manifestDir: string, manifest: Proje
|
|||||||
'allowUnusedPatches',
|
'allowUnusedPatches',
|
||||||
'allowedDeprecatedVersions',
|
'allowedDeprecatedVersions',
|
||||||
'auditConfig',
|
'auditConfig',
|
||||||
'auditConfig',
|
|
||||||
'auditConfig',
|
|
||||||
'configDependencies',
|
'configDependencies',
|
||||||
'ignorePatchFailures',
|
'ignorePatchFailures',
|
||||||
'ignoredBuiltDependencies',
|
|
||||||
'ignoredOptionalDependencies',
|
'ignoredOptionalDependencies',
|
||||||
'neverBuiltDependencies',
|
|
||||||
'onlyBuiltDependencies',
|
|
||||||
'onlyBuiltDependenciesFile',
|
|
||||||
'overrides',
|
'overrides',
|
||||||
'packageExtensions',
|
'packageExtensions',
|
||||||
'patchedDependencies',
|
'patchedDependencies',
|
||||||
@@ -74,9 +66,6 @@ export function getOptionsFromPnpmSettings (manifestDir: string | undefined, pnp
|
|||||||
settings.overrides = mapValues(createVersionReferencesReplacer(manifest), settings.overrides)
|
settings.overrides = mapValues(createVersionReferencesReplacer(manifest), settings.overrides)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pnpmSettings.onlyBuiltDependenciesFile && manifestDir != null) {
|
|
||||||
settings.onlyBuiltDependenciesFile = path.join(manifestDir, pnpmSettings.onlyBuiltDependenciesFile)
|
|
||||||
}
|
|
||||||
if (pnpmSettings.patchedDependencies) {
|
if (pnpmSettings.patchedDependencies) {
|
||||||
settings.patchedDependencies = { ...pnpmSettings.patchedDependencies }
|
settings.patchedDependencies = { ...pnpmSettings.patchedDependencies }
|
||||||
for (const [dep, patchFile] of Object.entries(pnpmSettings.patchedDependencies)) {
|
for (const [dep, patchFile] of Object.entries(pnpmSettings.patchedDependencies)) {
|
||||||
@@ -93,6 +82,7 @@ export function getOptionsFromPnpmSettings (manifestDir: string | undefined, pnp
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pnpmSettings.allowBuilds) {
|
if (pnpmSettings.allowBuilds) {
|
||||||
|
settings.allowBuilds = pnpmSettings.allowBuilds
|
||||||
settings.onlyBuiltDependencies ??= []
|
settings.onlyBuiltDependencies ??= []
|
||||||
settings.ignoredBuiltDependencies ??= []
|
settings.ignoredBuiltDependencies ??= []
|
||||||
for (const [packagePattern, build] of Object.entries(pnpmSettings.allowBuilds)) {
|
for (const [packagePattern, build] of Object.entries(pnpmSettings.allowBuilds)) {
|
||||||
|
|||||||
@@ -412,6 +412,17 @@ export async function getConfig (opts: {
|
|||||||
workspaceManifest,
|
workspaceManifest,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
} else if (cliOptions['global']) {
|
||||||
|
// For global installs, read settings from pnpm-workspace.yaml in the global package directory
|
||||||
|
const workspaceManifest = await readWorkspaceManifest(pnpmConfig.globalPkgDir)
|
||||||
|
if (workspaceManifest) {
|
||||||
|
addSettingsFromWorkspaceManifestToConfig(pnpmConfig, {
|
||||||
|
configFromCliOpts,
|
||||||
|
projectManifest: pnpmConfig.rootProjectManifest,
|
||||||
|
workspaceDir: pnpmConfig.globalPkgDir,
|
||||||
|
workspaceManifest,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -459,13 +470,8 @@ export async function getConfig (opts: {
|
|||||||
|
|
||||||
overrideSupportedArchitecturesWithCLI(pnpmConfig, cliOptions)
|
overrideSupportedArchitecturesWithCLI(pnpmConfig, cliOptions)
|
||||||
|
|
||||||
if (opts.cliOptions['global']) {
|
if (!hasDependencyBuildOptions(pnpmConfig)) {
|
||||||
extractAndRemoveDependencyBuildOptions(pnpmConfig)
|
|
||||||
Object.assign(pnpmConfig, globalDepsBuildConfig)
|
Object.assign(pnpmConfig, globalDepsBuildConfig)
|
||||||
} else {
|
|
||||||
if (!hasDependencyBuildOptions(pnpmConfig)) {
|
|
||||||
Object.assign(pnpmConfig, globalDepsBuildConfig)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (opts.cliOptions['save-peer']) {
|
if (opts.cliOptions['save-peer']) {
|
||||||
if (opts.cliOptions['save-prod']) {
|
if (opts.cliOptions['save-prod']) {
|
||||||
@@ -621,12 +627,6 @@ export async function getConfig (opts: {
|
|||||||
pnpmConfig.dev = true
|
pnpmConfig.dev = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pnpmConfig.dangerouslyAllowAllBuilds) {
|
|
||||||
if (pnpmConfig.neverBuiltDependencies && pnpmConfig.neverBuiltDependencies.length > 0) {
|
|
||||||
warnings.push('You have set dangerouslyAllowAllBuilds to true. The dependencies listed in neverBuiltDependencies will run their scripts.')
|
|
||||||
}
|
|
||||||
pnpmConfig.neverBuiltDependencies = []
|
|
||||||
}
|
|
||||||
if (pnpmConfig.ci) {
|
if (pnpmConfig.ci) {
|
||||||
// Using a global virtual store in CI makes little sense,
|
// Using a global virtual store in CI makes little sense,
|
||||||
// as there is never a warm cache in that environment.
|
// as there is never a warm cache in that environment.
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ test('getOptionsFromRootManifest() should return onlyBuiltDependencies as undefi
|
|||||||
test('getOptionsFromRootManifest() should return the list from onlyBuiltDependencies', () => {
|
test('getOptionsFromRootManifest() should return the list from onlyBuiltDependencies', () => {
|
||||||
const options = getOptionsFromRootManifest(process.cwd(), {
|
const options = getOptionsFromRootManifest(process.cwd(), {
|
||||||
pnpm: {
|
pnpm: {
|
||||||
onlyBuiltDependencies: ['electron'],
|
allowBuilds: { electron: true },
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
expect(options.onlyBuiltDependencies).toStrictEqual(['electron'])
|
expect(options.onlyBuiltDependencies).toStrictEqual(['electron'])
|
||||||
@@ -186,6 +186,11 @@ test('getOptionsFromRootManifest() converts allowBuilds', () => {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
expect(options).toStrictEqual({
|
expect(options).toStrictEqual({
|
||||||
|
allowBuilds: {
|
||||||
|
foo: true,
|
||||||
|
bar: false,
|
||||||
|
qar: 'warn',
|
||||||
|
},
|
||||||
onlyBuiltDependencies: ['foo'],
|
onlyBuiltDependencies: ['foo'],
|
||||||
ignoredBuiltDependencies: ['bar'],
|
ignoredBuiltDependencies: ['bar'],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1281,38 +1281,6 @@ test('settings gitBranchLockfile in pnpm-workspace.yaml should take effect', asy
|
|||||||
expect(config.rawConfig['git-branch-lockfile']).toBe(true)
|
expect(config.rawConfig['git-branch-lockfile']).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('when dangerouslyAllowAllBuilds is set to true neverBuiltDependencies is set to an empty array', async () => {
|
|
||||||
const { config } = await getConfig({
|
|
||||||
cliOptions: {
|
|
||||||
'dangerously-allow-all-builds': true,
|
|
||||||
},
|
|
||||||
packageManager: {
|
|
||||||
name: 'pnpm',
|
|
||||||
version: '1.0.0',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
expect(config.neverBuiltDependencies).toStrictEqual([])
|
|
||||||
})
|
|
||||||
|
|
||||||
test('when dangerouslyAllowAllBuilds is set to true and neverBuiltDependencies not empty, a warning is returned', async () => {
|
|
||||||
const workspaceDir = f.find('never-built-dependencies')
|
|
||||||
process.chdir(workspaceDir)
|
|
||||||
const { config, warnings } = await getConfig({
|
|
||||||
cliOptions: {
|
|
||||||
'dangerously-allow-all-builds': true,
|
|
||||||
},
|
|
||||||
packageManager: {
|
|
||||||
name: 'pnpm',
|
|
||||||
version: '1.0.0',
|
|
||||||
},
|
|
||||||
workspaceDir,
|
|
||||||
})
|
|
||||||
|
|
||||||
expect(config.neverBuiltDependencies).toStrictEqual([])
|
|
||||||
expect(warnings).toStrictEqual(['You have set dangerouslyAllowAllBuilds to true. The dependencies listed in neverBuiltDependencies will run their scripts.'])
|
|
||||||
})
|
|
||||||
|
|
||||||
test('loads setting from environment variable pnpm_config_*', async () => {
|
test('loads setting from environment variable pnpm_config_*', async () => {
|
||||||
prepareEmpty()
|
prepareEmpty()
|
||||||
const { config } = await getConfig({
|
const { config } = await getConfig({
|
||||||
|
|||||||
@@ -51,6 +51,7 @@
|
|||||||
"diskusage",
|
"diskusage",
|
||||||
"dislink",
|
"dislink",
|
||||||
"dpkg",
|
"dpkg",
|
||||||
|
"drivelist",
|
||||||
"duplexify",
|
"duplexify",
|
||||||
"eagain",
|
"eagain",
|
||||||
"ebadplatform",
|
"ebadplatform",
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { type Config } from '@pnpm/config'
|
|||||||
import { globalInfo } from '@pnpm/logger'
|
import { globalInfo } from '@pnpm/logger'
|
||||||
import { type StrictModules, writeModulesManifest } from '@pnpm/modules-yaml'
|
import { type StrictModules, writeModulesManifest } from '@pnpm/modules-yaml'
|
||||||
import { lexCompare } from '@pnpm/util.lex-comparator'
|
import { lexCompare } from '@pnpm/util.lex-comparator'
|
||||||
import { type PnpmSettings } from '@pnpm/types'
|
|
||||||
import renderHelp from 'render-help'
|
import renderHelp from 'render-help'
|
||||||
import enquirer from 'enquirer'
|
import enquirer from 'enquirer'
|
||||||
import chalk from 'chalk'
|
import chalk from 'chalk'
|
||||||
@@ -92,25 +91,19 @@ export async function handler (opts: ApproveBuildsCommandOpts & RebuildCommandOp
|
|||||||
} as any) as any // eslint-disable-line @typescript-eslint/no-explicit-any
|
} as any) as any // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||||
const buildPackages = result.map(({ value }: { value: string }) => value)
|
const buildPackages = result.map(({ value }: { value: string }) => value)
|
||||||
const ignoredPackages = automaticallyIgnoredBuilds.filter((automaticallyIgnoredBuild) => !buildPackages.includes(automaticallyIgnoredBuild))
|
const ignoredPackages = automaticallyIgnoredBuilds.filter((automaticallyIgnoredBuild) => !buildPackages.includes(automaticallyIgnoredBuild))
|
||||||
const updatedSettings: PnpmSettings = {}
|
const allowBuilds: Record<string, boolean> = {}
|
||||||
if (ignoredPackages.length) {
|
if (ignoredPackages.length) {
|
||||||
if (opts.ignoredBuiltDependencies == null) {
|
for (const pkg of [...ignoredPackages, ...opts.ignoredBuiltDependencies ?? []]) {
|
||||||
updatedSettings.ignoredBuiltDependencies = sortUniqueStrings(ignoredPackages)
|
allowBuilds[pkg] = false
|
||||||
} else {
|
|
||||||
updatedSettings.ignoredBuiltDependencies = sortUniqueStrings([
|
|
||||||
...opts.ignoredBuiltDependencies,
|
|
||||||
...ignoredPackages,
|
|
||||||
])
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (buildPackages.length) {
|
const onlyBuiltDependencies = [
|
||||||
if (opts.onlyBuiltDependencies == null) {
|
...opts.onlyBuiltDependencies ?? [],
|
||||||
updatedSettings.onlyBuiltDependencies = sortUniqueStrings(buildPackages)
|
...buildPackages,
|
||||||
} else {
|
]
|
||||||
updatedSettings.onlyBuiltDependencies = sortUniqueStrings([
|
if (onlyBuiltDependencies.length) {
|
||||||
...opts.onlyBuiltDependencies,
|
for (const pkg of onlyBuiltDependencies) {
|
||||||
...buildPackages,
|
allowBuilds[pkg] = true
|
||||||
])
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (buildPackages.length) {
|
if (buildPackages.length) {
|
||||||
@@ -130,12 +123,12 @@ Do you approve?`,
|
|||||||
await writeSettings({
|
await writeSettings({
|
||||||
...opts,
|
...opts,
|
||||||
workspaceDir: opts.workspaceDir ?? opts.rootProjectManifestDir,
|
workspaceDir: opts.workspaceDir ?? opts.rootProjectManifestDir,
|
||||||
updatedSettings,
|
updatedSettings: { allowBuilds },
|
||||||
})
|
})
|
||||||
if (buildPackages.length) {
|
if (buildPackages.length) {
|
||||||
return rebuild.handler({
|
return rebuild.handler({
|
||||||
...opts,
|
...opts,
|
||||||
onlyBuiltDependencies: updatedSettings.onlyBuiltDependencies,
|
onlyBuiltDependencies,
|
||||||
}, buildPackages)
|
}, buildPackages)
|
||||||
} else if (modulesManifest) {
|
} else if (modulesManifest) {
|
||||||
delete modulesManifest.ignoredBuilds
|
delete modulesManifest.ignoredBuilds
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { type Config } from '@pnpm/config'
|
|||||||
import renderHelp from 'render-help'
|
import renderHelp from 'render-help'
|
||||||
import { getAutomaticallyIgnoredBuilds } from './getAutomaticallyIgnoredBuilds.js'
|
import { getAutomaticallyIgnoredBuilds } from './getAutomaticallyIgnoredBuilds.js'
|
||||||
|
|
||||||
export type IgnoredBuildsCommandOpts = Pick<Config, 'modulesDir' | 'dir' | 'rootProjectManifest' | 'lockfileDir'>
|
export type IgnoredBuildsCommandOpts = Pick<Config, 'modulesDir' | 'dir' | 'ignoredBuiltDependencies' | 'lockfileDir'>
|
||||||
|
|
||||||
export const commandNames = ['ignored-builds']
|
export const commandNames = ['ignored-builds']
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ export function rcOptionsTypes (): Record<string, unknown> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function handler (opts: IgnoredBuildsCommandOpts): Promise<string> {
|
export async function handler (opts: IgnoredBuildsCommandOpts): Promise<string> {
|
||||||
const ignoredBuiltDependencies = opts.rootProjectManifest?.pnpm?.ignoredBuiltDependencies ?? []
|
const ignoredBuiltDependencies = opts.ignoredBuiltDependencies ?? []
|
||||||
let { automaticallyIgnoredBuilds } = await getAutomaticallyIgnoredBuilds(opts)
|
let { automaticallyIgnoredBuilds } = await getAutomaticallyIgnoredBuilds(opts)
|
||||||
if (automaticallyIgnoredBuilds) {
|
if (automaticallyIgnoredBuilds) {
|
||||||
automaticallyIgnoredBuilds = automaticallyIgnoredBuilds
|
automaticallyIgnoredBuilds = automaticallyIgnoredBuilds
|
||||||
@@ -35,12 +35,15 @@ export async function handler (opts: IgnoredBuildsCommandOpts): Promise<string>
|
|||||||
output += ' None'
|
output += ' None'
|
||||||
} else {
|
} else {
|
||||||
output += ` ${automaticallyIgnoredBuilds.join('\n ')}
|
output += ` ${automaticallyIgnoredBuilds.join('\n ')}
|
||||||
hint: To allow the execution of build scripts for a package, add its name to "pnpm.onlyBuiltDependencies" in your "package.json", then run "pnpm rebuild".
|
hint: To allow the execution of build scripts for a package, add its name to "allowBuilds" and set to "true", then run "pnpm rebuild".
|
||||||
hint: If you don't want to build a package, add it to the "pnpm.ignoredBuiltDependencies" list.`
|
hint: For example:
|
||||||
|
hint: allowBuilds:
|
||||||
|
hint: esbuild: true
|
||||||
|
hint: If you don't want to build a package, set it to "false" instead.`
|
||||||
}
|
}
|
||||||
output += '\n'
|
output += '\n'
|
||||||
if (ignoredBuiltDependencies.length) {
|
if (ignoredBuiltDependencies.length) {
|
||||||
output += `\nExplicitly ignored package builds (via pnpm.ignoredBuiltDependencies):\n ${ignoredBuiltDependencies.join('\n ')}\n`
|
output += `\nExplicitly ignored package builds (via allowBuilds):\n ${ignoredBuiltDependencies.join('\n ')}\n`
|
||||||
}
|
}
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||||
|
|
||||||
exports[`ignoredBuilds lists automatically ignored dependencies 1`] = `
|
exports[`ignoredBuilds lists automatically ignored dependencies 1`] = `
|
||||||
"Automatically ignored builds during installation:
|
"Automatically ignored builds during installation:
|
||||||
foo
|
foo
|
||||||
hint: To allow the execution of build scripts for a package, add its name to "pnpm.onlyBuiltDependencies" in your "package.json", then run "pnpm rebuild".
|
hint: To allow the execution of build scripts for a package, add its name to "allowBuilds" and set to "true", then run "pnpm rebuild".
|
||||||
hint: If you don't want to build a package, add it to the "pnpm.ignoredBuiltDependencies" list.
|
hint: For example:
|
||||||
|
hint: allowBuilds:
|
||||||
|
hint: esbuild: true
|
||||||
|
hint: If you don't want to build a package, set it to "false" instead.
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -12,10 +15,13 @@ exports[`ignoredBuilds lists both automatically and explicitly ignored dependenc
|
|||||||
"Automatically ignored builds during installation:
|
"Automatically ignored builds during installation:
|
||||||
foo
|
foo
|
||||||
bar
|
bar
|
||||||
hint: To allow the execution of build scripts for a package, add its name to "pnpm.onlyBuiltDependencies" in your "package.json", then run "pnpm rebuild".
|
hint: To allow the execution of build scripts for a package, add its name to "allowBuilds" and set to "true", then run "pnpm rebuild".
|
||||||
hint: If you don't want to build a package, add it to the "pnpm.ignoredBuiltDependencies" list.
|
hint: For example:
|
||||||
|
hint: allowBuilds:
|
||||||
|
hint: esbuild: true
|
||||||
|
hint: If you don't want to build a package, set it to "false" instead.
|
||||||
|
|
||||||
Explicitly ignored package builds (via pnpm.ignoredBuiltDependencies):
|
Explicitly ignored package builds (via allowBuilds):
|
||||||
qar
|
qar
|
||||||
zoo
|
zoo
|
||||||
"
|
"
|
||||||
@@ -25,7 +31,7 @@ exports[`ignoredBuilds lists explicitly ignored dependencies 1`] = `
|
|||||||
"Automatically ignored builds during installation:
|
"Automatically ignored builds during installation:
|
||||||
None
|
None
|
||||||
|
|
||||||
Explicitly ignored package builds (via pnpm.ignoredBuiltDependencies):
|
Explicitly ignored package builds (via allowBuilds):
|
||||||
bar
|
bar
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
@@ -34,7 +40,7 @@ exports[`ignoredBuilds prints an info message when there is no node_modules 1`]
|
|||||||
"Automatically ignored builds during installation:
|
"Automatically ignored builds during installation:
|
||||||
Cannot identify as no node_modules found
|
Cannot identify as no node_modules found
|
||||||
|
|
||||||
Explicitly ignored package builds (via pnpm.ignoredBuiltDependencies):
|
Explicitly ignored package builds (via allowBuilds):
|
||||||
qar
|
qar
|
||||||
zoo
|
zoo
|
||||||
"
|
"
|
||||||
|
|||||||
@@ -4,12 +4,10 @@ import { install } from '@pnpm/plugin-commands-installation'
|
|||||||
import { type ApproveBuildsCommandOpts } from '@pnpm/exec.build-commands'
|
import { type ApproveBuildsCommandOpts } from '@pnpm/exec.build-commands'
|
||||||
import { type RebuildCommandOpts } from '@pnpm/plugin-commands-rebuild'
|
import { type RebuildCommandOpts } from '@pnpm/plugin-commands-rebuild'
|
||||||
import { prepare } from '@pnpm/prepare'
|
import { prepare } from '@pnpm/prepare'
|
||||||
import { type ProjectManifest } from '@pnpm/types'
|
|
||||||
import { getConfig } from '@pnpm/config'
|
import { getConfig } from '@pnpm/config'
|
||||||
import { readModulesManifest } from '@pnpm/modules-yaml'
|
import { readModulesManifest } from '@pnpm/modules-yaml'
|
||||||
import { REGISTRY_MOCK_PORT } from '@pnpm/registry-mock'
|
import { REGISTRY_MOCK_PORT } from '@pnpm/registry-mock'
|
||||||
import { jest } from '@jest/globals'
|
import { jest } from '@jest/globals'
|
||||||
import { loadJsonFileSync } from 'load-json-file'
|
|
||||||
import { omit } from 'ramda'
|
import { omit } from 'ramda'
|
||||||
import { tempDir } from '@pnpm/prepare-temp-dir'
|
import { tempDir } from '@pnpm/prepare-temp-dir'
|
||||||
import { writePackageSync } from 'write-package'
|
import { writePackageSync } from 'write-package'
|
||||||
@@ -88,16 +86,15 @@ test('approve selected build', async () => {
|
|||||||
'@pnpm.e2e/pre-and-postinstall-scripts-example': '1.0.0',
|
'@pnpm.e2e/pre-and-postinstall-scripts-example': '1.0.0',
|
||||||
'@pnpm.e2e/install-script-example': '*',
|
'@pnpm.e2e/install-script-example': '*',
|
||||||
},
|
},
|
||||||
pnpm: {
|
|
||||||
overrides: {},
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
await approveSomeBuilds()
|
await approveSomeBuilds()
|
||||||
|
|
||||||
const manifest = loadJsonFileSync<ProjectManifest>(path.resolve('package.json'))
|
const workspaceManifest = readYamlFile<any>(path.resolve('pnpm-workspace.yaml')) // eslint-disable-line
|
||||||
expect(manifest.pnpm?.onlyBuiltDependencies).toStrictEqual(['@pnpm.e2e/pre-and-postinstall-scripts-example'])
|
expect(workspaceManifest.allowBuilds).toStrictEqual({
|
||||||
expect(manifest.pnpm?.ignoredBuiltDependencies).toStrictEqual(['@pnpm.e2e/install-script-example'])
|
'@pnpm.e2e/install-script-example': false,
|
||||||
|
'@pnpm.e2e/pre-and-postinstall-scripts-example': true,
|
||||||
|
})
|
||||||
|
|
||||||
expect(fs.existsSync('node_modules/@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-preinstall.js')).toBeTruthy()
|
expect(fs.existsSync('node_modules/@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-preinstall.js')).toBeTruthy()
|
||||||
expect(fs.existsSync('node_modules/@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-postinstall.js')).toBeTruthy()
|
expect(fs.existsSync('node_modules/@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-postinstall.js')).toBeTruthy()
|
||||||
@@ -155,62 +152,6 @@ test("works when root project manifest doesn't exist in a workspace", async () =
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should update onlyBuiltDependencies when package.json exists with ignoredBuiltDependencies defined', async () => {
|
|
||||||
const temp = tempDir()
|
|
||||||
const rootProjectManifest = {
|
|
||||||
dependencies: {
|
|
||||||
'@pnpm.e2e/pre-and-postinstall-scripts-example': '1.0.0',
|
|
||||||
'@pnpm.e2e/install-script-example': '*',
|
|
||||||
},
|
|
||||||
pnpm: {
|
|
||||||
ignoredBuiltDependencies: ['@pnpm.e2e/install-script-example'],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
prepare(rootProjectManifest, {
|
|
||||||
tempDir: temp,
|
|
||||||
})
|
|
||||||
|
|
||||||
const workspaceManifestFile = path.join(temp, 'pnpm-workspace.yaml')
|
|
||||||
writeYamlFile(workspaceManifestFile, { packages: ['packages/*'] })
|
|
||||||
await approveSomeBuilds({ workspaceDir: temp, rootProjectManifestDir: temp, rootProjectManifest })
|
|
||||||
|
|
||||||
expect(readYamlFile(workspaceManifestFile)).toStrictEqual({
|
|
||||||
packages: ['packages/*'],
|
|
||||||
})
|
|
||||||
expect(loadJsonFileSync<ProjectManifest>(path.join(temp, 'package.json'))!.pnpm).toStrictEqual({
|
|
||||||
ignoredBuiltDependencies: ['@pnpm.e2e/install-script-example'],
|
|
||||||
onlyBuiltDependencies: ['@pnpm.e2e/pre-and-postinstall-scripts-example'],
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('should approve builds when package.json exists with onlyBuiltDependencies defined', async () => {
|
|
||||||
const temp = tempDir()
|
|
||||||
|
|
||||||
prepare({
|
|
||||||
dependencies: {
|
|
||||||
'@pnpm.e2e/pre-and-postinstall-scripts-example': '1.0.0',
|
|
||||||
'@pnpm.e2e/install-script-example': '*',
|
|
||||||
},
|
|
||||||
pnpm: {
|
|
||||||
onlyBuiltDependencies: ['@pnpm.e2e/install-script-example'],
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
tempDir: temp,
|
|
||||||
})
|
|
||||||
|
|
||||||
const workspaceManifestFile = path.join(temp, 'pnpm-workspace.yaml')
|
|
||||||
writeYamlFile(workspaceManifestFile, { packages: ['packages/*'] })
|
|
||||||
await approveSomeBuilds({ workspaceDir: temp, rootProjectManifestDir: temp })
|
|
||||||
|
|
||||||
expect(readYamlFile(workspaceManifestFile)).toStrictEqual({
|
|
||||||
packages: ['packages/*'],
|
|
||||||
})
|
|
||||||
expect(loadJsonFileSync<ProjectManifest>(path.join(temp, 'package.json'))!.pnpm).toStrictEqual({
|
|
||||||
onlyBuiltDependencies: ['@pnpm.e2e/install-script-example', '@pnpm.e2e/pre-and-postinstall-scripts-example'],
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('should approve builds with package.json that has no onlyBuiltDependencies and ignoredBuiltDependencies fields defined', async () => {
|
test('should approve builds with package.json that has no onlyBuiltDependencies and ignoredBuiltDependencies fields defined', async () => {
|
||||||
const temp = tempDir()
|
const temp = tempDir()
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ test('ignoredBuilds lists automatically ignored dependencies', async () => {
|
|||||||
const output = await ignoredBuilds.handler({
|
const output = await ignoredBuilds.handler({
|
||||||
dir,
|
dir,
|
||||||
modulesDir,
|
modulesDir,
|
||||||
rootProjectManifest: {},
|
ignoredBuiltDependencies: [],
|
||||||
})
|
})
|
||||||
expect(output).toMatchSnapshot()
|
expect(output).toMatchSnapshot()
|
||||||
})
|
})
|
||||||
@@ -52,11 +52,7 @@ test('ignoredBuilds lists explicitly ignored dependencies', async () => {
|
|||||||
const output = await ignoredBuilds.handler({
|
const output = await ignoredBuilds.handler({
|
||||||
dir,
|
dir,
|
||||||
modulesDir,
|
modulesDir,
|
||||||
rootProjectManifest: {
|
ignoredBuiltDependencies: ['bar'],
|
||||||
pnpm: {
|
|
||||||
ignoredBuiltDependencies: ['bar'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
expect(output).toMatchSnapshot()
|
expect(output).toMatchSnapshot()
|
||||||
})
|
})
|
||||||
@@ -72,11 +68,7 @@ test('ignoredBuilds lists both automatically and explicitly ignored dependencies
|
|||||||
const output = await ignoredBuilds.handler({
|
const output = await ignoredBuilds.handler({
|
||||||
dir,
|
dir,
|
||||||
modulesDir,
|
modulesDir,
|
||||||
rootProjectManifest: {
|
ignoredBuiltDependencies: ['qar', 'zoo'],
|
||||||
pnpm: {
|
|
||||||
ignoredBuiltDependencies: ['qar', 'zoo'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
expect(output).toMatchSnapshot()
|
expect(output).toMatchSnapshot()
|
||||||
})
|
})
|
||||||
@@ -87,11 +79,7 @@ test('ignoredBuilds prints an info message when there is no node_modules', async
|
|||||||
const output = await ignoredBuilds.handler({
|
const output = await ignoredBuilds.handler({
|
||||||
dir,
|
dir,
|
||||||
modulesDir,
|
modulesDir,
|
||||||
rootProjectManifest: {
|
ignoredBuiltDependencies: ['qar', 'zoo'],
|
||||||
pnpm: {
|
|
||||||
ignoredBuiltDependencies: ['qar', 'zoo'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
expect(output).toMatchSnapshot()
|
expect(output).toMatchSnapshot()
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ export type StrictRebuildOptions = {
|
|||||||
peersSuffixMaxLength: number
|
peersSuffixMaxLength: number
|
||||||
strictStorePkgContentCheck: boolean
|
strictStorePkgContentCheck: boolean
|
||||||
fetchFullMetadata?: boolean
|
fetchFullMetadata?: boolean
|
||||||
} & Pick<Config, 'sslConfigs' | 'onlyBuiltDependencies' | 'onlyBuiltDependenciesFile' | 'neverBuiltDependencies' | 'ignoredBuiltDependencies'>
|
} & Pick<Config, 'sslConfigs' | 'onlyBuiltDependencies' | 'ignoredBuiltDependencies'>
|
||||||
|
|
||||||
export type RebuildOptions = Partial<StrictRebuildOptions> &
|
export type RebuildOptions = Partial<StrictRebuildOptions> &
|
||||||
Pick<StrictRebuildOptions, 'storeDir' | 'storeController'> & Pick<Config, 'rootProjectManifest' | 'rootProjectManifestDir'>
|
Pick<StrictRebuildOptions, 'storeDir' | 'storeController'> & Pick<Config, 'rootProjectManifest' | 'rootProjectManifestDir'>
|
||||||
@@ -106,7 +106,7 @@ export async function extendRebuildOptions (
|
|||||||
...(opts.rootProjectManifest ? getOptionsFromRootManifest(opts.rootProjectManifestDir, opts.rootProjectManifest) : {}),
|
...(opts.rootProjectManifest ? getOptionsFromRootManifest(opts.rootProjectManifestDir, opts.rootProjectManifest) : {}),
|
||||||
}
|
}
|
||||||
extendedOpts.registries = normalizeRegistries(extendedOpts.registries)
|
extendedOpts.registries = normalizeRegistries(extendedOpts.registries)
|
||||||
if (extendedOpts.neverBuiltDependencies == null && extendedOpts.onlyBuiltDependencies == null && extendedOpts.onlyBuiltDependenciesFile == null) {
|
if (extendedOpts.onlyBuiltDependencies == null) {
|
||||||
extendedOpts.onlyBuiltDependencies = []
|
extendedOpts.onlyBuiltDependencies = []
|
||||||
}
|
}
|
||||||
return extendedOpts
|
return extendedOpts
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ test('rebuilds dependencies', async () => {
|
|||||||
pending: false,
|
pending: false,
|
||||||
registries: modulesManifest!.registries!,
|
registries: modulesManifest!.registries!,
|
||||||
storeDir,
|
storeDir,
|
||||||
|
onlyBuiltDependencies: ['@pnpm.e2e/pre-and-postinstall-scripts-example', 'test-git-fetch'],
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
modules = project.readModulesManifest()
|
modules = project.readModulesManifest()
|
||||||
@@ -139,6 +140,7 @@ test('skipIfHasSideEffectsCache', async () => {
|
|||||||
registries: modulesManifest!.registries!,
|
registries: modulesManifest!.registries!,
|
||||||
skipIfHasSideEffectsCache: true,
|
skipIfHasSideEffectsCache: true,
|
||||||
storeDir,
|
storeDir,
|
||||||
|
onlyBuiltDependencies: ['@pnpm.e2e/pre-and-postinstall-scripts-example'],
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
modules = project.readModulesManifest()
|
modules = project.readModulesManifest()
|
||||||
@@ -176,6 +178,7 @@ test('rebuild does not fail when a linked package is present', async () => {
|
|||||||
pending: false,
|
pending: false,
|
||||||
registries: modulesManifest!.registries!,
|
registries: modulesManifest!.registries!,
|
||||||
storeDir,
|
storeDir,
|
||||||
|
onlyBuiltDependencies: ['local-pkg', 'is-positive'],
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
// see related issue https://github.com/pnpm/pnpm/issues/1155
|
// see related issue https://github.com/pnpm/pnpm/issues/1155
|
||||||
@@ -206,6 +209,7 @@ test('rebuilds specific dependencies', async () => {
|
|||||||
pending: false,
|
pending: false,
|
||||||
registries: modulesManifest!.registries!,
|
registries: modulesManifest!.registries!,
|
||||||
storeDir,
|
storeDir,
|
||||||
|
onlyBuiltDependencies: ['install-scripts-example-for-pnpm'],
|
||||||
}, ['install-scripts-example-for-pnpm'])
|
}, ['install-scripts-example-for-pnpm'])
|
||||||
|
|
||||||
project.hasNot('@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-preinstall')
|
project.hasNot('@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-preinstall')
|
||||||
@@ -265,6 +269,7 @@ test('rebuild with pending option', async () => {
|
|||||||
pending: true,
|
pending: true,
|
||||||
registries: modules!.registries!,
|
registries: modules!.registries!,
|
||||||
storeDir,
|
storeDir,
|
||||||
|
onlyBuiltDependencies: ['@pnpm.e2e/pre-and-postinstall-scripts-example', 'install-scripts-example-for-pnpm'],
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
modules = project.readModulesManifest()
|
modules = project.readModulesManifest()
|
||||||
@@ -318,6 +323,7 @@ test('rebuild dependencies in correct order', async () => {
|
|||||||
pending: false,
|
pending: false,
|
||||||
registries: modules!.registries!,
|
registries: modules!.registries!,
|
||||||
storeDir,
|
storeDir,
|
||||||
|
onlyBuiltDependencies: ['@pnpm.e2e/with-postinstall-a', '@pnpm.e2e/with-postinstall-b'],
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
modules = project.readModulesManifest()
|
modules = project.readModulesManifest()
|
||||||
@@ -359,6 +365,7 @@ test('rebuild links bins', async () => {
|
|||||||
pending: true,
|
pending: true,
|
||||||
registries: modules!.registries!,
|
registries: modules!.registries!,
|
||||||
storeDir,
|
storeDir,
|
||||||
|
onlyBuiltDependencies: ['@pnpm.e2e/has-generated-bins-as-dep', '@pnpm.e2e/generated-bins'],
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
project.isExecutable('.bin/cmd1')
|
project.isExecutable('.bin/cmd1')
|
||||||
@@ -400,51 +407,6 @@ test(`rebuild should not fail on incomplete ${WANTED_LOCKFILE}`, async () => {
|
|||||||
registries: modules!.registries!,
|
registries: modules!.registries!,
|
||||||
reporter,
|
reporter,
|
||||||
storeDir,
|
storeDir,
|
||||||
|
onlyBuiltDependencies: ['@pnpm.e2e/pre-and-postinstall-scripts-example', '@pnpm.e2e/not-compatible-with-any-os'],
|
||||||
}, [])
|
}, [])
|
||||||
})
|
})
|
||||||
|
|
||||||
test('never build neverBuiltDependencies', async () => {
|
|
||||||
const project = prepare({
|
|
||||||
pnpm: {
|
|
||||||
neverBuiltDependencies: [],
|
|
||||||
},
|
|
||||||
})
|
|
||||||
const cacheDir = path.resolve('cache')
|
|
||||||
const storeDir = path.resolve('store')
|
|
||||||
|
|
||||||
await execa('node', [
|
|
||||||
pnpmBin,
|
|
||||||
'add',
|
|
||||||
'@pnpm.e2e/install-script-example@1.0.0',
|
|
||||||
'@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0',
|
|
||||||
`--registry=${REGISTRY}`,
|
|
||||||
`--store-dir=${storeDir}`,
|
|
||||||
`--cache-dir=${cacheDir}`,
|
|
||||||
'--config.enableGlobalVirtualStore=false',
|
|
||||||
])
|
|
||||||
|
|
||||||
const modulesManifest = project.readModulesManifest()
|
|
||||||
await rebuild.handler(
|
|
||||||
{
|
|
||||||
...DEFAULT_OPTS,
|
|
||||||
neverBuiltDependencies: ['@pnpm.e2e/pre-and-postinstall-scripts-example'],
|
|
||||||
cacheDir,
|
|
||||||
dir: process.cwd(),
|
|
||||||
pending: false,
|
|
||||||
registries: modulesManifest!.registries!,
|
|
||||||
storeDir,
|
|
||||||
},
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(
|
|
||||||
fs.existsSync(
|
|
||||||
'node_modules/@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-prepare.js'
|
|
||||||
)
|
|
||||||
).toBeFalsy()
|
|
||||||
expect(
|
|
||||||
fs.existsSync(
|
|
||||||
'node_modules/@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-preinstall.js'
|
|
||||||
)
|
|
||||||
).toBeTruthy()
|
|
||||||
})
|
|
||||||
@@ -58,6 +58,7 @@ test('pnpm recursive rebuild', async () => {
|
|||||||
registries: modulesManifest!.registries!,
|
registries: modulesManifest!.registries!,
|
||||||
selectedProjectsGraph,
|
selectedProjectsGraph,
|
||||||
workspaceDir: process.cwd(),
|
workspaceDir: process.cwd(),
|
||||||
|
onlyBuiltDependencies: ['@pnpm.e2e/pre-and-postinstall-scripts-example'],
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
projects['project-1'].has('@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-preinstall.js')
|
projects['project-1'].has('@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-preinstall.js')
|
||||||
@@ -136,6 +137,7 @@ test('pnpm recursive rebuild with hoisted node linker', async () => {
|
|||||||
selectedProjectsGraph,
|
selectedProjectsGraph,
|
||||||
lockfileDir: process.cwd(),
|
lockfileDir: process.cwd(),
|
||||||
workspaceDir: process.cwd(),
|
workspaceDir: process.cwd(),
|
||||||
|
onlyBuiltDependencies: ['@pnpm.e2e/pre-and-postinstall-scripts-example'],
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
rootProject.has('@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-preinstall.js')
|
rootProject.has('@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-preinstall.js')
|
||||||
@@ -215,13 +217,14 @@ test('rebuild multiple packages in correct order', async () => {
|
|||||||
recursive: true,
|
recursive: true,
|
||||||
selectedProjectsGraph,
|
selectedProjectsGraph,
|
||||||
workspaceDir: process.cwd(),
|
workspaceDir: process.cwd(),
|
||||||
|
onlyBuiltDependencies: ['project-1', 'project-2', 'project-3'],
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
expect(server1.getLines()).toStrictEqual(['project-1', 'project-2'])
|
expect(server1.getLines()).toStrictEqual(['project-1', 'project-2'])
|
||||||
expect(server2.getLines()).toStrictEqual(['project-1', 'project-3'])
|
expect(server2.getLines()).toStrictEqual(['project-1', 'project-3'])
|
||||||
})
|
})
|
||||||
|
|
||||||
test('never build neverBuiltDependencies', async () => {
|
test('only build onlyBuiltDependencies (not others)', async () => {
|
||||||
const projects = preparePackages([
|
const projects = preparePackages([
|
||||||
{
|
{
|
||||||
name: 'project-1',
|
name: 'project-1',
|
||||||
@@ -285,7 +288,7 @@ test('never build neverBuiltDependencies', async () => {
|
|||||||
await rebuild.handler(
|
await rebuild.handler(
|
||||||
{
|
{
|
||||||
...DEFAULT_OPTS,
|
...DEFAULT_OPTS,
|
||||||
neverBuiltDependencies: ['@pnpm.e2e/pre-and-postinstall-scripts-example'],
|
onlyBuiltDependencies: ['@pnpm.e2e/install-script-example'],
|
||||||
allProjects,
|
allProjects,
|
||||||
dir: process.cwd(),
|
dir: process.cwd(),
|
||||||
recursive: true,
|
recursive: true,
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ export const DEFAULT_OPTS = {
|
|||||||
localAddress: undefined,
|
localAddress: undefined,
|
||||||
lock: false,
|
lock: false,
|
||||||
lockStaleDuration: 90,
|
lockStaleDuration: 90,
|
||||||
neverBuiltDependencies: [],
|
|
||||||
networkConcurrency: 16,
|
networkConcurrency: 16,
|
||||||
offline: false,
|
offline: false,
|
||||||
pending: false,
|
pending: false,
|
||||||
|
|||||||
@@ -151,11 +151,7 @@ export interface AuditConfig {
|
|||||||
|
|
||||||
export interface PnpmSettings {
|
export interface PnpmSettings {
|
||||||
configDependencies?: ConfigDependencies
|
configDependencies?: ConfigDependencies
|
||||||
neverBuiltDependencies?: string[] // deprecated
|
|
||||||
onlyBuiltDependencies?: string[] // deprecated
|
|
||||||
onlyBuiltDependenciesFile?: string // deprecated
|
|
||||||
allowBuilds?: Record<string, boolean | string>
|
allowBuilds?: Record<string, boolean | string>
|
||||||
ignoredBuiltDependencies?: string[]
|
|
||||||
overrides?: Record<string, string>
|
overrides?: Record<string, string>
|
||||||
packageExtensions?: Record<string, PackageExtension>
|
packageExtensions?: Record<string, PackageExtension>
|
||||||
ignoredOptionalDependencies?: string[]
|
ignoredOptionalDependencies?: string[]
|
||||||
|
|||||||
@@ -72,9 +72,7 @@ export interface StrictInstallOptions {
|
|||||||
verifyStoreIntegrity: boolean
|
verifyStoreIntegrity: boolean
|
||||||
engineStrict: boolean
|
engineStrict: boolean
|
||||||
ignoredBuiltDependencies?: string[]
|
ignoredBuiltDependencies?: string[]
|
||||||
neverBuiltDependencies?: string[]
|
|
||||||
onlyBuiltDependencies?: string[]
|
onlyBuiltDependencies?: string[]
|
||||||
onlyBuiltDependenciesFile?: string
|
|
||||||
nodeExecPath?: string
|
nodeExecPath?: string
|
||||||
nodeLinker: 'isolated' | 'hoisted' | 'pnp'
|
nodeLinker: 'isolated' | 'hoisted' | 'pnp'
|
||||||
nodeVersion?: string
|
nodeVersion?: string
|
||||||
@@ -291,12 +289,9 @@ export function extendOptions (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (opts.neverBuiltDependencies == null && opts.onlyBuiltDependencies == null && opts.onlyBuiltDependenciesFile == null) {
|
if (opts.onlyBuiltDependencies == null) {
|
||||||
opts.onlyBuiltDependencies = []
|
opts.onlyBuiltDependencies = []
|
||||||
}
|
}
|
||||||
if (opts.onlyBuiltDependencies && opts.neverBuiltDependencies) {
|
|
||||||
throw new PnpmError('CONFIG_CONFLICT_BUILT_DEPENDENCIES', 'Cannot have both neverBuiltDependencies and onlyBuiltDependencies')
|
|
||||||
}
|
|
||||||
const defaultOpts = defaults(opts)
|
const defaultOpts = defaults(opts)
|
||||||
const extendedOpts: ProcessedInstallOptions = {
|
const extendedOpts: ProcessedInstallOptions = {
|
||||||
...defaultOpts,
|
...defaultOpts,
|
||||||
|
|||||||
@@ -370,11 +370,9 @@ export async function mutateModules (
|
|||||||
if (!opts.ignoreScripts && ignoredBuilds?.size) {
|
if (!opts.ignoreScripts && ignoredBuilds?.size) {
|
||||||
ignoredBuilds = await runUnignoredDependencyBuilds(opts, ignoredBuilds)
|
ignoredBuilds = await runUnignoredDependencyBuilds(opts, ignoredBuilds)
|
||||||
}
|
}
|
||||||
if (!opts.neverBuiltDependencies) {
|
ignoredScriptsLogger.debug({
|
||||||
ignoredScriptsLogger.debug({
|
packageNames: ignoredBuilds ? dedupePackageNamesFromIgnoredBuilds(ignoredBuilds) : [],
|
||||||
packageNames: ignoredBuilds ? dedupePackageNamesFromIgnoredBuilds(ignoredBuilds) : [],
|
})
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((reporter != null) && typeof reporter === 'function') {
|
if ((reporter != null) && typeof reporter === 'function') {
|
||||||
streamParser.removeListener('data', reporter)
|
streamParser.removeListener('data', reporter)
|
||||||
@@ -1085,7 +1083,6 @@ type InstallFunction = (
|
|||||||
patchedDependencies?: PatchGroupRecord
|
patchedDependencies?: PatchGroupRecord
|
||||||
makePartialCurrentLockfile: boolean
|
makePartialCurrentLockfile: boolean
|
||||||
needsFullResolution: boolean
|
needsFullResolution: boolean
|
||||||
neverBuiltDependencies?: string[]
|
|
||||||
onlyBuiltDependencies?: string[]
|
onlyBuiltDependencies?: string[]
|
||||||
overrides?: Record<string, string>
|
overrides?: Record<string, string>
|
||||||
updateLockfileMinorVersion: boolean
|
updateLockfileMinorVersion: boolean
|
||||||
|
|||||||
@@ -184,7 +184,12 @@ test('run pre/postinstall scripts. bin files should be linked in a hoisted node_
|
|||||||
const project = prepareEmpty()
|
const project = prepareEmpty()
|
||||||
await addDependenciesToPackage({},
|
await addDependenciesToPackage({},
|
||||||
['@pnpm.e2e/pre-and-postinstall-scripts-example'],
|
['@pnpm.e2e/pre-and-postinstall-scripts-example'],
|
||||||
testDefaults({ fastUnpack: false, nodeLinker: 'hoisted', targetDependenciesField: 'devDependencies' })
|
testDefaults({
|
||||||
|
fastUnpack: false,
|
||||||
|
nodeLinker: 'hoisted',
|
||||||
|
targetDependenciesField: 'devDependencies',
|
||||||
|
onlyBuiltDependencies: ['@pnpm.e2e/pre-and-postinstall-scripts-example'],
|
||||||
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(fs.existsSync('node_modules/@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-prepare.js')).toBeFalsy()
|
expect(fs.existsSync('node_modules/@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-prepare.js')).toBeFalsy()
|
||||||
@@ -212,7 +217,7 @@ test('running install scripts in a workspace that has no root project', async ()
|
|||||||
},
|
},
|
||||||
mutation: 'install',
|
mutation: 'install',
|
||||||
rootDir: path.resolve('project-1') as ProjectRootDir,
|
rootDir: path.resolve('project-1') as ProjectRootDir,
|
||||||
}, testDefaults({ fastUnpack: false, nodeLinker: 'hoisted' }))
|
}, testDefaults({ fastUnpack: false, nodeLinker: 'hoisted', onlyBuiltDependencies: ['@pnpm.e2e/pre-and-postinstall-scripts-example'] }))
|
||||||
|
|
||||||
expect(fs.existsSync('node_modules/@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-preinstall.js')).toBeTruthy()
|
expect(fs.existsSync('node_modules/@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-preinstall.js')).toBeTruthy()
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ test('run pre/postinstall scripts', async () => {
|
|||||||
const project = prepareEmpty()
|
const project = prepareEmpty()
|
||||||
const { updatedManifest: manifest } = await addDependenciesToPackage({},
|
const { updatedManifest: manifest } = await addDependenciesToPackage({},
|
||||||
['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0'],
|
['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0'],
|
||||||
testDefaults({ fastUnpack: false, targetDependenciesField: 'devDependencies' })
|
testDefaults({ fastUnpack: false, targetDependenciesField: 'devDependencies', onlyBuiltDependencies: ['@pnpm.e2e/pre-and-postinstall-scripts-example'] })
|
||||||
)
|
)
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -46,7 +46,7 @@ test('run pre/postinstall scripts', async () => {
|
|||||||
// testing that the packages are not installed even though they are in lockfile
|
// testing that the packages are not installed even though they are in lockfile
|
||||||
// and that their scripts are not tried to be executed
|
// and that their scripts are not tried to be executed
|
||||||
|
|
||||||
await install(manifest, testDefaults({ fastUnpack: false, production: true }))
|
await install(manifest, testDefaults({ fastUnpack: false, production: true, onlyBuiltDependencies: ['@pnpm.e2e/pre-and-postinstall-scripts-example'] }))
|
||||||
|
|
||||||
{
|
{
|
||||||
const generatedByPreinstall = project.requireModule('@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-preinstall')
|
const generatedByPreinstall = project.requireModule('@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-preinstall')
|
||||||
@@ -95,6 +95,7 @@ test('run pre/postinstall scripts, when PnP is used and no symlinks', async () =
|
|||||||
enablePnp: true,
|
enablePnp: true,
|
||||||
symlink: false,
|
symlink: false,
|
||||||
targetDependenciesField: 'devDependencies',
|
targetDependenciesField: 'devDependencies',
|
||||||
|
onlyBuiltDependencies: ['@pnpm.e2e/pre-and-postinstall-scripts-example'],
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -108,7 +109,7 @@ test('testing that the bins are linked when the package with the bins was alread
|
|||||||
const project = prepareEmpty()
|
const project = prepareEmpty()
|
||||||
|
|
||||||
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/hello-world-js-bin'], testDefaults({ fastUnpack: false }))
|
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/hello-world-js-bin'], testDefaults({ fastUnpack: false }))
|
||||||
await addDependenciesToPackage(manifest, ['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0'], testDefaults({ fastUnpack: false, targetDependenciesField: 'devDependencies' }))
|
await addDependenciesToPackage(manifest, ['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0'], testDefaults({ fastUnpack: false, targetDependenciesField: 'devDependencies', onlyBuiltDependencies: ['@pnpm.e2e/pre-and-postinstall-scripts-example'] }))
|
||||||
|
|
||||||
const generatedByPreinstall = project.requireModule('@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-preinstall')
|
const generatedByPreinstall = project.requireModule('@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-preinstall')
|
||||||
expect(typeof generatedByPreinstall).toBe('function')
|
expect(typeof generatedByPreinstall).toBe('function')
|
||||||
@@ -119,7 +120,7 @@ test('testing that the bins are linked when the package with the bins was alread
|
|||||||
|
|
||||||
test('run install scripts', async () => {
|
test('run install scripts', async () => {
|
||||||
const project = prepareEmpty()
|
const project = prepareEmpty()
|
||||||
await addDependenciesToPackage({}, ['@pnpm.e2e/install-script-example'], testDefaults({ fastUnpack: false }))
|
await addDependenciesToPackage({}, ['@pnpm.e2e/install-script-example'], testDefaults({ fastUnpack: false, onlyBuiltDependencies: ['@pnpm.e2e/install-script-example'] }))
|
||||||
|
|
||||||
const generatedByInstall = project.requireModule('@pnpm.e2e/install-script-example/generated-by-install')
|
const generatedByInstall = project.requireModule('@pnpm.e2e/install-script-example/generated-by-install')
|
||||||
expect(typeof generatedByInstall).toBe('function')
|
expect(typeof generatedByInstall).toBe('function')
|
||||||
@@ -202,6 +203,7 @@ test('INIT_CWD is always set to lockfile directory', async () => {
|
|||||||
}, testDefaults({
|
}, testDefaults({
|
||||||
fastUnpack: false,
|
fastUnpack: false,
|
||||||
lockfileDir: rootDir,
|
lockfileDir: rootDir,
|
||||||
|
onlyBuiltDependencies: ['@pnpm.e2e/write-lifecycle-env'],
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const childEnv = loadJsonFileSync<{ INIT_CWD: string }>(path.join(rootDir, 'node_modules/@pnpm.e2e/write-lifecycle-env/env.json'))
|
const childEnv = loadJsonFileSync<{ INIT_CWD: string }>(path.join(rootDir, 'node_modules/@pnpm.e2e/write-lifecycle-env/env.json'))
|
||||||
@@ -217,7 +219,7 @@ test("reports child's output", async () => {
|
|||||||
|
|
||||||
const reporter = sinon.spy()
|
const reporter = sinon.spy()
|
||||||
|
|
||||||
await addDependenciesToPackage({}, ['@pnpm.e2e/count-to-10'], testDefaults({ fastUnpack: false, reporter }))
|
await addDependenciesToPackage({}, ['@pnpm.e2e/count-to-10'], testDefaults({ fastUnpack: false, reporter, onlyBuiltDependencies: ['@pnpm.e2e/count-to-10'] }))
|
||||||
|
|
||||||
expect(reporter.calledWithMatch({
|
expect(reporter.calledWithMatch({
|
||||||
depPath: '@pnpm.e2e/count-to-10@1.0.0',
|
depPath: '@pnpm.e2e/count-to-10@1.0.0',
|
||||||
@@ -265,7 +267,7 @@ test("reports child's close event", async () => {
|
|||||||
const reporter = sinon.spy()
|
const reporter = sinon.spy()
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
addDependenciesToPackage({}, ['@pnpm.e2e/failing-postinstall'], testDefaults({ reporter }))
|
addDependenciesToPackage({}, ['@pnpm.e2e/failing-postinstall'], testDefaults({ reporter, onlyBuiltDependencies: ['@pnpm.e2e/failing-postinstall'] }))
|
||||||
).rejects.toThrow()
|
).rejects.toThrow()
|
||||||
|
|
||||||
expect(reporter.calledWithMatch({
|
expect(reporter.calledWithMatch({
|
||||||
@@ -293,7 +295,7 @@ testOnNonWindows('lifecycle scripts have access to node-gyp', async () => {
|
|||||||
!p.includes(`${path.sep}.npm${path.sep}`))
|
!p.includes(`${path.sep}.npm${path.sep}`))
|
||||||
.join(path.delimiter)
|
.join(path.delimiter)
|
||||||
|
|
||||||
await addDependenciesToPackage({}, ['drivelist@5.1.8'], testDefaults({ fastUnpack: false }))
|
await addDependenciesToPackage({}, ['drivelist@5.1.8'], testDefaults({ fastUnpack: false, onlyBuiltDependencies: ['drivelist'] }))
|
||||||
|
|
||||||
process.env[PATH] = initialPath
|
process.env[PATH] = initialPath
|
||||||
})
|
})
|
||||||
@@ -301,7 +303,7 @@ testOnNonWindows('lifecycle scripts have access to node-gyp', async () => {
|
|||||||
test('run lifecycle scripts of dependent packages after running scripts of their deps', async () => {
|
test('run lifecycle scripts of dependent packages after running scripts of their deps', async () => {
|
||||||
const project = prepareEmpty()
|
const project = prepareEmpty()
|
||||||
|
|
||||||
await addDependenciesToPackage({}, ['@pnpm.e2e/with-postinstall-a'], testDefaults({ fastUnpack: false }))
|
await addDependenciesToPackage({}, ['@pnpm.e2e/with-postinstall-a'], testDefaults({ fastUnpack: false, onlyBuiltDependencies: ['@pnpm.e2e/with-postinstall-a', '@pnpm.e2e/with-postinstall-b'] }))
|
||||||
|
|
||||||
expect(+project.requireModule('.pnpm/@pnpm.e2e+with-postinstall-b@1.0.0/node_modules/@pnpm.e2e/with-postinstall-b/output.json')[0] < +project.requireModule('@pnpm.e2e/with-postinstall-a/output.json')[0]).toBeTruthy()
|
expect(+project.requireModule('.pnpm/@pnpm.e2e+with-postinstall-b@1.0.0/node_modules/@pnpm.e2e/with-postinstall-b/output.json')[0] < +project.requireModule('@pnpm.e2e/with-postinstall-a/output.json')[0]).toBeTruthy()
|
||||||
})
|
})
|
||||||
@@ -330,7 +332,7 @@ test('run prepare script for git-hosted dependencies', async () => {
|
|||||||
test('lifecycle scripts run before linking bins', async () => {
|
test('lifecycle scripts run before linking bins', async () => {
|
||||||
const project = prepareEmpty()
|
const project = prepareEmpty()
|
||||||
|
|
||||||
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/generated-bins'], testDefaults({ fastUnpack: false }))
|
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/generated-bins'], testDefaults({ fastUnpack: false, onlyBuiltDependencies: ['@pnpm.e2e/generated-bins'] }))
|
||||||
|
|
||||||
project.isExecutable('.bin/cmd1')
|
project.isExecutable('.bin/cmd1')
|
||||||
project.isExecutable('.bin/cmd2')
|
project.isExecutable('.bin/cmd2')
|
||||||
@@ -341,7 +343,7 @@ test('lifecycle scripts run before linking bins', async () => {
|
|||||||
manifest,
|
manifest,
|
||||||
mutation: 'install',
|
mutation: 'install',
|
||||||
rootDir: process.cwd() as ProjectRootDir,
|
rootDir: process.cwd() as ProjectRootDir,
|
||||||
}, testDefaults({ frozenLockfile: true }))
|
}, testDefaults({ frozenLockfile: true, onlyBuiltDependencies: ['@pnpm.e2e/generated-bins'] }))
|
||||||
|
|
||||||
project.isExecutable('.bin/cmd1')
|
project.isExecutable('.bin/cmd1')
|
||||||
project.isExecutable('.bin/cmd2')
|
project.isExecutable('.bin/cmd2')
|
||||||
@@ -350,7 +352,7 @@ test('lifecycle scripts run before linking bins', async () => {
|
|||||||
test('hoisting does not fail on commands that will be created by lifecycle scripts on a later stage', async () => {
|
test('hoisting does not fail on commands that will be created by lifecycle scripts on a later stage', async () => {
|
||||||
prepareEmpty()
|
prepareEmpty()
|
||||||
|
|
||||||
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/has-generated-bins-as-dep'], testDefaults({ fastUnpack: false, hoistPattern: '*' }))
|
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/has-generated-bins-as-dep'], testDefaults({ fastUnpack: false, hoistPattern: '*', onlyBuiltDependencies: ['@pnpm.e2e/has-generated-bins-as-dep', '@pnpm.e2e/generated-bins'] }))
|
||||||
|
|
||||||
// project.isExecutable('.pnpm/node_modules/.bin/cmd1')
|
// project.isExecutable('.pnpm/node_modules/.bin/cmd1')
|
||||||
// project.isExecutable('.pnpm/node_modules/.bin/cmd2')
|
// project.isExecutable('.pnpm/node_modules/.bin/cmd2')
|
||||||
@@ -362,7 +364,7 @@ test('hoisting does not fail on commands that will be created by lifecycle scrip
|
|||||||
manifest,
|
manifest,
|
||||||
mutation: 'install',
|
mutation: 'install',
|
||||||
rootDir: process.cwd() as ProjectRootDir,
|
rootDir: process.cwd() as ProjectRootDir,
|
||||||
}, testDefaults({ frozenLockfile: true, hoistPattern: '*' }))
|
}, testDefaults({ frozenLockfile: true, hoistPattern: '*', onlyBuiltDependencies: ['@pnpm.e2e/has-generated-bins-as-dep', '@pnpm.e2e/generated-bins'] }))
|
||||||
|
|
||||||
// project.isExecutable('.pnpm/node_modules/.bin/cmd1')
|
// project.isExecutable('.pnpm/node_modules/.bin/cmd1')
|
||||||
// project.isExecutable('.pnpm/node_modules/.bin/cmd2')
|
// project.isExecutable('.pnpm/node_modules/.bin/cmd2')
|
||||||
@@ -423,7 +425,7 @@ test('dependency should not be added to current lockfile if it was not built suc
|
|||||||
manifest,
|
manifest,
|
||||||
mutation: 'install',
|
mutation: 'install',
|
||||||
rootDir: process.cwd() as ProjectRootDir,
|
rootDir: process.cwd() as ProjectRootDir,
|
||||||
}, testDefaults({ frozenLockfile: true }))
|
}, testDefaults({ frozenLockfile: true, onlyBuiltDependencies: ['package-that-cannot-be-installed'] }))
|
||||||
).rejects.toThrow()
|
).rejects.toThrow()
|
||||||
|
|
||||||
expect(project.readCurrentLockfile()).toBeFalsy()
|
expect(project.readCurrentLockfile()).toBeFalsy()
|
||||||
@@ -435,53 +437,19 @@ test('scripts have access to unlisted bins when hoisting is used', async () => {
|
|||||||
await addDependenciesToPackage(
|
await addDependenciesToPackage(
|
||||||
{},
|
{},
|
||||||
['@pnpm.e2e/pkg-that-calls-unlisted-dep-in-hooks'],
|
['@pnpm.e2e/pkg-that-calls-unlisted-dep-in-hooks'],
|
||||||
testDefaults({ fastUnpack: false, hoistPattern: '*' })
|
testDefaults({ fastUnpack: false, hoistPattern: '*', onlyBuiltDependencies: ['@pnpm.e2e/pkg-that-calls-unlisted-dep-in-hooks'] })
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(project.requireModule('@pnpm.e2e/pkg-that-calls-unlisted-dep-in-hooks/output.json')).toStrictEqual(['Hello world!'])
|
expect(project.requireModule('@pnpm.e2e/pkg-that-calls-unlisted-dep-in-hooks/output.json')).toStrictEqual(['Hello world!'])
|
||||||
})
|
})
|
||||||
|
|
||||||
test('selectively ignore scripts in some dependencies by neverBuiltDependencies', async () => {
|
|
||||||
prepareEmpty()
|
|
||||||
const neverBuiltDependencies = ['@pnpm.e2e/pre-and-postinstall-scripts-example']
|
|
||||||
const { updatedManifest: manifest } = await addDependenciesToPackage({},
|
|
||||||
['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0', '@pnpm.e2e/install-script-example'],
|
|
||||||
testDefaults({ fastUnpack: false, neverBuiltDependencies })
|
|
||||||
)
|
|
||||||
|
|
||||||
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()
|
|
||||||
|
|
||||||
rimraf('node_modules')
|
|
||||||
|
|
||||||
await install(manifest, testDefaults({ fastUnpack: false, frozenLockfile: true, neverBuiltDependencies }))
|
|
||||||
|
|
||||||
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()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('throw an exception when both neverBuiltDependencies and onlyBuiltDependencies are used', async () => {
|
|
||||||
prepareEmpty()
|
|
||||||
|
|
||||||
await expect(
|
|
||||||
addDependenciesToPackage(
|
|
||||||
{},
|
|
||||||
['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0'],
|
|
||||||
testDefaults({ onlyBuiltDependencies: ['@pnpm.e2e/foo'], neverBuiltDependencies: ['@pnpm.e2e/bar'] })
|
|
||||||
)
|
|
||||||
).rejects.toThrow(/Cannot have both/)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('selectively allow scripts in some dependencies by onlyBuiltDependencies', async () => {
|
test('selectively allow scripts in some dependencies by onlyBuiltDependencies', async () => {
|
||||||
prepareEmpty()
|
prepareEmpty()
|
||||||
const reporter = sinon.spy()
|
const reporter = sinon.spy()
|
||||||
const onlyBuiltDependencies = ['@pnpm.e2e/install-script-example']
|
const onlyBuiltDependencies = ['@pnpm.e2e/install-script-example']
|
||||||
const neverBuiltDependencies: string[] | undefined = undefined
|
|
||||||
const { updatedManifest: manifest } = await addDependenciesToPackage({},
|
const { updatedManifest: manifest } = await addDependenciesToPackage({},
|
||||||
['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0', '@pnpm.e2e/install-script-example'],
|
['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0', '@pnpm.e2e/install-script-example'],
|
||||||
testDefaults({ fastUnpack: false, onlyBuiltDependencies, neverBuiltDependencies, reporter })
|
testDefaults({ fastUnpack: false, onlyBuiltDependencies, reporter })
|
||||||
)
|
)
|
||||||
|
|
||||||
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-preinstall.js')).toBeFalsy()
|
||||||
@@ -500,7 +468,6 @@ test('selectively allow scripts in some dependencies by onlyBuiltDependencies',
|
|||||||
fastUnpack: false,
|
fastUnpack: false,
|
||||||
frozenLockfile: true,
|
frozenLockfile: true,
|
||||||
ignoredBuiltDependencies: ['@pnpm.e2e/pre-and-postinstall-scripts-example'],
|
ignoredBuiltDependencies: ['@pnpm.e2e/pre-and-postinstall-scripts-example'],
|
||||||
neverBuiltDependencies,
|
|
||||||
onlyBuiltDependencies,
|
onlyBuiltDependencies,
|
||||||
reporter,
|
reporter,
|
||||||
}))
|
}))
|
||||||
@@ -519,10 +486,9 @@ test('selectively allow scripts in some dependencies by onlyBuiltDependencies us
|
|||||||
prepareEmpty()
|
prepareEmpty()
|
||||||
const reporter = sinon.spy()
|
const reporter = sinon.spy()
|
||||||
const onlyBuiltDependencies = ['@pnpm.e2e/install-script-example@1.0.0']
|
const onlyBuiltDependencies = ['@pnpm.e2e/install-script-example@1.0.0']
|
||||||
const neverBuiltDependencies: string[] | undefined = undefined
|
|
||||||
const { updatedManifest: manifest } = await addDependenciesToPackage({},
|
const { updatedManifest: manifest } = await addDependenciesToPackage({},
|
||||||
['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0', '@pnpm.e2e/install-script-example'],
|
['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0', '@pnpm.e2e/install-script-example'],
|
||||||
testDefaults({ fastUnpack: false, onlyBuiltDependencies, neverBuiltDependencies, reporter })
|
testDefaults({ fastUnpack: false, onlyBuiltDependencies, reporter })
|
||||||
)
|
)
|
||||||
|
|
||||||
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-preinstall.js')).toBeFalsy()
|
||||||
@@ -541,7 +507,6 @@ test('selectively allow scripts in some dependencies by onlyBuiltDependencies us
|
|||||||
fastUnpack: false,
|
fastUnpack: false,
|
||||||
frozenLockfile: true,
|
frozenLockfile: true,
|
||||||
ignoredBuiltDependencies: ['@pnpm.e2e/pre-and-postinstall-scripts-example'],
|
ignoredBuiltDependencies: ['@pnpm.e2e/pre-and-postinstall-scripts-example'],
|
||||||
neverBuiltDependencies,
|
|
||||||
onlyBuiltDependencies,
|
onlyBuiltDependencies,
|
||||||
reporter,
|
reporter,
|
||||||
}))
|
}))
|
||||||
@@ -560,7 +525,7 @@ test('lifecycle scripts have access to package\'s own binary by binary name', as
|
|||||||
const project = prepareEmpty()
|
const project = prepareEmpty()
|
||||||
await addDependenciesToPackage({},
|
await addDependenciesToPackage({},
|
||||||
['@pnpm.e2e/runs-own-bin'],
|
['@pnpm.e2e/runs-own-bin'],
|
||||||
testDefaults({ fastUnpack: false })
|
testDefaults({ fastUnpack: false, onlyBuiltDependencies: ['@pnpm.e2e/runs-own-bin'] })
|
||||||
)
|
)
|
||||||
|
|
||||||
project.isExecutable('.pnpm/@pnpm.e2e+runs-own-bin@1.0.0/node_modules/@pnpm.e2e/runs-own-bin/node_modules/.bin/runs-own-bin')
|
project.isExecutable('.pnpm/@pnpm.e2e+runs-own-bin@1.0.0/node_modules/@pnpm.e2e/runs-own-bin/node_modules/.bin/runs-own-bin')
|
||||||
@@ -580,7 +545,7 @@ test('lifecycle scripts run after linking root dependencies', async () => {
|
|||||||
manifest,
|
manifest,
|
||||||
mutation: 'install',
|
mutation: 'install',
|
||||||
rootDir: process.cwd() as ProjectRootDir,
|
rootDir: process.cwd() as ProjectRootDir,
|
||||||
}, testDefaults({ fastUnpack: false }))
|
}, testDefaults({ fastUnpack: false, onlyBuiltDependencies: ['@pnpm.e2e/postinstall-requires-is-positive'] }))
|
||||||
|
|
||||||
rimraf('node_modules')
|
rimraf('node_modules')
|
||||||
|
|
||||||
@@ -588,7 +553,7 @@ test('lifecycle scripts run after linking root dependencies', async () => {
|
|||||||
manifest,
|
manifest,
|
||||||
mutation: 'install',
|
mutation: 'install',
|
||||||
rootDir: process.cwd() as ProjectRootDir,
|
rootDir: process.cwd() as ProjectRootDir,
|
||||||
}, testDefaults({ fastUnpack: false, frozenLockfile: true }))
|
}, testDefaults({ fastUnpack: false, frozenLockfile: true, onlyBuiltDependencies: ['@pnpm.e2e/postinstall-requires-is-positive'] }))
|
||||||
|
|
||||||
// if there was no exception, the test passed
|
// if there was no exception, the test passed
|
||||||
})
|
})
|
||||||
@@ -718,6 +683,7 @@ test('run pre/postinstall scripts in a workspace that uses node-linker=hoisted',
|
|||||||
allProjects,
|
allProjects,
|
||||||
fastUnpack: false,
|
fastUnpack: false,
|
||||||
nodeLinker: 'hoisted',
|
nodeLinker: 'hoisted',
|
||||||
|
onlyBuiltDependencies: ['@pnpm.e2e/pre-and-postinstall-scripts-example'],
|
||||||
}))
|
}))
|
||||||
const rootProject = assertProject(process.cwd())
|
const rootProject = assertProject(process.cwd())
|
||||||
rootProject.has('@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-preinstall.js')
|
rootProject.has('@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-preinstall.js')
|
||||||
@@ -736,7 +702,7 @@ test('run pre/postinstall scripts in a project that uses node-linker=hoisted. Sh
|
|||||||
const project = prepareEmpty()
|
const project = prepareEmpty()
|
||||||
const { updatedManifest: manifest } = await addDependenciesToPackage({},
|
const { updatedManifest: manifest } = await addDependenciesToPackage({},
|
||||||
['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0'],
|
['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0'],
|
||||||
testDefaults({ fastUnpack: false, targetDependenciesField: 'devDependencies', nodeLinker: 'hoisted', sideEffectsCacheRead: true, sideEffectsCacheWrite: true })
|
testDefaults({ fastUnpack: false, targetDependenciesField: 'devDependencies', nodeLinker: 'hoisted', sideEffectsCacheRead: true, sideEffectsCacheWrite: true, onlyBuiltDependencies: ['@pnpm.e2e/pre-and-postinstall-scripts-example'] })
|
||||||
)
|
)
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -760,6 +726,7 @@ test('run pre/postinstall scripts in a project that uses node-linker=hoisted. Sh
|
|||||||
reporter,
|
reporter,
|
||||||
sideEffectsCacheRead: true,
|
sideEffectsCacheRead: true,
|
||||||
sideEffectsCacheWrite: true,
|
sideEffectsCacheWrite: true,
|
||||||
|
onlyBuiltDependencies: ['@pnpm.e2e/pre-and-postinstall-scripts-example'],
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -771,13 +738,11 @@ test('run pre/postinstall scripts in a project that uses node-linker=hoisted. Sh
|
|||||||
|
|
||||||
test('build dependencies that were not previously built after onlyBuiltDependencies changes', async () => {
|
test('build dependencies that were not previously built after onlyBuiltDependencies changes', async () => {
|
||||||
prepareEmpty()
|
prepareEmpty()
|
||||||
const neverBuiltDependencies: string[] | undefined = undefined
|
|
||||||
const { updatedManifest: manifest } = await addDependenciesToPackage({},
|
const { updatedManifest: manifest } = await addDependenciesToPackage({},
|
||||||
['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0', '@pnpm.e2e/install-script-example'],
|
['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0', '@pnpm.e2e/install-script-example'],
|
||||||
testDefaults({
|
testDefaults({
|
||||||
fastUnpack: false,
|
fastUnpack: false,
|
||||||
onlyBuiltDependencies: ['@pnpm.e2e/install-script-example'],
|
onlyBuiltDependencies: ['@pnpm.e2e/install-script-example'],
|
||||||
neverBuiltDependencies,
|
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -789,7 +754,6 @@ test('build dependencies that were not previously built after onlyBuiltDependenc
|
|||||||
fastUnpack: false,
|
fastUnpack: false,
|
||||||
frozenLockfile: true,
|
frozenLockfile: true,
|
||||||
ignoredBuiltDependencies: [],
|
ignoredBuiltDependencies: [],
|
||||||
neverBuiltDependencies,
|
|
||||||
onlyBuiltDependencies: ['@pnpm.e2e/install-script-example', '@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0'],
|
onlyBuiltDependencies: ['@pnpm.e2e/install-script-example', '@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0'],
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|||||||
@@ -549,7 +549,7 @@ test('bin specified in the directories property symlinked to .bin folder when pr
|
|||||||
testOnNonWindows('building native addons', async () => {
|
testOnNonWindows('building native addons', async () => {
|
||||||
prepareEmpty()
|
prepareEmpty()
|
||||||
|
|
||||||
await addDependenciesToPackage({}, ['diskusage@1.1.3'], testDefaults({ fastUnpack: false }))
|
await addDependenciesToPackage({}, ['diskusage@1.1.3'], testDefaults({ fastUnpack: false, onlyBuiltDependencies: ['diskusage'] }))
|
||||||
|
|
||||||
expect(fs.existsSync('node_modules/diskusage/build')).toBeTruthy()
|
expect(fs.existsSync('node_modules/diskusage/build')).toBeTruthy()
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -578,7 +578,9 @@ test('fail on a package with failing postinstall if the package is both an optio
|
|||||||
'@pnpm.e2e/has-failing-postinstall-dep': '1.0.0',
|
'@pnpm.e2e/has-failing-postinstall-dep': '1.0.0',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
testDefaults({})
|
testDefaults({
|
||||||
|
onlyBuiltDependencies: ['@pnpm.e2e/has-failing-postinstall-dep', '@pnpm.e2e/failing-postinstall'],
|
||||||
|
})
|
||||||
)
|
)
|
||||||
).rejects.toThrow()
|
).rejects.toThrow()
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -822,7 +822,7 @@ test('peer bins are linked', async () => {
|
|||||||
test('run pre/postinstall scripts of each variations of packages with peer dependencies', async () => {
|
test('run pre/postinstall scripts of each variations of packages with peer dependencies', async () => {
|
||||||
await addDistTag({ package: '@pnpm.e2e/peer-c', version: '1.0.0', distTag: 'latest' })
|
await addDistTag({ package: '@pnpm.e2e/peer-c', version: '1.0.0', distTag: 'latest' })
|
||||||
prepareEmpty()
|
prepareEmpty()
|
||||||
await addDependenciesToPackage({}, ['@pnpm.e2e/parent-of-pkg-with-events-and-peers', '@pnpm.e2e/pkg-with-events-and-peers', '@pnpm.e2e/peer-c@2.0.0'], testDefaults({ fastUnpack: false }))
|
await addDependenciesToPackage({}, ['@pnpm.e2e/parent-of-pkg-with-events-and-peers', '@pnpm.e2e/pkg-with-events-and-peers', '@pnpm.e2e/peer-c@2.0.0'], testDefaults({ fastUnpack: false, onlyBuiltDependencies: ['@pnpm.e2e/pkg-with-events-and-peers'] }))
|
||||||
|
|
||||||
const pkgVariation1 = path.resolve('node_modules/.pnpm/@pnpm.e2e+pkg-with-events-and-peers@1.0.0_@pnpm.e2e+peer-c@1.0.0/node_modules')
|
const pkgVariation1 = path.resolve('node_modules/.pnpm/@pnpm.e2e+pkg-with-events-and-peers@1.0.0_@pnpm.e2e+peer-c@1.0.0/node_modules')
|
||||||
await okFile(path.join(pkgVariation1, '@pnpm.e2e/pkg-with-events-and-peers', 'generated-by-preinstall.js'))
|
await okFile(path.join(pkgVariation1, '@pnpm.e2e/pkg-with-events-and-peers', 'generated-by-preinstall.js'))
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ test('using side effects cache', async () => {
|
|||||||
sideEffectsCacheRead: true,
|
sideEffectsCacheRead: true,
|
||||||
sideEffectsCacheWrite: true,
|
sideEffectsCacheWrite: true,
|
||||||
verifyStoreIntegrity: false,
|
verifyStoreIntegrity: false,
|
||||||
|
onlyBuiltDependencies: ['@pnpm.e2e/pre-and-postinstall-scripts-example'],
|
||||||
}, {}, {}, { packageImportMethod: 'copy' })
|
}, {}, {}, { packageImportMethod: 'copy' })
|
||||||
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0'], opts)
|
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0'], opts)
|
||||||
|
|
||||||
@@ -111,6 +112,7 @@ test('using side effects cache', async () => {
|
|||||||
sideEffectsCacheWrite: true,
|
sideEffectsCacheWrite: true,
|
||||||
storeDir: opts.storeDir,
|
storeDir: opts.storeDir,
|
||||||
verifyStoreIntegrity: false,
|
verifyStoreIntegrity: false,
|
||||||
|
onlyBuiltDependencies: ['@pnpm.e2e/pre-and-postinstall-scripts-example'],
|
||||||
}, {}, {}, { packageImportMethod: 'copy' })
|
}, {}, {}, { packageImportMethod: 'copy' })
|
||||||
await addDependenciesToPackage(manifest, ['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0'], opts2)
|
await addDependenciesToPackage(manifest, ['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0'], opts2)
|
||||||
|
|
||||||
@@ -159,6 +161,7 @@ test('uploading errors do not interrupt installation', async () => {
|
|||||||
fastUnpack: false,
|
fastUnpack: false,
|
||||||
sideEffectsCacheRead: true,
|
sideEffectsCacheRead: true,
|
||||||
sideEffectsCacheWrite: true,
|
sideEffectsCacheWrite: true,
|
||||||
|
onlyBuiltDependencies: ['@pnpm.e2e/pre-and-postinstall-scripts-example'],
|
||||||
})
|
})
|
||||||
opts.storeController.upload = async () => {
|
opts.storeController.upload = async () => {
|
||||||
throw new Error('an unexpected error')
|
throw new Error('an unexpected error')
|
||||||
@@ -179,6 +182,7 @@ test('a postinstall script does not modify the original sources added to the sto
|
|||||||
fastUnpack: false,
|
fastUnpack: false,
|
||||||
sideEffectsCacheRead: true,
|
sideEffectsCacheRead: true,
|
||||||
sideEffectsCacheWrite: true,
|
sideEffectsCacheWrite: true,
|
||||||
|
onlyBuiltDependencies: ['@pnpm/postinstall-modifies-source'],
|
||||||
}, {}, {}, { packageImportMethod: 'hardlink' })
|
}, {}, {}, { packageImportMethod: 'hardlink' })
|
||||||
await addDependenciesToPackage({}, ['@pnpm/postinstall-modifies-source@1.0.0'], opts)
|
await addDependenciesToPackage({}, ['@pnpm/postinstall-modifies-source@1.0.0'], opts)
|
||||||
|
|
||||||
@@ -211,6 +215,7 @@ test('a corrupted side-effects cache is ignored', async () => {
|
|||||||
fastUnpack: false,
|
fastUnpack: false,
|
||||||
sideEffectsCacheRead: true,
|
sideEffectsCacheRead: true,
|
||||||
sideEffectsCacheWrite: true,
|
sideEffectsCacheWrite: true,
|
||||||
|
onlyBuiltDependencies: ['@pnpm.e2e/pre-and-postinstall-scripts-example'],
|
||||||
})
|
})
|
||||||
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0'], opts)
|
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0'], opts)
|
||||||
|
|
||||||
@@ -242,6 +247,7 @@ test('a corrupted side-effects cache is ignored', async () => {
|
|||||||
sideEffectsCacheRead: true,
|
sideEffectsCacheRead: true,
|
||||||
sideEffectsCacheWrite: true,
|
sideEffectsCacheWrite: true,
|
||||||
storeDir: opts.storeDir,
|
storeDir: opts.storeDir,
|
||||||
|
onlyBuiltDependencies: ['@pnpm.e2e/pre-and-postinstall-scripts-example'],
|
||||||
})
|
})
|
||||||
await install(manifest, opts2)
|
await install(manifest, opts2)
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ export function testDefaults<T> (
|
|||||||
})
|
})
|
||||||
const result = {
|
const result = {
|
||||||
cacheDir,
|
cacheDir,
|
||||||
neverBuiltDependencies: [] as string[],
|
|
||||||
registries: {
|
registries: {
|
||||||
default: registry,
|
default: registry,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -104,10 +104,8 @@ export interface Project {
|
|||||||
|
|
||||||
export interface HeadlessOptions {
|
export interface HeadlessOptions {
|
||||||
ignorePatchFailures?: boolean
|
ignorePatchFailures?: boolean
|
||||||
neverBuiltDependencies?: string[]
|
|
||||||
ignoredBuiltDependencies?: string[]
|
ignoredBuiltDependencies?: string[]
|
||||||
onlyBuiltDependencies?: string[]
|
onlyBuiltDependencies?: string[]
|
||||||
onlyBuiltDependenciesFile?: string
|
|
||||||
autoInstallPeers?: boolean
|
autoInstallPeers?: boolean
|
||||||
childConcurrency?: number
|
childConcurrency?: number
|
||||||
currentLockfile?: LockfileObject
|
currentLockfile?: LockfileObject
|
||||||
|
|||||||
@@ -263,28 +263,41 @@ export async function handler (
|
|||||||
if (opts.argv.original.includes('--allow-build')) {
|
if (opts.argv.original.includes('--allow-build')) {
|
||||||
throw new PnpmError('ALLOW_BUILD_MISSING_PACKAGE', 'The --allow-build flag is missing a package name. Please specify the package name(s) that are allowed to run installation scripts.')
|
throw new PnpmError('ALLOW_BUILD_MISSING_PACKAGE', 'The --allow-build flag is missing a package name. Please specify the package name(s) that are allowed to run installation scripts.')
|
||||||
}
|
}
|
||||||
if (opts.rootProjectManifest?.pnpm?.ignoredBuiltDependencies?.length) {
|
if (opts.rootProjectManifest?.pnpm?.allowBuilds) {
|
||||||
const overlapDependencies = opts.rootProjectManifest.pnpm.ignoredBuiltDependencies.filter((dep) => opts.allowBuild?.includes(dep))
|
const ignoredBuiltDependencies = Object.keys(opts.rootProjectManifest.pnpm.allowBuilds)
|
||||||
|
.filter(pkg => opts.rootProjectManifest!.pnpm!.allowBuilds![pkg] === false)
|
||||||
|
const overlapDependencies = ignoredBuiltDependencies.filter((dep) => opts.allowBuild?.includes(dep))
|
||||||
if (overlapDependencies.length) {
|
if (overlapDependencies.length) {
|
||||||
throw new PnpmError('OVERRIDING_IGNORED_BUILT_DEPENDENCIES', `The following dependencies are ignored by the root project, but are allowed to be built by the current command: ${overlapDependencies.join(', ')}`, {
|
throw new PnpmError('OVERRIDING_IGNORED_BUILT_DEPENDENCIES', `The following dependencies are ignored by the root project, but are allowed to be built by the current command: ${overlapDependencies.join(', ')}`, {
|
||||||
hint: 'If you are sure you want to allow those dependencies to run installation scripts, remove them from the pnpm.ignoredBuiltDependencies list.',
|
hint: 'If you are sure you want to allow those dependencies to run installation scripts, remove them from the pnpm.allowBuilds list (or change their value to true).',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
opts.onlyBuiltDependencies = Array.from(new Set([
|
const allowBuilds: Record<string, boolean> = {}
|
||||||
...(opts.onlyBuiltDependencies ?? []),
|
for (const pkg of opts.allowBuild) {
|
||||||
...opts.allowBuild,
|
allowBuilds[pkg] = true
|
||||||
])).sort((a, b) => a.localeCompare(b))
|
}
|
||||||
if (opts.rootProjectManifestDir) {
|
if (opts.rootProjectManifestDir) {
|
||||||
opts.rootProjectManifest = opts.rootProjectManifest ?? {}
|
opts.rootProjectManifest = opts.rootProjectManifest ?? {}
|
||||||
await writeSettings({
|
await writeSettings({
|
||||||
...opts,
|
...opts,
|
||||||
workspaceDir: opts.workspaceDir ?? opts.rootProjectManifestDir,
|
workspaceDir: opts.workspaceDir ?? opts.rootProjectManifestDir,
|
||||||
updatedSettings: {
|
updatedSettings: {
|
||||||
onlyBuiltDependencies: opts.onlyBuiltDependencies,
|
allowBuilds,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
// Pass the allowed packages to onlyBuiltDependencies so they can build during this install
|
||||||
|
return installDeps({
|
||||||
|
...opts,
|
||||||
|
onlyBuiltDependencies: [
|
||||||
|
...opts.onlyBuiltDependencies ?? [],
|
||||||
|
...opts.allowBuild,
|
||||||
|
],
|
||||||
|
fetchFullMetadata: getFetchFullMetadata(opts),
|
||||||
|
include,
|
||||||
|
includeDirect: include,
|
||||||
|
}, params)
|
||||||
}
|
}
|
||||||
return installDeps({
|
return installDeps({
|
||||||
...opts,
|
...opts,
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ export type InstallDepsOptions = Pick<Config,
|
|||||||
| 'sharedWorkspaceLockfile'
|
| 'sharedWorkspaceLockfile'
|
||||||
| 'shellEmulator'
|
| 'shellEmulator'
|
||||||
| 'tag'
|
| 'tag'
|
||||||
|
| 'onlyBuiltDependencies'
|
||||||
| 'optional'
|
| 'optional'
|
||||||
| 'workspaceConcurrency'
|
| 'workspaceConcurrency'
|
||||||
| 'workspaceDir'
|
| 'workspaceDir'
|
||||||
@@ -212,11 +213,18 @@ when running add/update with the --workspace option')
|
|||||||
linkWorkspacePackages: Boolean(opts.linkWorkspacePackages),
|
linkWorkspacePackages: Boolean(opts.linkWorkspacePackages),
|
||||||
}).graph
|
}).graph
|
||||||
|
|
||||||
|
const recursiveRootManifestOpts = getOptionsFromRootManifest(opts.rootProjectManifestDir, opts.rootProjectManifest ?? {})
|
||||||
await recursiveInstallThenUpdateWorkspaceState(allProjects,
|
await recursiveInstallThenUpdateWorkspaceState(allProjects,
|
||||||
params,
|
params,
|
||||||
{
|
{
|
||||||
...opts,
|
...opts,
|
||||||
...getOptionsFromRootManifest(opts.rootProjectManifestDir, opts.rootProjectManifest ?? {}),
|
...recursiveRootManifestOpts,
|
||||||
|
// Preserve onlyBuiltDependencies from opts if explicitly passed (e.g., from --allow-build flag)
|
||||||
|
// and merge with any from the manifest
|
||||||
|
onlyBuiltDependencies: [
|
||||||
|
...recursiveRootManifestOpts.onlyBuiltDependencies ?? [],
|
||||||
|
...opts.onlyBuiltDependencies ?? [],
|
||||||
|
],
|
||||||
forceHoistPattern,
|
forceHoistPattern,
|
||||||
forcePublicHoistPattern,
|
forcePublicHoistPattern,
|
||||||
allProjectsGraph,
|
allProjectsGraph,
|
||||||
@@ -247,9 +255,16 @@ when running add/update with the --workspace option')
|
|||||||
manifest = {}
|
manifest = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const rootManifestOpts = getOptionsFromRootManifest(opts.dir, (opts.dir === opts.rootProjectManifestDir ? opts.rootProjectManifest ?? manifest : manifest))
|
||||||
const installOpts: Omit<MutateModulesOptions, 'allProjects'> = {
|
const installOpts: Omit<MutateModulesOptions, 'allProjects'> = {
|
||||||
...opts,
|
...opts,
|
||||||
...getOptionsFromRootManifest(opts.dir, (opts.dir === opts.rootProjectManifestDir ? opts.rootProjectManifest ?? manifest : manifest)),
|
...rootManifestOpts,
|
||||||
|
// Preserve onlyBuiltDependencies from opts if explicitly passed (e.g., from --allow-build flag)
|
||||||
|
// and merge with any from the manifest
|
||||||
|
onlyBuiltDependencies: [
|
||||||
|
...rootManifestOpts.onlyBuiltDependencies ?? [],
|
||||||
|
...opts.onlyBuiltDependencies ?? [],
|
||||||
|
],
|
||||||
forceHoistPattern,
|
forceHoistPattern,
|
||||||
forcePublicHoistPattern,
|
forcePublicHoistPattern,
|
||||||
// In case installation is done in a multi-package repository
|
// In case installation is done in a multi-package repository
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ export type RecursiveOptions = CreateStoreControllerOptions & Pick<Config,
|
|||||||
| 'lockfileDir'
|
| 'lockfileDir'
|
||||||
| 'lockfileOnly'
|
| 'lockfileOnly'
|
||||||
| 'modulesDir'
|
| 'modulesDir'
|
||||||
|
| 'onlyBuiltDependencies'
|
||||||
| 'rawLocalConfig'
|
| 'rawLocalConfig'
|
||||||
| 'registries'
|
| 'registries'
|
||||||
| 'rootProjectManifest'
|
| 'rootProjectManifest'
|
||||||
|
|||||||
20
pnpm-lock.yaml
generated
20
pnpm-lock.yaml
generated
@@ -7020,6 +7020,9 @@ importers:
|
|||||||
render-help:
|
render-help:
|
||||||
specifier: 'catalog:'
|
specifier: 'catalog:'
|
||||||
version: 1.0.3
|
version: 1.0.3
|
||||||
|
write-yaml-file:
|
||||||
|
specifier: 'catalog:'
|
||||||
|
version: 5.0.0
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@jest/globals':
|
'@jest/globals':
|
||||||
specifier: 'catalog:'
|
specifier: 'catalog:'
|
||||||
@@ -7048,9 +7051,6 @@ importers:
|
|||||||
'@types/ramda':
|
'@types/ramda':
|
||||||
specifier: 'catalog:'
|
specifier: 'catalog:'
|
||||||
version: 0.29.12
|
version: 0.29.12
|
||||||
write-yaml-file:
|
|
||||||
specifier: 'catalog:'
|
|
||||||
version: 5.0.0
|
|
||||||
|
|
||||||
releasing/plugin-commands-publishing:
|
releasing/plugin-commands-publishing:
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -18412,7 +18412,7 @@ snapshots:
|
|||||||
'@pnpm/fs.packlist': 2.0.0
|
'@pnpm/fs.packlist': 2.0.0
|
||||||
'@pnpm/logger': 1001.0.0
|
'@pnpm/logger': 1001.0.0
|
||||||
'@pnpm/prepare-package': 1000.0.16(@pnpm/logger@1001.0.0)(typanion@3.14.0)
|
'@pnpm/prepare-package': 1000.0.16(@pnpm/logger@1001.0.0)(typanion@3.14.0)
|
||||||
'@pnpm/worker': 1000.1.7(@pnpm/logger@packages+logger)(@types/node@22.15.30)
|
'@pnpm/worker': 1000.1.7(@pnpm/logger@1001.0.0)(@types/node@22.15.30)
|
||||||
'@zkochan/rimraf': 3.0.2
|
'@zkochan/rimraf': 3.0.2
|
||||||
execa: safe-execa@0.1.2
|
execa: safe-execa@0.1.2
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
@@ -18547,7 +18547,7 @@ snapshots:
|
|||||||
'@pnpm/find-workspace-dir': 1000.1.0
|
'@pnpm/find-workspace-dir': 1000.1.0
|
||||||
'@pnpm/logger': 1001.0.0
|
'@pnpm/logger': 1001.0.0
|
||||||
'@pnpm/types': 1000.6.0
|
'@pnpm/types': 1000.6.0
|
||||||
'@pnpm/worker': 1000.1.7(@pnpm/logger@packages+logger)(@types/node@22.15.30)
|
'@pnpm/worker': 1000.1.7(@pnpm/logger@1001.0.0)(@types/node@22.15.30)
|
||||||
'@pnpm/workspace.find-packages': 1000.0.25(@pnpm/logger@1001.0.0)(@pnpm/worker@1000.1.7(@pnpm/logger@1001.0.0)(@types/node@22.15.30))(typanion@3.14.0)
|
'@pnpm/workspace.find-packages': 1000.0.25(@pnpm/logger@1001.0.0)(@pnpm/worker@1000.1.7(@pnpm/logger@1001.0.0)(@types/node@22.15.30))(typanion@3.14.0)
|
||||||
'@pnpm/workspace.read-manifest': 1000.1.5
|
'@pnpm/workspace.read-manifest': 1000.1.5
|
||||||
load-json-file: 7.0.1
|
load-json-file: 7.0.1
|
||||||
@@ -18753,7 +18753,7 @@ snapshots:
|
|||||||
'@pnpm/store-controller-types': 1003.0.2
|
'@pnpm/store-controller-types': 1003.0.2
|
||||||
'@pnpm/store.cafs': 1000.0.13
|
'@pnpm/store.cafs': 1000.0.13
|
||||||
'@pnpm/types': 1000.6.0
|
'@pnpm/types': 1000.6.0
|
||||||
'@pnpm/worker': 1000.1.7(@pnpm/logger@packages+logger)(@types/node@22.15.30)
|
'@pnpm/worker': 1000.1.7(@pnpm/logger@1001.0.0)(@types/node@22.15.30)
|
||||||
p-defer: 3.0.0
|
p-defer: 3.0.0
|
||||||
p-limit: 3.1.0
|
p-limit: 3.1.0
|
||||||
p-queue: 6.6.2
|
p-queue: 6.6.2
|
||||||
@@ -18772,7 +18772,7 @@ snapshots:
|
|||||||
'@pnpm/store-controller-types': 1003.0.2
|
'@pnpm/store-controller-types': 1003.0.2
|
||||||
'@pnpm/store.cafs': 1000.0.13
|
'@pnpm/store.cafs': 1000.0.13
|
||||||
'@pnpm/types': 1000.6.0
|
'@pnpm/types': 1000.6.0
|
||||||
'@pnpm/worker': 1000.1.7(@pnpm/logger@packages+logger)(@types/node@22.15.30)
|
'@pnpm/worker': 1000.1.7(@pnpm/logger@1001.0.0)(@types/node@22.15.30)
|
||||||
'@zkochan/rimraf': 3.0.2
|
'@zkochan/rimraf': 3.0.2
|
||||||
load-json-file: 6.2.0
|
load-json-file: 6.2.0
|
||||||
ramda: '@pnpm/ramda@0.28.1'
|
ramda: '@pnpm/ramda@0.28.1'
|
||||||
@@ -19051,7 +19051,7 @@ snapshots:
|
|||||||
'@pnpm/graceful-fs': 1000.0.0
|
'@pnpm/graceful-fs': 1000.0.0
|
||||||
'@pnpm/logger': 1001.0.0
|
'@pnpm/logger': 1001.0.0
|
||||||
'@pnpm/prepare-package': 1000.0.16(@pnpm/logger@1001.0.0)(typanion@3.14.0)
|
'@pnpm/prepare-package': 1000.0.16(@pnpm/logger@1001.0.0)(typanion@3.14.0)
|
||||||
'@pnpm/worker': 1000.1.7(@pnpm/logger@packages+logger)(@types/node@22.15.30)
|
'@pnpm/worker': 1000.1.7(@pnpm/logger@1001.0.0)(@types/node@22.15.30)
|
||||||
'@zkochan/retry': 0.2.0
|
'@zkochan/retry': 0.2.0
|
||||||
lodash.throttle: 4.1.1
|
lodash.throttle: 4.1.1
|
||||||
p-map-values: 1.0.0
|
p-map-values: 1.0.0
|
||||||
@@ -19090,7 +19090,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
isexe: 2.0.0
|
isexe: 2.0.0
|
||||||
|
|
||||||
'@pnpm/worker@1000.1.7(@pnpm/logger@packages+logger)(@types/node@22.15.30)':
|
'@pnpm/worker@1000.1.7(@pnpm/logger@1001.0.0)(@types/node@22.15.30)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@pnpm/cafs-types': 1000.0.0
|
'@pnpm/cafs-types': 1000.0.0
|
||||||
'@pnpm/create-cafs-store': 1000.0.14(@pnpm/logger@1001.0.0)
|
'@pnpm/create-cafs-store': 1000.0.14(@pnpm/logger@1001.0.0)
|
||||||
@@ -19099,7 +19099,7 @@ snapshots:
|
|||||||
'@pnpm/exec.pkg-requires-build': 1000.0.8
|
'@pnpm/exec.pkg-requires-build': 1000.0.8
|
||||||
'@pnpm/fs.hard-link-dir': 1000.0.1(@pnpm/logger@1001.0.0)
|
'@pnpm/fs.hard-link-dir': 1000.0.1(@pnpm/logger@1001.0.0)
|
||||||
'@pnpm/graceful-fs': 1000.0.0
|
'@pnpm/graceful-fs': 1000.0.0
|
||||||
'@pnpm/logger': link:packages/logger
|
'@pnpm/logger': 1001.0.0
|
||||||
'@pnpm/store.cafs': 1000.0.13
|
'@pnpm/store.cafs': 1000.0.13
|
||||||
'@pnpm/symlink-dependency': 1000.0.9(@pnpm/logger@1001.0.0)
|
'@pnpm/symlink-dependency': 1000.0.9(@pnpm/logger@1001.0.0)
|
||||||
'@rushstack/worker-pool': 0.4.9(@types/node@22.15.30)
|
'@rushstack/worker-pool': 0.4.9(@types/node@22.15.30)
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import { prepare } from '@pnpm/prepare'
|
import { prepare } from '@pnpm/prepare'
|
||||||
import { getIntegrity } from '@pnpm/registry-mock'
|
import { getIntegrity } from '@pnpm/registry-mock'
|
||||||
import { sync as rimraf } from '@zkochan/rimraf'
|
|
||||||
import { sync as readYamlFile } from 'read-yaml-file'
|
import { sync as readYamlFile } from 'read-yaml-file'
|
||||||
import { sync as writeYamlFile } from 'write-yaml-file'
|
import { sync as writeYamlFile } from 'write-yaml-file'
|
||||||
import { execPnpm } from './utils/index.js'
|
import { execPnpm } from './utils/index.js'
|
||||||
@@ -39,56 +38,6 @@ test('patch from configuration dependency is applied via updateConfig hook', asy
|
|||||||
expect(lockfile.patchedDependencies['@pnpm.e2e/foo'].path).toBe('node_modules/.pnpm-config/@pnpm.e2e/has-patch-for-foo/@pnpm.e2e__foo@100.0.0.patch')
|
expect(lockfile.patchedDependencies['@pnpm.e2e/foo'].path).toBe('node_modules/.pnpm-config/@pnpm.e2e/has-patch-for-foo/@pnpm.e2e__foo@100.0.0.patch')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('selectively allow scripts in some dependencies by onlyBuiltDependenciesFile', async () => {
|
|
||||||
prepare({})
|
|
||||||
writeYamlFile('pnpm-workspace.yaml', {
|
|
||||||
configDependencies: {
|
|
||||||
'@pnpm.e2e/build-allow-list': `1.0.0+${getIntegrity('@pnpm.e2e/build-allow-list', '1.0.0')}`,
|
|
||||||
},
|
|
||||||
onlyBuiltDependenciesFile: 'node_modules/.pnpm-config/@pnpm.e2e/build-allow-list/list.json',
|
|
||||||
strictDepBuilds: false,
|
|
||||||
})
|
|
||||||
|
|
||||||
await execPnpm(['add', '@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()
|
|
||||||
|
|
||||||
rimraf('node_modules')
|
|
||||||
|
|
||||||
await execPnpm(['install'])
|
|
||||||
|
|
||||||
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()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('selectively allow scripts in some dependencies by onlyBuiltDependenciesFile and onlyBuiltDependencies', async () => {
|
|
||||||
prepare()
|
|
||||||
writeYamlFile('pnpm-workspace.yaml', {
|
|
||||||
configDependencies: {
|
|
||||||
'@pnpm.e2e/build-allow-list': `1.0.0+${getIntegrity('@pnpm.e2e/build-allow-list', '1.0.0')}`,
|
|
||||||
},
|
|
||||||
onlyBuiltDependenciesFile: 'node_modules/.pnpm-config/@pnpm.e2e/build-allow-list/list.json',
|
|
||||||
onlyBuiltDependencies: ['@pnpm.e2e/pre-and-postinstall-scripts-example'],
|
|
||||||
})
|
|
||||||
|
|
||||||
await execPnpm(['add', '@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')).toBeTruthy()
|
|
||||||
expect(fs.existsSync('node_modules/@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-postinstall.js')).toBeTruthy()
|
|
||||||
expect(fs.existsSync('node_modules/@pnpm.e2e/install-script-example/generated-by-install.js')).toBeTruthy()
|
|
||||||
|
|
||||||
rimraf('node_modules')
|
|
||||||
|
|
||||||
await execPnpm(['install'])
|
|
||||||
|
|
||||||
expect(fs.existsSync('node_modules/@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-preinstall.js')).toBeTruthy()
|
|
||||||
expect(fs.existsSync('node_modules/@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-postinstall.js')).toBeTruthy()
|
|
||||||
expect(fs.existsSync('node_modules/@pnpm.e2e/install-script-example/generated-by-install.js')).toBeTruthy()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('catalog applied by configurational dependency hook', async () => {
|
test('catalog applied by configurational dependency hook', async () => {
|
||||||
const project = prepare({
|
const project = prepare({
|
||||||
dependencies: {
|
dependencies: {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { LAYOUT_VERSION } from '@pnpm/constants'
|
|||||||
import { prepare } from '@pnpm/prepare'
|
import { prepare } from '@pnpm/prepare'
|
||||||
import { type ProjectManifest } from '@pnpm/types'
|
import { type ProjectManifest } from '@pnpm/types'
|
||||||
import isWindows from 'is-windows'
|
import isWindows from 'is-windows'
|
||||||
|
import writeYamlFile from 'write-yaml-file'
|
||||||
import {
|
import {
|
||||||
addDistTag,
|
addDistTag,
|
||||||
execPnpm,
|
execPnpm,
|
||||||
@@ -100,7 +101,12 @@ test('run lifecycle events of global packages in correct working directory', asy
|
|||||||
const pnpmHome = path.join(global, 'pnpm')
|
const pnpmHome = path.join(global, 'pnpm')
|
||||||
const globalPkgDir = path.join(pnpmHome, 'global', String(LAYOUT_VERSION))
|
const globalPkgDir = path.join(pnpmHome, 'global', String(LAYOUT_VERSION))
|
||||||
fs.mkdirSync(globalPkgDir, { recursive: true })
|
fs.mkdirSync(globalPkgDir, { recursive: true })
|
||||||
fs.writeFileSync(path.join(globalPkgDir, 'package.json'), JSON.stringify({ pnpm: { neverBuiltDependencies: [] } }))
|
fs.writeFileSync(path.join(globalPkgDir, 'package.json'), JSON.stringify({}))
|
||||||
|
writeYamlFile.sync(path.join(globalPkgDir, 'pnpm-workspace.yaml'), {
|
||||||
|
allowBuilds: {
|
||||||
|
'@pnpm.e2e/postinstall-calls-pnpm': true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
const env = {
|
const env = {
|
||||||
[PATH_NAME]: `${pnpmHome}${path.delimiter}${process.env[PATH_NAME]!}`,
|
[PATH_NAME]: `${pnpmHome}${path.delimiter}${process.env[PATH_NAME]!}`,
|
||||||
@@ -124,7 +130,7 @@ test.skip('dangerously-allow-all-builds=true in global config', async () => {
|
|||||||
version: '0.0.0',
|
version: '0.0.0',
|
||||||
private: true,
|
private: true,
|
||||||
pnpm: {
|
pnpm: {
|
||||||
onlyBuiltDependencies: [], // don't allow any dependencies to be built
|
allowBuilds: {}, // don't allow any dependencies to be built
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,7 +166,7 @@ test.skip('dangerously-allow-all-builds=true in global config', async () => {
|
|||||||
expect(fs.readdirSync(path.resolve('node_modules/@pnpm.e2e/postinstall-calls-pnpm'))).not.toContain('created-by-postinstall')
|
expect(fs.readdirSync(path.resolve('node_modules/@pnpm.e2e/postinstall-calls-pnpm'))).not.toContain('created-by-postinstall')
|
||||||
|
|
||||||
// global config should be used if local config did not specify
|
// global config should be used if local config did not specify
|
||||||
delete manifest.pnpm!.onlyBuiltDependencies
|
delete manifest.pnpm!.allowBuilds
|
||||||
project.writePackageJson(manifest)
|
project.writePackageJson(manifest)
|
||||||
fs.rmSync('node_modules', { recursive: true })
|
fs.rmSync('node_modules', { recursive: true })
|
||||||
fs.rmSync('pnpm-lock.yaml')
|
fs.rmSync('pnpm-lock.yaml')
|
||||||
@@ -179,7 +185,7 @@ test.skip('dangerously-allow-all-builds=false in global config', async () => {
|
|||||||
version: '0.0.0',
|
version: '0.0.0',
|
||||||
private: true,
|
private: true,
|
||||||
pnpm: {
|
pnpm: {
|
||||||
onlyBuiltDependencies: ['@pnpm.e2e/postinstall-calls-pnpm'],
|
allowBuilds: { '@pnpm.e2e/postinstall-calls-pnpm': true },
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,7 +221,7 @@ test.skip('dangerously-allow-all-builds=false in global config', async () => {
|
|||||||
expect(fs.readdirSync(path.resolve('node_modules/@pnpm.e2e/postinstall-calls-pnpm'))).toContain('created-by-postinstall')
|
expect(fs.readdirSync(path.resolve('node_modules/@pnpm.e2e/postinstall-calls-pnpm'))).toContain('created-by-postinstall')
|
||||||
|
|
||||||
// global config should be used if local config did not specify
|
// global config should be used if local config did not specify
|
||||||
delete manifest.pnpm!.onlyBuiltDependencies
|
delete manifest.pnpm!.allowBuilds
|
||||||
project.writePackageJson(manifest)
|
project.writePackageJson(manifest)
|
||||||
fs.rmSync('node_modules', { recursive: true })
|
fs.rmSync('node_modules', { recursive: true })
|
||||||
fs.rmSync('pnpm-lock.yaml')
|
fs.rmSync('pnpm-lock.yaml')
|
||||||
|
|||||||
@@ -2,12 +2,10 @@ import fs from 'fs'
|
|||||||
import path from 'path'
|
import path from 'path'
|
||||||
import { prepare } from '@pnpm/prepare'
|
import { prepare } from '@pnpm/prepare'
|
||||||
import { type PackageManifest, type ProjectManifest } from '@pnpm/types'
|
import { type PackageManifest, type ProjectManifest } from '@pnpm/types'
|
||||||
import { sync as rimraf } from '@zkochan/rimraf'
|
|
||||||
import PATH from 'path-name'
|
import PATH from 'path-name'
|
||||||
import { loadJsonFileSync } from 'load-json-file'
|
import { loadJsonFileSync } from 'load-json-file'
|
||||||
import writeYamlFile from 'write-yaml-file'
|
import writeYamlFile from 'write-yaml-file'
|
||||||
import { execPnpmSync, pnpmBinLocation } from '../utils/index.js'
|
import { execPnpmSync, pnpmBinLocation } from '../utils/index.js'
|
||||||
import { getIntegrity } from '@pnpm/registry-mock'
|
|
||||||
import { readWorkspaceManifest } from '@pnpm/workspace.read-manifest'
|
import { readWorkspaceManifest } from '@pnpm/workspace.read-manifest'
|
||||||
|
|
||||||
const pkgRoot = path.join(import.meta.dirname, '..', '..')
|
const pkgRoot = path.join(import.meta.dirname, '..', '..')
|
||||||
@@ -108,9 +106,9 @@ test('dependency should not be added to package.json and lockfile if it was not
|
|||||||
const initialPkg = {
|
const initialPkg = {
|
||||||
name: 'foo',
|
name: 'foo',
|
||||||
version: '1.0.0',
|
version: '1.0.0',
|
||||||
pnpm: { neverBuiltDependencies: [] },
|
|
||||||
}
|
}
|
||||||
const project = prepare(initialPkg)
|
const project = prepare(initialPkg)
|
||||||
|
await writeYamlFile('pnpm-workspace.yaml', { allowBuilds: { 'package-that-cannot-be-installed': true } })
|
||||||
|
|
||||||
const result = execPnpmSync(['install', 'package-that-cannot-be-installed@0.0.0'])
|
const result = execPnpmSync(['install', 'package-that-cannot-be-installed@0.0.0'])
|
||||||
|
|
||||||
@@ -145,36 +143,6 @@ test('node-gyp is in the PATH', async () => {
|
|||||||
expect(result.status).toBe(0)
|
expect(result.status).toBe(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('selectively allow scripts in some dependencies by onlyBuiltDependenciesFile', async () => {
|
|
||||||
prepare({
|
|
||||||
pnpm: {
|
|
||||||
configDependencies: {
|
|
||||||
'@pnpm.e2e/build-allow-list': `1.0.0+${getIntegrity('@pnpm.e2e/build-allow-list', '1.0.0')}`,
|
|
||||||
},
|
|
||||||
onlyBuiltDependenciesFile: 'node_modules/.pnpm-config/@pnpm.e2e/build-allow-list/list.json',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
execPnpmSync(['add', '@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()
|
|
||||||
|
|
||||||
rimraf('node_modules')
|
|
||||||
|
|
||||||
execPnpmSync(['install', '--frozen-lockfile'])
|
|
||||||
|
|
||||||
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()
|
|
||||||
|
|
||||||
execPnpmSync(['rebuild'])
|
|
||||||
|
|
||||||
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()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('selectively allow scripts in some dependencies by --allow-build flag', async () => {
|
test('selectively allow scripts in some dependencies by --allow-build flag', async () => {
|
||||||
const project = prepare({})
|
const project = 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'])
|
execPnpmSync(['add', '--allow-build=@pnpm.e2e/install-script-example', '@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0', '@pnpm.e2e/install-script-example'])
|
||||||
@@ -183,10 +151,7 @@ test('selectively allow scripts in some dependencies by --allow-build flag', asy
|
|||||||
expect(fs.existsSync('node_modules/@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-postinstall.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()
|
expect(fs.existsSync('node_modules/@pnpm.e2e/install-script-example/generated-by-install.js')).toBeTruthy()
|
||||||
|
|
||||||
const manifest = loadJsonFileSync<ProjectManifest>('package.json')
|
|
||||||
expect(manifest.pnpm?.onlyBuiltDependencies).toBeUndefined()
|
|
||||||
const modulesManifest = await readWorkspaceManifest(project.dir())
|
const modulesManifest = await readWorkspaceManifest(project.dir())
|
||||||
expect(modulesManifest?.onlyBuiltDependencies).toBeUndefined()
|
|
||||||
expect(modulesManifest?.allowBuilds).toStrictEqual({ '@pnpm.e2e/install-script-example': true })
|
expect(modulesManifest?.allowBuilds).toStrictEqual({ '@pnpm.e2e/install-script-example': true })
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -201,22 +166,8 @@ test('--allow-build flag should specify the package', async () => {
|
|||||||
expect(fs.existsSync('node_modules/@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-postinstall.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')).toBeFalsy()
|
expect(fs.existsSync('node_modules/@pnpm.e2e/install-script-example/generated-by-install.js')).toBeFalsy()
|
||||||
|
|
||||||
const manifest = loadJsonFileSync<ProjectManifest>('package.json')
|
|
||||||
expect(manifest.pnpm?.onlyBuiltDependencies).toBeUndefined()
|
|
||||||
const modulesManifest = await readWorkspaceManifest(project.dir())
|
const modulesManifest = await readWorkspaceManifest(project.dir())
|
||||||
expect(modulesManifest?.onlyBuiltDependencies).toBeUndefined()
|
expect(modulesManifest?.allowBuilds).toBeUndefined()
|
||||||
})
|
|
||||||
|
|
||||||
test('selectively allow scripts in some dependencies by --allow-build flag overlap ignoredBuiltDependencies', async () => {
|
|
||||||
prepare({
|
|
||||||
pnpm: {
|
|
||||||
ignoredBuiltDependencies: ['@pnpm.e2e/install-script-example'],
|
|
||||||
},
|
|
||||||
})
|
|
||||||
const result = 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(result.status).toBe(1)
|
|
||||||
expect(result.stdout.toString()).toContain('The following dependencies are ignored by the root project, but are allowed to be built by the current command: @pnpm.e2e/install-script-example')
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test('preinstall script does not trigger verify-deps-before-run (#8954)', async () => {
|
test('preinstall script does not trigger verify-deps-before-run (#8954)', async () => {
|
||||||
@@ -310,3 +261,15 @@ test('git dependencies with preparation scripts should be installed when dangero
|
|||||||
expect(result.status).toBe(0)
|
expect(result.status).toBe(0)
|
||||||
expect(fs.existsSync('node_modules/test-git-fetch/dist/index.js')).toBeTruthy()
|
expect(fs.existsSync('node_modules/test-git-fetch/dist/index.js')).toBeTruthy()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('--allow-build flag should error when conflicting with allowBuilds: false', async () => {
|
||||||
|
prepare({
|
||||||
|
pnpm: {
|
||||||
|
allowBuilds: { '@pnpm.e2e/install-script-example': false },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const result = 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(result.status).toBe(1)
|
||||||
|
expect(result.stdout.toString()).toContain('The following dependencies are ignored by the root project, but are allowed to be built by the current command: @pnpm.e2e/install-script-example')
|
||||||
|
})
|
||||||
|
|||||||
@@ -1251,11 +1251,7 @@ test('dependencies of workspace projects are built during headless installation'
|
|||||||
const projects = preparePackages([
|
const projects = preparePackages([
|
||||||
{
|
{
|
||||||
location: '.',
|
location: '.',
|
||||||
package: {
|
package: {},
|
||||||
pnpm: {
|
|
||||||
neverBuiltDependencies: [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'project-1',
|
name: 'project-1',
|
||||||
@@ -1270,6 +1266,9 @@ test('dependencies of workspace projects are built during headless installation'
|
|||||||
writeYamlFile('pnpm-workspace.yaml', {
|
writeYamlFile('pnpm-workspace.yaml', {
|
||||||
packages: ['**', '!store/**'],
|
packages: ['**', '!store/**'],
|
||||||
sharedWorkspaceLockfile: false,
|
sharedWorkspaceLockfile: false,
|
||||||
|
allowBuilds: {
|
||||||
|
'@pnpm.e2e/pre-and-postinstall-scripts-example': true,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
await execPnpm(['install', '--lockfile-only'])
|
await execPnpm(['install', '--lockfile-only'])
|
||||||
@@ -1890,9 +1889,6 @@ test('deploy should keep files created by lifecycle scripts', async () => {
|
|||||||
name: 'root',
|
name: 'root',
|
||||||
version: '0.0.0',
|
version: '0.0.0',
|
||||||
private: true,
|
private: true,
|
||||||
pnpm: {
|
|
||||||
neverBuiltDependencies: [],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
'project-0': {
|
'project-0': {
|
||||||
name: 'project-0',
|
name: 'project-0',
|
||||||
@@ -1914,6 +1910,9 @@ test('deploy should keep files created by lifecycle scripts', async () => {
|
|||||||
writeYamlFile('pnpm-workspace.yaml', {
|
writeYamlFile('pnpm-workspace.yaml', {
|
||||||
packages: ['**', '!store/**'],
|
packages: ['**', '!store/**'],
|
||||||
injectWorkspacePackages: true,
|
injectWorkspacePackages: true,
|
||||||
|
allowBuilds: {
|
||||||
|
'@pnpm.e2e/install-script-example': true,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const monorepoRoot = process.cwd()
|
const monorepoRoot = process.cwd()
|
||||||
@@ -1941,9 +1940,6 @@ test('rebuild in a directory created with "pnpm deploy" and with "pnpm.neverBuil
|
|||||||
name: 'root',
|
name: 'root',
|
||||||
version: '0.0.0',
|
version: '0.0.0',
|
||||||
private: true,
|
private: true,
|
||||||
pnpm: {
|
|
||||||
neverBuiltDependencies: [],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
'project-0': {
|
'project-0': {
|
||||||
name: 'project-0',
|
name: 'project-0',
|
||||||
@@ -1965,6 +1961,9 @@ test('rebuild in a directory created with "pnpm deploy" and with "pnpm.neverBuil
|
|||||||
writeYamlFile('pnpm-workspace.yaml', {
|
writeYamlFile('pnpm-workspace.yaml', {
|
||||||
packages: ['**', '!store/**'],
|
packages: ['**', '!store/**'],
|
||||||
injectWorkspacePackages: true,
|
injectWorkspacePackages: true,
|
||||||
|
allowBuilds: {
|
||||||
|
'@pnpm.e2e/install-script-example': true,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const monorepoRoot = process.cwd()
|
const monorepoRoot = process.cwd()
|
||||||
|
|||||||
@@ -5,11 +5,7 @@ test('`pnpm recursive rebuild` specific dependencies', async () => {
|
|||||||
const projects = preparePackages([
|
const projects = preparePackages([
|
||||||
{
|
{
|
||||||
location: '.',
|
location: '.',
|
||||||
package: {
|
package: {},
|
||||||
pnpm: {
|
|
||||||
neverBuiltDependencies: [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'project-1',
|
name: 'project-1',
|
||||||
@@ -42,7 +38,7 @@ test('`pnpm recursive rebuild` specific dependencies', async () => {
|
|||||||
projects['project-2'].hasNot('@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-preinstall.js')
|
projects['project-2'].hasNot('@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-preinstall.js')
|
||||||
projects['project-2'].hasNot('@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-postinstall.js')
|
projects['project-2'].hasNot('@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-postinstall.js')
|
||||||
|
|
||||||
await execPnpm(['recursive', 'rebuild', 'install-scripts-example-for-pnpm'])
|
await execPnpm(['recursive', 'rebuild', 'install-scripts-example-for-pnpm', '--config.dangerouslyAllowAllBuilds=true'])
|
||||||
|
|
||||||
projects['project-1'].hasNot('@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-preinstall.js')
|
projects['project-1'].hasNot('@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-preinstall.js')
|
||||||
projects['project-1'].hasNot('@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-postinstall.js')
|
projects['project-1'].hasNot('@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-postinstall.js')
|
||||||
|
|||||||
@@ -49,7 +49,8 @@
|
|||||||
"@zkochan/rimraf": "catalog:",
|
"@zkochan/rimraf": "catalog:",
|
||||||
"normalize-path": "catalog:",
|
"normalize-path": "catalog:",
|
||||||
"ramda": "catalog:",
|
"ramda": "catalog:",
|
||||||
"render-help": "catalog:"
|
"render-help": "catalog:",
|
||||||
|
"write-yaml-file": "catalog:"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@pnpm/logger": "catalog:"
|
"@pnpm/logger": "catalog:"
|
||||||
@@ -63,8 +64,7 @@
|
|||||||
"@pnpm/registry-mock": "catalog:",
|
"@pnpm/registry-mock": "catalog:",
|
||||||
"@pnpm/test-fixtures": "workspace:*",
|
"@pnpm/test-fixtures": "workspace:*",
|
||||||
"@pnpm/workspace.filter-packages-from-dir": "workspace:*",
|
"@pnpm/workspace.filter-packages-from-dir": "workspace:*",
|
||||||
"@types/ramda": "catalog:",
|
"@types/ramda": "catalog:"
|
||||||
"write-yaml-file": "catalog:"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=20.19"
|
"node": ">=20.19"
|
||||||
|
|||||||
@@ -30,11 +30,17 @@ export interface CreateDeployFilesOptions {
|
|||||||
selectedProjectManifest: ProjectManifest
|
selectedProjectManifest: ProjectManifest
|
||||||
projectId: ProjectId
|
projectId: ProjectId
|
||||||
rootProjectManifestDir: string
|
rootProjectManifestDir: string
|
||||||
|
allowBuilds?: Record<string, boolean | string>
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DeployWorkspaceManifest {
|
||||||
|
allowBuilds?: Record<string, boolean | string>
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DeployFiles {
|
export interface DeployFiles {
|
||||||
lockfile: LockfileObject
|
lockfile: LockfileObject
|
||||||
manifest: ProjectManifest
|
manifest: ProjectManifest
|
||||||
|
workspaceManifest?: DeployWorkspaceManifest
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createDeployFiles ({
|
export function createDeployFiles ({
|
||||||
@@ -46,6 +52,7 @@ export function createDeployFiles ({
|
|||||||
selectedProjectManifest,
|
selectedProjectManifest,
|
||||||
projectId,
|
projectId,
|
||||||
rootProjectManifestDir,
|
rootProjectManifestDir,
|
||||||
|
allowBuilds,
|
||||||
}: CreateDeployFilesOptions): DeployFiles {
|
}: CreateDeployFilesOptions): DeployFiles {
|
||||||
const deployedProjectRealPath = path.resolve(lockfileDir, projectId)
|
const deployedProjectRealPath = path.resolve(lockfileDir, projectId)
|
||||||
const inputSnapshot = lockfile.importers[projectId]
|
const inputSnapshot = lockfile.importers[projectId]
|
||||||
@@ -160,6 +167,12 @@ export function createDeployFiles ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (allowBuilds) {
|
||||||
|
result.workspaceManifest = {
|
||||||
|
allowBuilds,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import path from 'path'
|
|||||||
import { pick } from 'ramda'
|
import { pick } from 'ramda'
|
||||||
import { docsUrl } from '@pnpm/cli-utils'
|
import { docsUrl } from '@pnpm/cli-utils'
|
||||||
import { type Config, types as configTypes } from '@pnpm/config'
|
import { type Config, types as configTypes } from '@pnpm/config'
|
||||||
|
import { WORKSPACE_MANIFEST_FILENAME } from '@pnpm/constants'
|
||||||
import { fetchFromDir } from '@pnpm/directory-fetcher'
|
import { fetchFromDir } from '@pnpm/directory-fetcher'
|
||||||
import { createIndexedPkgImporter } from '@pnpm/fs.indexed-pkg-importer'
|
import { createIndexedPkgImporter } from '@pnpm/fs.indexed-pkg-importer'
|
||||||
import { isEmptyDirOrNothing } from '@pnpm/fs.is-empty-dir-or-nothing'
|
import { isEmptyDirOrNothing } from '@pnpm/fs.is-empty-dir-or-nothing'
|
||||||
@@ -12,6 +13,7 @@ import { PnpmError } from '@pnpm/error'
|
|||||||
import { getLockfileImporterId, readWantedLockfile, writeWantedLockfile } from '@pnpm/lockfile.fs'
|
import { getLockfileImporterId, readWantedLockfile, writeWantedLockfile } from '@pnpm/lockfile.fs'
|
||||||
import rimraf from '@zkochan/rimraf'
|
import rimraf from '@zkochan/rimraf'
|
||||||
import renderHelp from 'render-help'
|
import renderHelp from 'render-help'
|
||||||
|
import writeYamlFile from 'write-yaml-file'
|
||||||
import { deployHook } from './deployHook.js'
|
import { deployHook } from './deployHook.js'
|
||||||
import { logger, globalWarn } from '@pnpm/logger'
|
import { logger, globalWarn } from '@pnpm/logger'
|
||||||
import { type Project } from '@pnpm/types'
|
import { type Project } from '@pnpm/types'
|
||||||
@@ -78,7 +80,7 @@ export function help (): string {
|
|||||||
|
|
||||||
export type DeployOptions =
|
export type DeployOptions =
|
||||||
& Omit<install.InstallCommandOptions, 'useLockfile'>
|
& Omit<install.InstallCommandOptions, 'useLockfile'>
|
||||||
& Pick<Config, 'forceLegacyDeploy'>
|
& Pick<Config, 'allowBuilds' | 'forceLegacyDeploy'>
|
||||||
|
|
||||||
export async function handler (opts: DeployOptions, params: string[]): Promise<void> {
|
export async function handler (opts: DeployOptions, params: string[]): Promise<void> {
|
||||||
if (!opts.workspaceDir) {
|
if (!opts.workspaceDir) {
|
||||||
@@ -240,15 +242,22 @@ async function deployFromSharedLockfile (
|
|||||||
selectedProjectManifest: selectedProject.manifest,
|
selectedProjectManifest: selectedProject.manifest,
|
||||||
projectId,
|
projectId,
|
||||||
rootProjectManifestDir,
|
rootProjectManifestDir,
|
||||||
|
allowBuilds: opts.allowBuilds,
|
||||||
})
|
})
|
||||||
|
|
||||||
await Promise.all([
|
const filesToWrite: Array<Promise<void>> = [
|
||||||
fs.promises.writeFile(
|
fs.promises.writeFile(
|
||||||
path.join(deployDir, 'package.json'),
|
path.join(deployDir, 'package.json'),
|
||||||
JSON.stringify(deployFiles.manifest, undefined, 2) + '\n'
|
JSON.stringify(deployFiles.manifest, undefined, 2) + '\n'
|
||||||
),
|
),
|
||||||
writeWantedLockfile(deployDir, deployFiles.lockfile),
|
writeWantedLockfile(deployDir, deployFiles.lockfile),
|
||||||
])
|
]
|
||||||
|
if (deployFiles.workspaceManifest) {
|
||||||
|
filesToWrite.push(
|
||||||
|
writeYamlFile(path.join(deployDir, WORKSPACE_MANIFEST_FILENAME), deployFiles.workspaceManifest)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
await Promise.all(filesToWrite)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await install.handler({
|
await install.handler({
|
||||||
|
|||||||
@@ -278,7 +278,7 @@ test('the deploy manifest should inherit some fields from the pnpm object from t
|
|||||||
version: '0.0.0',
|
version: '0.0.0',
|
||||||
private: true,
|
private: true,
|
||||||
pnpm: {
|
pnpm: {
|
||||||
onlyBuiltDependencies: ['from-root'],
|
allowBuilds: { 'from-root': true },
|
||||||
overrides: {
|
overrides: {
|
||||||
'is-positive': '2.0.0',
|
'is-positive': '2.0.0',
|
||||||
},
|
},
|
||||||
@@ -292,7 +292,7 @@ test('the deploy manifest should inherit some fields from the pnpm object from t
|
|||||||
'is-positive': '3.1.0',
|
'is-positive': '3.1.0',
|
||||||
},
|
},
|
||||||
pnpm: {
|
pnpm: {
|
||||||
onlyBuiltDependencies: ['from-project-0'],
|
allowBuilds: { 'from-project-0': true },
|
||||||
overrides: {
|
overrides: {
|
||||||
'is-positive': '=1.0.0',
|
'is-positive': '=1.0.0',
|
||||||
},
|
},
|
||||||
@@ -344,7 +344,7 @@ test('the deploy manifest should inherit some fields from the pnpm object from t
|
|||||||
|
|
||||||
const manifest = readPackageJson('deploy') as ProjectManifest
|
const manifest = readPackageJson('deploy') as ProjectManifest
|
||||||
expect(manifest.pnpm).toStrictEqual({
|
expect(manifest.pnpm).toStrictEqual({
|
||||||
onlyBuiltDependencies: preparedManifests.root.pnpm!.onlyBuiltDependencies,
|
allowBuilds: preparedManifests.root.pnpm!.allowBuilds,
|
||||||
} as ProjectManifest['pnpm'])
|
} as ProjectManifest['pnpm'])
|
||||||
|
|
||||||
expect(readPackageJson('deploy/node_modules/is-positive/')).toHaveProperty(['version'], preparedManifests.root.pnpm!.overrides!['is-positive'])
|
expect(readPackageJson('deploy/node_modules/is-positive/')).toHaveProperty(['version'], preparedManifests.root.pnpm!.overrides!['is-positive'])
|
||||||
@@ -1079,9 +1079,6 @@ test('deploy with a shared lockfile should keep files created by lifecycle scrip
|
|||||||
name: 'root',
|
name: 'root',
|
||||||
version: '0.0.0',
|
version: '0.0.0',
|
||||||
private: true,
|
private: true,
|
||||||
pnpm: {
|
|
||||||
neverBuiltDependencies: [],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
'project-0': {
|
'project-0': {
|
||||||
name: 'project-0',
|
name: 'project-0',
|
||||||
@@ -1117,6 +1114,7 @@ test('deploy with a shared lockfile should keep files created by lifecycle scrip
|
|||||||
rootProjectManifestDir: process.cwd(),
|
rootProjectManifestDir: process.cwd(),
|
||||||
recursive: true,
|
recursive: true,
|
||||||
lockfileDir: process.cwd(),
|
lockfileDir: process.cwd(),
|
||||||
|
onlyBuiltDependencies: ['@pnpm.e2e/install-script-example'],
|
||||||
workspaceDir: process.cwd(),
|
workspaceDir: process.cwd(),
|
||||||
})
|
})
|
||||||
expect(fs.existsSync('pnpm-lock.yaml')).toBeTruthy()
|
expect(fs.existsSync('pnpm-lock.yaml')).toBeTruthy()
|
||||||
@@ -1132,6 +1130,7 @@ test('deploy with a shared lockfile should keep files created by lifecycle scrip
|
|||||||
selectedProjectsGraph,
|
selectedProjectsGraph,
|
||||||
sharedWorkspaceLockfile: true,
|
sharedWorkspaceLockfile: true,
|
||||||
lockfileDir: process.cwd(),
|
lockfileDir: process.cwd(),
|
||||||
|
onlyBuiltDependencies: ['@pnpm.e2e/install-script-example'],
|
||||||
workspaceDir: process.cwd(),
|
workspaceDir: process.cwd(),
|
||||||
}, ['deploy'])
|
}, ['deploy'])
|
||||||
|
|
||||||
|
|||||||
@@ -45,32 +45,7 @@ export async function updateWorkspaceManifest (dir: string, opts: {
|
|||||||
shouldBeUpdated = removePackagesFromWorkspaceCatalog(manifest, opts.allProjects ?? []) || shouldBeUpdated
|
shouldBeUpdated = removePackagesFromWorkspaceCatalog(manifest, opts.allProjects ?? []) || shouldBeUpdated
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the current manifest has allowBuilds, convert old fields to allowBuilds format
|
|
||||||
const updatedFields = { ...opts.updatedFields }
|
const updatedFields = { ...opts.updatedFields }
|
||||||
if (manifest.allowBuilds != null || (manifest.onlyBuiltDependencies == null && manifest.ignoredBuiltDependencies == null)) {
|
|
||||||
const allowBuilds: Record<string, boolean | string> = { ...manifest.allowBuilds }
|
|
||||||
|
|
||||||
// Convert onlyBuiltDependencies to allowBuilds with true values
|
|
||||||
if (updatedFields.onlyBuiltDependencies != null) {
|
|
||||||
for (const pattern of updatedFields.onlyBuiltDependencies) {
|
|
||||||
allowBuilds[pattern] = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert ignoredBuiltDependencies to allowBuilds with false values
|
|
||||||
if (updatedFields.ignoredBuiltDependencies != null) {
|
|
||||||
for (const pattern of updatedFields.ignoredBuiltDependencies) {
|
|
||||||
allowBuilds[pattern] = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update allowBuilds instead of the old fields
|
|
||||||
if (manifest.allowBuilds != null || Object.keys(allowBuilds).length > 0) {
|
|
||||||
updatedFields.allowBuilds = allowBuilds
|
|
||||||
}
|
|
||||||
delete updatedFields.onlyBuiltDependencies
|
|
||||||
delete updatedFields.ignoredBuiltDependencies
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const [key, value] of Object.entries(updatedFields)) {
|
for (const [key, value] of Object.entries(updatedFields)) {
|
||||||
if (!equals(manifest[key as keyof WorkspaceManifest], value)) {
|
if (!equals(manifest[key as keyof WorkspaceManifest], value)) {
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ import { sync as writeYamlFile } from 'write-yaml-file'
|
|||||||
test('updateWorkspaceManifest adds a new setting', async () => {
|
test('updateWorkspaceManifest adds a new setting', async () => {
|
||||||
const dir = tempDir(false)
|
const dir = tempDir(false)
|
||||||
const filePath = path.join(dir, WORKSPACE_MANIFEST_FILENAME)
|
const filePath = path.join(dir, WORKSPACE_MANIFEST_FILENAME)
|
||||||
writeYamlFile(filePath, { packages: ['*'], onlyBuiltDependencies: [] })
|
writeYamlFile(filePath, { packages: ['*'], allowBuilds: {} })
|
||||||
await updateWorkspaceManifest(dir, {
|
await updateWorkspaceManifest(dir, {
|
||||||
updatedFields: { onlyBuiltDependencies: [] },
|
updatedFields: { allowBuilds: {} },
|
||||||
})
|
})
|
||||||
expect(readYamlFile(filePath)).toStrictEqual({
|
expect(readYamlFile(filePath)).toStrictEqual({
|
||||||
packages: ['*'],
|
packages: ['*'],
|
||||||
onlyBuiltDependencies: [],
|
allowBuilds: {},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -48,14 +48,13 @@ test('updateWorkspaceManifest updates allowBuilds', async () => {
|
|||||||
const filePath = path.join(dir, WORKSPACE_MANIFEST_FILENAME)
|
const filePath = path.join(dir, WORKSPACE_MANIFEST_FILENAME)
|
||||||
writeYamlFile(filePath, { packages: ['*'], allowBuilds: { qar: 'warn' } })
|
writeYamlFile(filePath, { packages: ['*'], allowBuilds: { qar: 'warn' } })
|
||||||
await updateWorkspaceManifest(dir, {
|
await updateWorkspaceManifest(dir, {
|
||||||
updatedFields: { onlyBuiltDependencies: ['foo'], ignoredBuiltDependencies: ['bar'] },
|
updatedFields: { allowBuilds: { foo: true, bar: false } },
|
||||||
})
|
})
|
||||||
expect(readYamlFile(filePath)).toStrictEqual({
|
expect(readYamlFile(filePath)).toStrictEqual({
|
||||||
packages: ['*'],
|
packages: ['*'],
|
||||||
allowBuilds: {
|
allowBuilds: {
|
||||||
bar: false,
|
bar: false,
|
||||||
foo: true,
|
foo: true,
|
||||||
qar: 'warn',
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user