mirror of
https://github.com/pnpm/pnpm.git
synced 2025-12-24 07:38:12 -05:00
fix: don't overwrite node_modules inside inject dependencies (#4299)
This commit is contained in:
6
.changeset/hip-actors-boil.md
Normal file
6
.changeset/hip-actors-boil.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@pnpm/lifecycle": patch
|
||||
"pnpm": patch
|
||||
---
|
||||
|
||||
`node_modules` directories inside injected dependencies should not be overwritten.
|
||||
@@ -357,8 +357,6 @@ test('inject local packages when node-linker is hoisted', async () => {
|
||||
version: '1.0.0',
|
||||
dependencies: {
|
||||
'is-negative': '1.0.0',
|
||||
},
|
||||
devDependencies: {
|
||||
'dep-of-pkg-with-1-dep': '100.0.0',
|
||||
},
|
||||
peerDependencies: {
|
||||
@@ -370,6 +368,7 @@ test('inject local packages when node-linker is hoisted', async () => {
|
||||
version: '1.0.0',
|
||||
dependencies: {
|
||||
'project-1': 'workspace:1.0.0',
|
||||
'dep-of-pkg-with-1-dep': '101.0.0',
|
||||
},
|
||||
devDependencies: {
|
||||
'is-positive': '1.0.0',
|
||||
@@ -461,6 +460,7 @@ test('inject local packages when node-linker is hoisted', async () => {
|
||||
await rootModules.has('is-positive')
|
||||
|
||||
await projects['project-2'].has('project-1')
|
||||
await projects['project-2'].has('project-1/node_modules/dep-of-pkg-with-1-dep')
|
||||
|
||||
await projects['project-3'].has('project-1')
|
||||
await projects['project-3'].has('project-2')
|
||||
@@ -485,6 +485,7 @@ test('inject local packages when node-linker is hoisted', async () => {
|
||||
'is-positive': '>=1.0.0',
|
||||
},
|
||||
dependencies: {
|
||||
'dep-of-pkg-with-1-dep': '100.0.0',
|
||||
'is-negative': '1.0.0',
|
||||
'is-positive': '1.0.0',
|
||||
},
|
||||
@@ -499,6 +500,7 @@ test('inject local packages when node-linker is hoisted', async () => {
|
||||
name: 'project-2',
|
||||
version: '1.0.0',
|
||||
dependencies: {
|
||||
'dep-of-pkg-with-1-dep': '101.0.0',
|
||||
'project-1': 'file:project-1_is-positive@2.0.0',
|
||||
},
|
||||
transitivePeerDependencies: ['is-positive'],
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import { fetchFromDir } from '@pnpm/directory-fetcher'
|
||||
import { StoreController } from '@pnpm/store-controller-types'
|
||||
import { ProjectManifest } from '@pnpm/types'
|
||||
@@ -53,16 +55,46 @@ export default async function runLifecycleHooksConcurrently (
|
||||
if (targetDirs == null || targetDirs.length === 0) return
|
||||
const filesResponse = await fetchFromDir(rootDir, {})
|
||||
await Promise.all(
|
||||
targetDirs.map((targetDir) => opts.storeController.importPackage(targetDir, {
|
||||
filesResponse: {
|
||||
fromStore: false,
|
||||
...filesResponse,
|
||||
},
|
||||
force: false,
|
||||
}))
|
||||
targetDirs.map(async (targetDir) => {
|
||||
const targetModulesDir = path.join(targetDir, 'node_modules')
|
||||
const nodeModulesIndex = {}
|
||||
if (fs.existsSync(targetModulesDir)) {
|
||||
// If the target directory contains a node_modules directory
|
||||
// (it may happen when the hoisted node linker is used)
|
||||
// then we need to preserve this node_modules.
|
||||
// So we scan this node_modules directory and pass it as part of the new package.
|
||||
await scanDir('node_modules', targetModulesDir, targetModulesDir, nodeModulesIndex)
|
||||
}
|
||||
return opts.storeController.importPackage(targetDir, {
|
||||
filesResponse: {
|
||||
fromStore: false,
|
||||
...filesResponse,
|
||||
filesIndex: {
|
||||
...filesResponse.filesIndex,
|
||||
...nodeModulesIndex,
|
||||
},
|
||||
},
|
||||
force: false,
|
||||
})
|
||||
})
|
||||
)
|
||||
}
|
||||
)
|
||||
})
|
||||
await runGroups(childConcurrency, groups)
|
||||
}
|
||||
|
||||
async function scanDir (prefix: string, rootDir: string, currentDir: string, index: Record<string, string>) {
|
||||
const files = await fs.promises.readdir(currentDir)
|
||||
await Promise.all(files.map(async (file) => {
|
||||
const fullPath = path.join(currentDir, file)
|
||||
const stat = await fs.promises.stat(fullPath)
|
||||
if (stat.isDirectory()) {
|
||||
return scanDir(prefix, rootDir, fullPath, index)
|
||||
}
|
||||
if (stat.isFile()) {
|
||||
const relativePath = path.relative(rootDir, fullPath)
|
||||
index[path.join(prefix, relativePath)] = fullPath
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user