mirror of
https://github.com/pnpm/pnpm.git
synced 2026-07-26 07:27:20 -04:00
fix: excluding external links from subprojects (#6505)
This commit is contained in:
5
.changeset/wet-monkeys-guess.md
Normal file
5
.changeset/wet-monkeys-guess.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@pnpm/headless": patch
|
||||
---
|
||||
|
||||
Don't create broken symlinks in subprojects that have external symlinks, when the linked dependencies are excluded from the lockfile.
|
||||
@@ -20,8 +20,11 @@ const f = fixtures(__dirname)
|
||||
|
||||
test('links are not added to the lockfile when excludeLinksFromLockfile is true', async () => {
|
||||
const externalPkg1 = tempDir(false)
|
||||
fs.writeFileSync(path.join(externalPkg1, 'index.js'), '', 'utf8')
|
||||
const externalPkg2 = tempDir(false)
|
||||
fs.writeFileSync(path.join(externalPkg2, 'index.js'), '', 'utf8')
|
||||
const externalPkg3 = tempDir(false)
|
||||
fs.writeFileSync(path.join(externalPkg3, 'index.js'), '', 'utf8')
|
||||
preparePackages([
|
||||
{
|
||||
location: 'project-1',
|
||||
@@ -53,7 +56,7 @@ test('links are not added to the lockfile when excludeLinksFromLockfile is true'
|
||||
|
||||
dependencies: {
|
||||
'is-positive': '1.0.0',
|
||||
'external-1': `link:${path.relative(project1Dir, externalPkg1)}`,
|
||||
'external-1': `link:${externalPkg1}`,
|
||||
},
|
||||
},
|
||||
rootDir: project1Dir,
|
||||
@@ -77,8 +80,8 @@ test('links are not added to the lockfile when excludeLinksFromLockfile is true'
|
||||
expect(lockfile.importers['project-1'].dependencies?.['external-1']).toBeUndefined()
|
||||
expect(lockfile.importers['project-2'].dependencies?.['external-2']).toBeUndefined()
|
||||
|
||||
expect(fs.existsSync(path.resolve('project-1/node_modules/external-1'))).toBeTruthy()
|
||||
expect(fs.existsSync(path.resolve('project-2/node_modules/external-2'))).toBeTruthy()
|
||||
expect(fs.existsSync(path.resolve('project-1/node_modules/external-1/index.js'))).toBeTruthy()
|
||||
expect(fs.existsSync(path.resolve('project-2/node_modules/external-2/index.js'))).toBeTruthy()
|
||||
|
||||
await rimraf('node_modules')
|
||||
await rimraf('project-1/node_modules')
|
||||
@@ -88,8 +91,8 @@ test('links are not added to the lockfile when excludeLinksFromLockfile is true'
|
||||
expect(lockfile.importers['project-1'].dependencies?.['external-1']).toBeUndefined()
|
||||
expect(lockfile.importers['project-2'].dependencies?.['external-2']).toBeUndefined()
|
||||
|
||||
expect(fs.existsSync(path.resolve('project-1/node_modules/external-1'))).toBeTruthy()
|
||||
expect(fs.existsSync(path.resolve('project-2/node_modules/external-2'))).toBeTruthy()
|
||||
expect(fs.existsSync(path.resolve('project-1/node_modules/external-1/index.js'))).toBeTruthy()
|
||||
expect(fs.existsSync(path.resolve('project-2/node_modules/external-2/index.js'))).toBeTruthy()
|
||||
|
||||
await rimraf('node_modules')
|
||||
await rimraf('project-1/node_modules')
|
||||
@@ -99,8 +102,8 @@ test('links are not added to the lockfile when excludeLinksFromLockfile is true'
|
||||
expect(lockfile.importers['project-1'].dependencies?.['external-1']).toBeUndefined()
|
||||
expect(lockfile.importers['project-2'].dependencies?.['external-2']).toBeUndefined()
|
||||
|
||||
expect(fs.existsSync(path.resolve('project-1/node_modules/external-1'))).toBeTruthy()
|
||||
expect(fs.existsSync(path.resolve('project-2/node_modules/external-2'))).toBeTruthy()
|
||||
expect(fs.existsSync(path.resolve('project-1/node_modules/external-1/index.js'))).toBeTruthy()
|
||||
expect(fs.existsSync(path.resolve('project-2/node_modules/external-2/index.js'))).toBeTruthy()
|
||||
|
||||
delete allProjects[1].manifest.dependencies!['external-2']
|
||||
allProjects[1].manifest.dependencies!['external-3'] = `link:${path.relative(project2Dir, externalPkg3)}`
|
||||
@@ -109,9 +112,9 @@ test('links are not added to the lockfile when excludeLinksFromLockfile is true'
|
||||
expect(lockfile.importers['project-2'].dependencies?.['external-2']).toBeUndefined()
|
||||
expect(lockfile.importers['project-2'].dependencies?.['external-3']).toBeUndefined()
|
||||
|
||||
expect(fs.existsSync(path.resolve('project-1/node_modules/external-1'))).toBeTruthy()
|
||||
expect(fs.existsSync(path.resolve('project-1/node_modules/external-1/index.js'))).toBeTruthy()
|
||||
// expect(fs.existsSync(path.resolve('project-2/node_modules/external-2'))).toBeFalsy() // Should we remove external links that are not in deps anymore?
|
||||
expect(fs.existsSync(path.resolve('project-2/node_modules/external-3'))).toBeTruthy()
|
||||
expect(fs.existsSync(path.resolve('project-2/node_modules/external-3/index.js'))).toBeTruthy()
|
||||
})
|
||||
|
||||
test('local file using absolute path is correctly installed on repeat install', async () => {
|
||||
|
||||
@@ -278,7 +278,7 @@ export async function headlessInstall (opts: HeadlessOptions): Promise<Installat
|
||||
lockfileDir,
|
||||
})
|
||||
if (opts.excludeLinksFromLockfile) {
|
||||
for (const { id, manifest } of selectedProjects) {
|
||||
for (const { id, manifest, rootDir } of selectedProjects) {
|
||||
if (filteredLockfile.importers[id]) {
|
||||
for (const depType of DEPENDENCIES_FIELDS) {
|
||||
filteredLockfile.importers[id][depType] = {
|
||||
@@ -286,7 +286,8 @@ export async function headlessInstall (opts: HeadlessOptions): Promise<Installat
|
||||
...Object.entries(manifest[depType] ?? {})
|
||||
.filter(([_, spec]) => spec.startsWith('link:'))
|
||||
.reduce((acc, [depName, spec]) => {
|
||||
acc[depName] = `link:${path.relative(opts.lockfileDir, spec.substring(5))}`
|
||||
const linkPath = spec.substring(5)
|
||||
acc[depName] = path.isAbsolute(linkPath) ? `link:${path.relative(rootDir, spec.substring(5))}` : spec
|
||||
return acc
|
||||
}, {} as Record<string, string>),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user