Skip to content

Commit

Permalink
fix: don't overwrite node_modules inside inject dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
zkochan committed Feb 4, 2022
1 parent 1a3126e commit c1982a1
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 10 deletions.
6 changes: 6 additions & 0 deletions .changeset/hip-actors-boil.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@pnpm/lifecycle": patch
"pnpm": patch
---

`node_modules` directories inside injected dependencies should not be overwritten.
6 changes: 4 additions & 2 deletions packages/core/test/install/injectLocalPackages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand All @@ -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',
Expand Down Expand Up @@ -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')
Expand All @@ -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',
},
Expand All @@ -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'],
Expand Down
46 changes: 39 additions & 7 deletions packages/lifecycle/src/runLifecycleHooksConcurrently.ts
Original file line number Diff line number Diff line change
@@ -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'
Expand Down Expand Up @@ -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
}
}))
}
4 changes: 3 additions & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit c1982a1

Please sign in to comment.