Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

node-linker=hoisted support autoinstallpeers #6680

Merged
merged 3 commits into from
Jun 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/quiet-moons-sparkle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@pnpm/real-hoist": patch
"@pnpm/headless": patch
"pnpm": patch
---

Peer dependencies of subdependencies should be installed, when `node-linker` is set to `hoisted` [#6680](https://github.com/pnpm/pnpm/pull/6680).
14 changes: 14 additions & 0 deletions pkg-manager/core/test/hoistedNodeLinker/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -316,3 +316,17 @@ test('linking bins of local projects when node-linker is set to hoisted', async

expect(fs.existsSync('project-1/node_modules/.bin/project-2')).toBeTruthy()
})

test('peerDependencies should be installed when autoInstallPeers is set to true and nodeLinker is set to hoisted', async () => {
prepareEmpty()
await install({
dependencies: {
'react-dom': '18.2.0',
},
}, await testDefaults({
nodeLinker: 'hoisted',
autoInstallPeers: true,
}))

expect(fs.existsSync('node_modules/react')).toBeTruthy()
})
1 change: 1 addition & 0 deletions pkg-manager/headless/src/lockfileToDepGraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export interface DependenciesGraph {
}

export interface LockfileToDepGraphOptions {
autoInstallPeers: boolean
engineStrict: boolean
force: boolean
importerIds: string[]
Expand Down
7 changes: 6 additions & 1 deletion pkg-manager/headless/src/lockfileToHoistedDepGraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
} from './lockfileToDepGraph'

export interface LockfileToHoistedDepGraphOptions {
autoInstallPeers: boolean
engineStrict: boolean
force: boolean
hoistingLimits?: HoistingLimits
Expand Down Expand Up @@ -68,7 +69,11 @@ async function _lockfileToHoistedDepGraph (
lockfile: Lockfile,
opts: LockfileToHoistedDepGraphOptions
): Promise<Omit<LockfileToDepGraphResult, 'prevGraph'>> {
const tree = hoist(lockfile, { hoistingLimits: opts.hoistingLimits, externalDependencies: opts.externalDependencies })
const tree = hoist(lockfile, {
hoistingLimits: opts.hoistingLimits,
externalDependencies: opts.externalDependencies,
autoInstallPeers: opts.autoInstallPeers,
})
const graph: DependenciesGraph = {}
const modulesDir = path.join(opts.lockfileDir, 'node_modules')
const fetchDepsOpts = {
Expand Down
22 changes: 15 additions & 7 deletions pkg-manager/real-hoist/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export function hoist (
// This option was added for Bit CLI in order to prevent pnpm from overwriting dependencies linked by Bit.
// However, in the future it might be useful to use it in pnpm for skipping any dependencies added by external tools.
externalDependencies?: Set<string>
autoInstallPeers?: boolean
}
): HoisterResult {
const nodes = new Map<string, HoisterTree>()
Expand All @@ -37,7 +38,7 @@ export function hoist (
acc[dep] = 'link:'
return acc
}, {} as Record<string, string>),
}),
}, opts?.autoInstallPeers),
}
for (const [importerId, importer] of Object.entries(lockfile.importers)) {
if (importerId === '.') continue
Expand All @@ -51,7 +52,7 @@ export function hoist (
...importer.dependencies,
...importer.devDependencies,
...importer.optionalDependencies,
}),
}, opts?.autoInstallPeers),
}
node.dependencies.add(importerNode)
}
Expand All @@ -67,7 +68,12 @@ export function hoist (
return hoisterResult
}

function toTree (nodes: Map<string, HoisterTree>, lockfile: Lockfile, deps: Record<string, string>): Set<HoisterTree> {
function toTree (
nodes: Map<string, HoisterTree>,
lockfile: Lockfile,
deps: Record<string, string>,
autoInstallPeers?: boolean
): Set<HoisterTree> {
return new Set(Object.entries(deps).map(([alias, ref]) => {
const depPath = dp.refToRelative(ref, alias)!
if (!depPath) {
Expand Down Expand Up @@ -100,10 +106,12 @@ function toTree (nodes: Map<string, HoisterTree>, lockfile: Lockfile, deps: Reco
reference: depPath,
dependencyKind: HoisterDependencyKind.REGULAR,
dependencies: new Set(),
peerNames: new Set([
...Object.keys(pkgSnapshot.peerDependencies ?? {}),
...(pkgSnapshot.transitivePeerDependencies ?? []),
]),
peerNames: new Set(autoInstallPeers
? []
: [
...Object.keys(pkgSnapshot.peerDependencies ?? {}),
...(pkgSnapshot.transitivePeerDependencies ?? []),
]),
}
nodes.set(key, node)
node.dependencies = toTree(nodes, lockfile, { ...pkgSnapshot.dependencies, ...pkgSnapshot.optionalDependencies })
Expand Down