fix: linking external links when excludeLinksFromLockfile is enabled (#6417)

This commit is contained in:
Zoltan Kochan
2023-04-17 18:51:30 +03:00
committed by GitHub
parent e0ebe9194f
commit 8f7e99477b
4 changed files with 62 additions and 3 deletions

View File

@@ -0,0 +1,5 @@
---
"@pnpm/headless": patch
---
External links should be correctly installed on repeat install, when `excludeLinksFromLockfile` is set to `true`.

View File

@@ -31,11 +31,13 @@ export function satisfiesPackageManifest (
}
}
const pickNonLinkedDeps = pickBy((spec) => !spec.startsWith('link:'))
let specs = importer.specifiers
if (opts?.excludeLinksFromLockfile) {
existingDeps = pickNonLinkedDeps(existingDeps)
specs = pickNonLinkedDeps(specs)
}
if (
!equals(existingDeps, importer.specifiers) ||
!equals(existingDeps, specs) ||
importer.publishDirectory !== pkg.publishConfig?.directory
) {
return false

View File

@@ -2,16 +2,22 @@ import fs from 'fs'
import path from 'path'
import { WANTED_LOCKFILE } from '@pnpm/constants'
import {
addDependenciesToPackage,
install,
mutateModules,
type MutatedProject,
type ProjectOptions,
} from '@pnpm/core'
import { type LockfileV6 } from '@pnpm/lockfile-types'
import { preparePackages, tempDir } from '@pnpm/prepare'
import { prepareEmpty, preparePackages, tempDir } from '@pnpm/prepare'
import { fixtures } from '@pnpm/test-fixtures'
import rimraf from '@zkochan/rimraf'
import normalizePath from 'normalize-path'
import readYamlFile from 'read-yaml-file'
import { testDefaults } from '../utils'
const f = fixtures(__dirname)
test('links are not added to the lockfile when excludeLinksFromLockfile is true', async () => {
const externalPkg1 = tempDir(false)
const externalPkg2 = tempDir(false)
@@ -107,3 +113,49 @@ test('links are not added to the lockfile when excludeLinksFromLockfile is true'
// 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()
})
test('local file using absolute path is correctly installed on repeat install', async () => {
const project = prepareEmpty()
const absolutePath = path.resolve('..', 'local-pkg')
f.copy('local-pkg', absolutePath)
// is-odd is only added because otherwise no lockfile is created
const manifest = await addDependenciesToPackage({},
[`link:${absolutePath}`, 'is-odd@1.0.0'],
await testDefaults({ excludeLinksFromLockfile: true })
)
const expectedSpecs = {
'is-odd': '1.0.0',
'local-pkg': `link:${normalizePath(absolutePath)}`,
}
expect(manifest.dependencies).toStrictEqual(expectedSpecs)
await rimraf('node_modules')
await install(manifest, await testDefaults({ frozenLockfile: true, excludeLinksFromLockfile: true }))
{
const m = project.requireModule('local-pkg')
expect(m).toBeTruthy()
}
})
test('hoisted install should not fail with excludeLinksFromLockfile true', async () => {
const project = prepareEmpty()
const absolutePath = path.resolve('..', 'local-pkg')
f.copy('local-pkg', absolutePath)
// is-odd is only added because otherwise no lockfile is created
const manifest = await addDependenciesToPackage({},
[`link:${absolutePath}`, 'is-odd@1.0.0'],
await testDefaults({ excludeLinksFromLockfile: true, nodeLinker: 'hoisted' })
)
const expectedSpecs = {
'is-odd': '1.0.0',
'local-pkg': `link:${normalizePath(absolutePath)}`,
}
expect(manifest.dependencies).toStrictEqual(expectedSpecs)
const m = project.requireModule('local-pkg')
expect(m).toBeTruthy()
})

View File

@@ -274,7 +274,7 @@ export async function headlessInstall (opts: HeadlessOptions) {
if (!filteredLockfile.importers[id][depType]) {
filteredLockfile.importers[id][depType] = {}
}
filteredLockfile.importers[id][depType]![depName] = spec
filteredLockfile.importers[id][depType]![depName] = `link:${path.relative(opts.lockfileDir, spec.substring(5))}`
}
}
}