fix: excluding external links from subprojects (#6505)

This commit is contained in:
Zoltan Kochan
2023-05-05 13:42:46 +03:00
committed by GitHub
parent fcfbf96429
commit 32801442e8
3 changed files with 20 additions and 11 deletions

View 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.

View File

@@ -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 () => {

View File

@@ -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>),
}