fix: error that sometimes happen on projects with linked deps (#5628)

close #5327
close #5614
This commit is contained in:
Zoltan Kochan
2022-11-14 02:51:40 +02:00
committed by GitHub
parent 9ad96e25a6
commit 4a4b2ac93b
7 changed files with 103 additions and 2 deletions

View File

@@ -0,0 +1,5 @@
---
"pnpm": patch
---
Fix an error that sometimes happen on projects with linked local dependencies [#5327](https://github.com/pnpm/pnpm/issues/5327).

View File

@@ -0,0 +1,5 @@
---
"@pnpm/resolve-dependencies": patch
---
Fix the nodeId in dependenciesTree for linked local packages.

View File

@@ -8,6 +8,8 @@ import { fixtures } from '@pnpm/test-fixtures'
import {
addDependenciesToPackage,
install,
mutateModules,
MutatedProject,
mutateModulesInSingleProject,
} from '@pnpm/core'
import rimraf from '@zkochan/rimraf'
@@ -276,3 +278,78 @@ test('deep local', async () => {
const lockfile = await readYamlFile<Lockfile>('pnpm-lock.yaml')
expect(Object.keys(lockfile.packages ?? {})).toStrictEqual(['file:../project-2', 'file:../project-2/project-3'])
})
// Covers https://github.com/pnpm/pnpm/issues/5327
test('resolution should not fail when a peer is resolved from a local package and there are many circular dependencies', async () => {
const manifest1 = {
name: 'chained-iterator',
version: '0.0.4',
dependencies: {
'@bryntum/siesta': '6.0.0-beta-1',
},
}
const manifest2 = {
name: '@bryntum/chronograph',
version: '2.0.3',
dependencies: {
'@bryntum/siesta': '6.0.0-beta-1',
'typescript-serializable-mixin': '0.0.3',
'typescript-mixin-class': 'link:../typescript-mixin-class',
},
}
const manifest3 = {
name: 'typescript-mixin-class',
version: '0.0.3',
dependencies: {
'@bryntum/siesta': '6.0.0-beta-1',
},
}
preparePackages([
{
location: manifest1.name,
package: manifest1,
},
{
location: manifest2.name,
package: manifest2,
},
{
location: manifest3.name,
package: manifest3,
},
])
const importers: MutatedProject[] = [
{
mutation: 'install',
rootDir: path.resolve(manifest1.name),
},
{
mutation: 'install',
rootDir: path.resolve(manifest2.name),
},
{
mutation: 'install',
rootDir: path.resolve(manifest3.name),
},
]
const allProjects = [
{
buildIndex: 0,
manifest: manifest1,
rootDir: path.resolve(manifest1.name),
},
{
buildIndex: 0,
manifest: manifest2,
rootDir: path.resolve(manifest2.name),
},
{
buildIndex: 0,
manifest: manifest3,
rootDir: path.resolve(manifest3.name),
},
]
await mutateModules(importers, await testDefaults({ allProjects, lockfileOnly: true, strictPeerDependencies: false }))
// All we need to know in this test is that installation doesn't fail
})

View File

@@ -50,6 +50,7 @@
"get-npm-tarball-url": "^2.0.3",
"is-inner-link": "^4.0.0",
"is-subdir": "^1.2.0",
"normalize-path": "^3.0.0",
"p-defer": "^3.0.0",
"path-exists": "^4.0.0",
"promise-share": "^1.0.0",
@@ -63,6 +64,7 @@
},
"devDependencies": {
"@pnpm/resolve-dependencies": "workspace:*",
"@types/normalize-path": "^3.0.0",
"@types/ramda": "0.28.15",
"@types/semver": "7.3.13"
},

View File

@@ -25,6 +25,7 @@ import promiseShare from 'promise-share'
import difference from 'ramda/src/difference'
import { getWantedDependencies, WantedDependency } from './getWantedDependencies'
import { depPathToRef } from './depPathToRef'
import { createNodeIdForLinkedLocalPkg } from './resolveDependencies'
import {
Importer,
LinkedDependency,
@@ -179,7 +180,7 @@ export async function resolveDependencies (
topParents.push({
name: linkedDependency.alias,
version: linkedDependency.version,
linkedDir: `link:${path.relative(opts.lockfileDir, linkedDependency.resolution.directory)}`,
linkedDir: createNodeIdForLinkedLocalPkg(opts.lockfileDir, linkedDependency.resolution.directory),
})
})

View File

@@ -39,6 +39,7 @@ import {
Registries,
} from '@pnpm/types'
import * as dp from 'dependency-path'
import normalizePath from 'normalize-path'
import exists from 'path-exists'
import pDefer from 'p-defer'
import pShare from 'promise-share'
@@ -665,7 +666,7 @@ async function resolveDependenciesOfDependency (
if (resolveDependencyResult == null) return { resolveDependencyResult: null }
if (resolveDependencyResult.isLinkedDependency) {
ctx.dependenciesTree[resolveDependencyResult.pkgId] = {
ctx.dependenciesTree[createNodeIdForLinkedLocalPkg(ctx.lockfileDir, resolveDependencyResult.resolution.directory)] = {
children: {},
depth: -1,
installable: true,
@@ -708,6 +709,10 @@ async function resolveDependenciesOfDependency (
}
}
export function createNodeIdForLinkedLocalPkg (lockfileDir: string, pkgDir: string) {
return `link:${normalizePath(path.relative(lockfileDir, pkgDir))}`
}
function filterMissingPeers (
{ missingPeers, resolvedPeers }: PeersResolutionResult,
parentPkgAliases: ParentPkgAliases

6
pnpm-lock.yaml generated
View File

@@ -4882,6 +4882,9 @@ importers:
is-subdir:
specifier: ^1.2.0
version: 1.2.0
normalize-path:
specifier: ^3.0.0
version: 3.0.0
p-defer:
specifier: ^3.0.0
version: 3.0.0
@@ -4916,6 +4919,9 @@ importers:
'@pnpm/resolve-dependencies':
specifier: workspace:*
version: 'link:'
'@types/normalize-path':
specifier: ^3.0.0
version: 3.0.0
'@types/ramda':
specifier: 0.28.15
version: 0.28.15