fix: automatically resolve conflicts in lockfile v6 (#6127)

This commit is contained in:
Zoltan Kochan
2023-02-23 12:13:04 +02:00
committed by GitHub
parent 77c754b10a
commit ed946c73e9
4 changed files with 53 additions and 8 deletions

View File

@@ -0,0 +1,7 @@
---
"@pnpm/lockfile-file": patch
"@pnpm/core": patch
"pnpm": patch
---
Automatically fix conflicts in v6 lockfile.

View File

@@ -1,6 +1,7 @@
import { Lockfile } from '@pnpm/lockfile-types'
import { mergeLockfileChanges } from '@pnpm/merge-lockfile-changes'
import yaml from 'js-yaml'
import { revertFromInlineSpecifiersFormatIfNecessary } from './experiments/inlineSpecifiersLockfileConverters'
const MERGE_CONFLICT_PARENT = '|||||||'
const MERGE_CONFLICT_END = '>>>>>>>'
@@ -10,8 +11,8 @@ const MERGE_CONFLICT_OURS = '<<<<<<<'
export function autofixMergeConflicts (fileContent: string) {
const { ours, theirs } = parseMergeFile(fileContent)
return mergeLockfileChanges(
yaml.load(ours) as Lockfile,
yaml.load(theirs) as Lockfile
revertFromInlineSpecifiersFormatIfNecessary(yaml.load(ours) as Lockfile),
revertFromInlineSpecifiersFormatIfNecessary(yaml.load(theirs) as Lockfile)
)
}

View File

@@ -85,24 +85,23 @@ async function _read (
hadConflicts: false,
}
}
let lockfileFile: LockfileFile
let lockfile: Lockfile
let hadConflicts!: boolean
try {
lockfileFile = yaml.load(lockfileRawContent) as Lockfile
lockfile = revertFromInlineSpecifiersFormatIfNecessary(convertFromLockfileFileMutable(yaml.load(lockfileRawContent) as Lockfile))
hadConflicts = false
} catch (err: any) { // eslint-disable-line
if (!opts.autofixMergeConflicts || !isDiff(lockfileRawContent)) {
throw new PnpmError('BROKEN_LOCKFILE', `The lockfile at "${lockfilePath}" is broken: ${err.message as string}`)
}
hadConflicts = true
lockfileFile = autofixMergeConflicts(lockfileRawContent)
lockfile = convertFromLockfileFileMutable(autofixMergeConflicts(lockfileRawContent))
logger.info({
message: `Merge conflict detected in ${WANTED_LOCKFILE} and successfully merged`,
prefix,
})
}
if (lockfileFile) {
const lockfile = revertFromInlineSpecifiersFormatIfNecessary(convertFromLockfileFileMutable(lockfileFile))
if (lockfile) {
const lockfileSemver = comverToSemver((lockfile.lockfileVersion ?? 0).toString())
/* eslint-enable @typescript-eslint/dot-notation */
if (

View File

@@ -1,6 +1,6 @@
import { promises as fs } from 'fs'
import path from 'path'
import { LOCKFILE_VERSION, WANTED_LOCKFILE } from '@pnpm/constants'
import { LOCKFILE_VERSION, LOCKFILE_VERSION_V6, WANTED_LOCKFILE } from '@pnpm/constants'
import { RootLog } from '@pnpm/core-loggers'
import { PnpmError } from '@pnpm/error'
import { Lockfile, TarballResolution } from '@pnpm/lockfile-file'
@@ -1217,6 +1217,44 @@ packages:
expect(lockfile.dependencies['@pnpm.e2e/dep-of-pkg-with-1-dep']).toBe('100.1.0')
})
test('a lockfile v6 with merge conflicts is autofixed', async () => {
const project = prepareEmpty()
await fs.writeFile(WANTED_LOCKFILE, `\
lockfileVersion: '${LOCKFILE_VERSION_V6}'
importers:
.:
dependencies:
'@pnpm.e2e/dep-of-pkg-with-1-dep':
specifier: '>100.0.0'
<<<<<<< HEAD
version: 100.0.0
=======
version: 100.1.0
>>>>>>> next
packages:
<<<<<<< HEAD
/@pnpm.e2e/dep-of-pkg-with-1-dep@100.0.0:
dev: false
resolution:
integrity: ${getIntegrity('@pnpm.e2e/dep-of-pkg-with-1-dep', '100.0.0')}
=======
/@pnpm.e2e/dep-of-pkg-with-1-dep@100.1.0:
dev: false
resolution:
integrity: ${getIntegrity('@pnpm.e2e/dep-of-pkg-with-1-dep', '100.1.0')}
>>>>>>> next`, 'utf8')
await install({
dependencies: {
'@pnpm.e2e/dep-of-pkg-with-1-dep': '>100.0.0',
},
}, await testDefaults())
const lockfile = await project.readLockfile()
expect(lockfile.dependencies['@pnpm.e2e/dep-of-pkg-with-1-dep']).toHaveProperty('version', '100.1.0')
})
test('a lockfile with duplicate keys is fixed', async () => {
const project = prepareEmpty()