mirror of
https://github.com/pnpm/pnpm.git
synced 2025-12-23 23:29:17 -05:00
fix: throw a meaningful error message on broken lockfile (#4387)
When `node-linker` is set to `hoisted`, a meaningful error message should be thrown if the lockfile is broken and `pnpm install` is executed.
This commit is contained in:
5
.changeset/rich-books-build.md
Normal file
5
.changeset/rich-books-build.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@pnpm/filter-lockfile": patch
|
||||
---
|
||||
|
||||
Update `@pnpm/error`.
|
||||
6
.changeset/serious-jars-provide.md
Normal file
6
.changeset/serious-jars-provide.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@pnpm/real-hoist": patch
|
||||
"pnpm": patch
|
||||
---
|
||||
|
||||
Throw a meaningful error message on `pnpm install` when the lockfile is broken and `node-linker` is set to `hoisted`.
|
||||
5
.changeset/stupid-dryers-wave.md
Normal file
5
.changeset/stupid-dryers-wave.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@pnpm/error": minor
|
||||
---
|
||||
|
||||
Add new error object: LockfileMissingDependencyError.
|
||||
@@ -31,5 +31,8 @@
|
||||
"funding": "https://opencollective.com/pnpm",
|
||||
"devDependencies": {
|
||||
"@pnpm/error": "workspace:2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@pnpm/constants": "workspace:5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { WANTED_LOCKFILE } from '@pnpm/constants'
|
||||
|
||||
export default class PnpmError extends Error {
|
||||
public readonly code: string
|
||||
public readonly hint?: string
|
||||
@@ -55,3 +57,13 @@ function hideAuthInformation (authHeaderValue: string) {
|
||||
const [authType, token] = authHeaderValue.split(' ')
|
||||
return `${authType} ${token.substring(0, 4)}[hidden]`
|
||||
}
|
||||
|
||||
export class LockfileMissingDependencyError extends PnpmError {
|
||||
constructor (depPath: string) {
|
||||
const message = `Broken lockfile: no entry for '${depPath}' in ${WANTED_LOCKFILE}`
|
||||
super('LOCKFILE_MISSING_DEPENDENCY', message, {
|
||||
hint: 'This issue is probably caused by a badly resolved merge conflict.\n' +
|
||||
'To fix the lockfile, run \'pnpm install --no-frozen-lockfile\'.',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,5 +8,9 @@
|
||||
"src/**/*.ts",
|
||||
"../../typings/**/*.d.ts"
|
||||
],
|
||||
"references": []
|
||||
"references": [
|
||||
{
|
||||
"path": "../constants"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
import { WANTED_LOCKFILE } from '@pnpm/constants'
|
||||
import PnpmError from '@pnpm/error'
|
||||
|
||||
export default class LockfileMissingDependencyError extends PnpmError {
|
||||
constructor (depPath: string) {
|
||||
const message = `Broken lockfile: no entry for '${depPath}' in ${WANTED_LOCKFILE}`
|
||||
super('LOCKFILE_MISSING_DEPENDENCY', message, {
|
||||
hint: 'This issue is probably caused by a badly resolved merge conflict.\n' +
|
||||
'To fix the lockfile, run \'pnpm install --no-frozen-lockfile\'.',
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import { WANTED_LOCKFILE } from '@pnpm/constants'
|
||||
import { LockfileMissingDependencyError } from '@pnpm/error'
|
||||
import {
|
||||
Lockfile,
|
||||
PackageSnapshots,
|
||||
@@ -7,7 +8,6 @@ import lockfileWalker, { LockfileWalkerStep } from '@pnpm/lockfile-walker'
|
||||
import pnpmLogger from '@pnpm/logger'
|
||||
import { DependenciesField } from '@pnpm/types'
|
||||
import filterImporter from './filterImporter'
|
||||
import LockfileMissingDependencyError from './LockfileMissingDependencyError'
|
||||
|
||||
const logger = pnpmLogger('lockfile')
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { WANTED_LOCKFILE } from '@pnpm/constants'
|
||||
import { LockfileMissingDependencyError } from '@pnpm/error'
|
||||
import {
|
||||
Lockfile,
|
||||
PackageSnapshots,
|
||||
@@ -10,7 +11,6 @@ import { DependenciesField } from '@pnpm/types'
|
||||
import * as dp from 'dependency-path'
|
||||
import unnest from 'ramda/src/unnest'
|
||||
import filterImporter from './filterImporter'
|
||||
import LockfileMissingDependencyError from './LockfileMissingDependencyError'
|
||||
|
||||
const logger = pnpmLogger('lockfile')
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
"compile": "tsc --build && pnpm run lint --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@pnpm/error": "workspace:2.0.0",
|
||||
"@pnpm/lockfile-utils": "workspace:3.2.1",
|
||||
"@yarnpkg/nm": "3.0.1-rc.10",
|
||||
"dependency-path": "workspace:8.0.11"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { LockfileMissingDependencyError } from '@pnpm/error'
|
||||
import {
|
||||
Lockfile,
|
||||
nameVerFromPkgSnapshot,
|
||||
@@ -70,8 +71,10 @@ function toTree (nodes: Map<string, HoisterTree>, lockfile: Lockfile, deps: Reco
|
||||
const key = `${alias}:${depPath}`
|
||||
let node = nodes.get(key)
|
||||
if (!node) {
|
||||
// const { name, version, peersSuffix } = nameVerFromPkgSnapshot(depPath, lockfile.packages![depPath])
|
||||
const pkgSnapshot = lockfile.packages![depPath]
|
||||
if (!pkgSnapshot) {
|
||||
throw new LockfileMissingDependencyError(depPath)
|
||||
}
|
||||
const pkgName = nameVerFromPkgSnapshot(depPath, pkgSnapshot).name
|
||||
node = {
|
||||
name: alias,
|
||||
|
||||
@@ -6,3 +6,20 @@ test('hoist', async () => {
|
||||
const lockfile = await readWantedLockfile(path.join(__dirname, '../../..'), { ignoreIncompatible: true })
|
||||
expect(hoist(lockfile!)).toBeTruthy()
|
||||
})
|
||||
|
||||
test('hoist throws an error if the lockfile is broken', () => {
|
||||
expect(() => hoist({
|
||||
lockfileVersion: 5,
|
||||
importers: {
|
||||
'.': {
|
||||
dependencies: {
|
||||
foo: '1.0.0',
|
||||
},
|
||||
specifiers: {
|
||||
foo: '1.0.0',
|
||||
},
|
||||
},
|
||||
},
|
||||
packages: {},
|
||||
})).toThrow(/Broken lockfile/)
|
||||
})
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
{
|
||||
"path": "../dependency-path"
|
||||
},
|
||||
{
|
||||
"path": "../error"
|
||||
},
|
||||
{
|
||||
"path": "../lockfile-file"
|
||||
},
|
||||
|
||||
5
pnpm-lock.yaml
generated
5
pnpm-lock.yaml
generated
@@ -717,7 +717,10 @@ importers:
|
||||
|
||||
packages/error:
|
||||
specifiers:
|
||||
'@pnpm/constants': workspace:5.0.0
|
||||
'@pnpm/error': workspace:2.0.0
|
||||
dependencies:
|
||||
'@pnpm/constants': link:../constants
|
||||
devDependencies:
|
||||
'@pnpm/error': 'link:'
|
||||
|
||||
@@ -3054,6 +3057,7 @@ importers:
|
||||
|
||||
packages/real-hoist:
|
||||
specifiers:
|
||||
'@pnpm/error': workspace:2.0.0
|
||||
'@pnpm/lockfile-file': workspace:4.3.0
|
||||
'@pnpm/lockfile-utils': workspace:3.2.1
|
||||
'@pnpm/logger': ^4.0.0
|
||||
@@ -3061,6 +3065,7 @@ importers:
|
||||
'@yarnpkg/nm': 3.0.1-rc.10
|
||||
dependency-path: workspace:8.0.11
|
||||
dependencies:
|
||||
'@pnpm/error': link:../error
|
||||
'@pnpm/lockfile-utils': link:../lockfile-utils
|
||||
'@yarnpkg/nm': 3.0.1-rc.10
|
||||
dependency-path: link:../dependency-path
|
||||
|
||||
Reference in New Issue
Block a user