feat: set hoisting limits (#4300)

This commit is contained in:
Zoltan Kochan
2022-02-05 13:23:58 +02:00
committed by GitHub
parent 7ae349cd3f
commit 329e186e9e
7 changed files with 44 additions and 4 deletions

View File

@@ -0,0 +1,7 @@
---
"@pnpm/core": minor
"@pnpm/headless": minor
"@pnpm/real-hoist": patch
---
Allow to set hoistingLimits for the hoisted node linker.

View File

@@ -6,6 +6,7 @@ export {
PeerDependencyIssues,
PeerDependencyIssuesByProjects,
} from '@pnpm/types'
export { HoistingLimits } from '@pnpm/headless'
export * from './api'
export { ProjectOptions, UnexpectedStoreError, UnexpectedVirtualStoreDirError } from '@pnpm/get-context'

View File

@@ -1,5 +1,6 @@
import { WANTED_LOCKFILE } from '@pnpm/constants'
import PnpmError from '@pnpm/error'
import { HoistingLimits } from '@pnpm/headless'
import { Lockfile } from '@pnpm/lockfile-file'
import { IncludedDependencies } from '@pnpm/modules-yaml'
import normalizeRegistries, { DEFAULT_REGISTRIES } from '@pnpm/normalize-registries'
@@ -21,6 +22,7 @@ export interface StrictInstallOptions {
enablePnp: boolean
extendNodePath: boolean
extraBinPaths: string[]
hoistingLimits?: HoistingLimits
useLockfile: boolean
linkWorkspacePackagesDepth: number
lockfileOnly: boolean

View File

@@ -198,3 +198,21 @@ test('running install scripts in a workspace that has no root project', async ()
expect(fs.existsSync('node_modules/pre-and-postinstall-scripts-example/generated-by-preinstall.js')).toBeTruthy()
})
test('hoistingLimits should prevent packages to be hoisted', async () => {
prepareEmpty()
const hoistingLimits = new Map()
hoistingLimits.set('.@', new Set(['send']))
await install({
dependencies: {
send: '0.17.2',
},
}, await testDefaults({
nodeLinker: 'hoisted',
hoistingLimits,
}))
expect(fs.existsSync('node_modules/ms')).toBeFalsy()
expect(fs.existsSync('node_modules/send/node_modules/ms')).toBeTruthy()
})

View File

@@ -46,6 +46,7 @@ import {
IncludedDependencies,
write as writeModulesYaml,
} from '@pnpm/modules-yaml'
import { HoistingLimits } from '@pnpm/real-hoist'
import { fromDir as readPackageFromDir } from '@pnpm/read-package-json'
import { readProjectManifestOnly, safeReadProjectManifestOnly } from '@pnpm/read-project-manifest'
import {
@@ -73,6 +74,8 @@ import lockfileToDepGraph, {
} from './lockfileToDepGraph'
import lockfileToHoistedDepGraph from './lockfileToHoistedDepGraph'
export { HoistingLimits }
export type ReporterFunction = (logObj: LogBase) => void
export interface Project {
@@ -96,6 +99,7 @@ export interface HeadlessOptions {
engineStrict: boolean
extendNodePath?: boolean
extraBinPaths?: string[]
hoistingLimits?: HoistingLimits
ignoreScripts: boolean
ignorePackageManifest?: boolean
include: IncludedDependencies

View File

@@ -16,7 +16,7 @@ import {
FetchPackageToStoreFunction,
StoreController,
} from '@pnpm/store-controller-types'
import hoist, { HoisterResult } from '@pnpm/real-hoist'
import hoist, { HoistingLimits, HoisterResult } from '@pnpm/real-hoist'
import * as dp from 'dependency-path'
import {
DependenciesGraph,
@@ -28,6 +28,7 @@ import {
export interface LockfileToHoistedDepGraphOptions {
engineStrict: boolean
force: boolean
hoistingLimits?: HoistingLimits
importerIds: string[]
include: IncludedDependencies
lockfileDir: string
@@ -62,7 +63,7 @@ async function _lockfileToHoistedDepGraph (
lockfile: Lockfile,
opts: LockfileToHoistedDepGraphOptions
): Promise<Omit<LockfileToDepGraphResult, 'prevGraph'>> {
const tree = hoist(lockfile)
const tree = hoist(lockfile, { hoistingLimits: opts.hoistingLimits })
const graph: DependenciesGraph = {}
const modulesDir = path.join(opts.lockfileDir, 'node_modules')
const fetchDepsOpts = {

View File

@@ -5,9 +5,16 @@ import {
import * as dp from 'dependency-path'
import { hoist, HoisterDependencyKind, HoisterTree, HoisterResult } from '@yarnpkg/nm/lib/hoist'
export type HoistingLimits = Map<string, Set<string>>
export { HoisterResult }
export default function hoistByLockfile (lockfile: Lockfile): HoisterResult {
export default function hoistByLockfile (
lockfile: Lockfile,
opts?: {
hoistingLimits?: HoistingLimits
}
): HoisterResult {
const nodes = new Map<string, HoisterTree>()
const node: HoisterTree = {
name: '.',
@@ -38,7 +45,7 @@ export default function hoistByLockfile (lockfile: Lockfile): HoisterResult {
node.dependencies.add(importerNode)
}
return hoist(node)
return hoist(node, opts)
}
function toTree (nodes: Map<string, HoisterTree>, lockfile: Lockfile, deps: Record<string, string>): Set<HoisterTree> {