fix: direct deduplication with resolution-mode=lowest-direct (#6262)

close #6042
This commit is contained in:
Zoltan Kochan
2023-03-24 02:17:22 +02:00
committed by GitHub
parent 1d105e7fcd
commit f835994eab
3 changed files with 76 additions and 3 deletions

View File

@@ -0,0 +1,6 @@
---
"@pnpm/npm-resolver": patch
"pnpm": patch
---
Deduplicate direct dependencies, when `resolution-mode` is set to `lowest-direct` [#6042](https://github.com/pnpm/pnpm/issues/6042).

View File

@@ -5,7 +5,7 @@ import { mutateModules, type MutatedProject } from '@pnpm/core'
import { addDistTag } from '@pnpm/registry-mock'
import { testDefaults } from '../utils'
test('pick common range for a dependency used in two workspace projects', async () => {
test('pick common range for a dependency used in two workspace projects when resolution mode is highest', async () => {
await addDistTag({ package: '@pnpm.e2e/dep-of-pkg-with-1-dep', version: '100.1.0', distTag: 'latest' })
preparePackages([
{
@@ -54,10 +54,67 @@ test('pick common range for a dependency used in two workspace projects', async
rootDir: path.resolve('project-2'),
},
]
await mutateModules(importers, await testDefaults({ allProjects, lockfileOnly: true }))
await mutateModules(importers, await testDefaults({ allProjects, lockfileOnly: true, resolutionMode: 'highest' }))
const project = assertProject(process.cwd())
const lockfile = await project.readLockfile()
expect(lockfile.packages).toHaveProperty(['/@pnpm.e2e/dep-of-pkg-with-1-dep@100.0.0'])
expect(lockfile.packages).not.toHaveProperty(['/@pnpm.e2e/dep-of-pkg-with-1-dep@100.1.0'])
})
test('pick common range for a dependency used in two workspace projects when resolution mode is lowest-direct', async () => {
await addDistTag({ package: '@pnpm.e2e/dep-of-pkg-with-1-dep', version: '100.1.0', distTag: 'latest' })
preparePackages([
{
location: 'project-1',
package: { name: 'project-1' },
},
{
location: 'project-2',
package: { name: 'project-2' },
},
])
const importers: MutatedProject[] = [
{
mutation: 'install',
rootDir: path.resolve('project-1'),
},
{
mutation: 'install',
rootDir: path.resolve('project-2'),
},
]
const allProjects = [
{
buildIndex: 0,
manifest: {
name: 'project-1',
version: '1.0.0',
dependencies: {
'@pnpm.e2e/dep-of-pkg-with-1-dep': '100.1.0',
},
},
rootDir: path.resolve('project-1'),
},
{
buildIndex: 0,
manifest: {
name: 'project-2',
version: '1.0.0',
dependencies: {
'@pnpm.e2e/dep-of-pkg-with-1-dep': '^100.0.0',
},
},
rootDir: path.resolve('project-2'),
},
]
await mutateModules(importers, await testDefaults({ allProjects, lockfileOnly: true, resolutionMode: 'lowest-direct' }))
const project = assertProject(process.cwd())
const lockfile = await project.readLockfile()
expect(lockfile.packages).toHaveProperty(['/@pnpm.e2e/dep-of-pkg-with-1-dep@100.1.0'])
expect(lockfile.packages).not.toHaveProperty(['/@pnpm.e2e/dep-of-pkg-with-1-dep@100.0.0'])
})

View File

@@ -60,8 +60,18 @@ export function pickPackageFromMeta (
export function pickLowestVersionByVersionRange (
meta: PackageMeta,
versionRange: string
versionRange: string,
preferredVerSels?: VersionSelectors
) {
if (preferredVerSels != null && Object.keys(preferredVerSels).length > 0) {
const prioritizedPreferredVersions = prioritizePreferredVersions(meta, versionRange, preferredVerSels)
for (const preferredVersions of prioritizedPreferredVersions) {
const preferredVersion = semver.minSatisfying(preferredVersions, versionRange, true)
if (preferredVersion) {
return preferredVersion
}
}
}
if (versionRange === '*') {
return Object.keys(meta.versions).sort(semver.compare)[0]
}