fix!: always create a lockfile (#6073)

This commit is contained in:
Zoltan Kochan
2023-02-13 22:33:10 +02:00
committed by GitHub
parent 170d975ec7
commit 417c8ac595
13 changed files with 40 additions and 24 deletions

View File

@@ -0,0 +1,6 @@
---
"@pnpm/lockfile-file": major
"pnpm": major
---
Create a lockfile even if the project has no dependencies at all.

1
__fixtures__/empty/pnpm-lock.yaml generated Normal file
View File

@@ -0,0 +1 @@
lockfileVersion: '6.0'

1
__fixtures__/local-pkg/pnpm-lock.yaml generated Normal file
View File

@@ -0,0 +1 @@
lockfileVersion: '6.0'

View File

@@ -0,0 +1 @@
lockfileVersion: '6.0'

1
__fixtures__/pnpm-lock.yaml generated Normal file
View File

@@ -0,0 +1 @@
lockfileVersion: '6.0'

1
__fixtures__/tar-pkg/pnpm-lock.yaml generated Normal file
View File

@@ -0,0 +1 @@
lockfileVersion: '6.0'

View File

@@ -0,0 +1 @@
lockfileVersion: '6.0'

View File

@@ -0,0 +1 @@
lockfileVersion: '6.0'

View File

@@ -0,0 +1 @@
lockfileVersion: '6.0'

View File

@@ -1,4 +1,5 @@
export {
isEmptyLockfile,
writeLockfiles,
writeCurrentLockfile,
writeWantedLockfile,

View File

@@ -53,6 +53,11 @@ export async function writeCurrentLockfile (
forceSharedFormat?: boolean
}
) {
// empty lockfile is not saved
if (isEmptyLockfile(currentLockfile)) {
await rimraf(path.join(virtualStoreDir, 'lock.yaml'))
return
}
await fs.mkdir(virtualStoreDir, { recursive: true })
return writeLockfile('lock.yaml', virtualStoreDir, currentLockfile, opts)
}
@@ -70,11 +75,6 @@ async function writeLockfile (
) {
const lockfilePath = path.join(pkgPath, lockfileFilename)
// empty lockfile is not saved
if (isEmptyLockfile(wantedLockfile)) {
return rimraf(lockfilePath)
}
const isLockfileV6 = wantedLockfile['lockfileVersion'].toString().startsWith('6.')
const lockfileToStringify = (Boolean(opts?.useInlineSpecifiersFormat) || isLockfileV6)
? convertToInlineSpecifiersFormat(wantedLockfile) as unknown as Lockfile
@@ -94,7 +94,7 @@ function yamlStringify (lockfile: Lockfile, opts: NormalizeLockfileOpts) {
return yaml.dump(normalizedLockfile, LOCKFILE_YAML_FORMAT)
}
function isEmptyLockfile (lockfile: Lockfile) {
export function isEmptyLockfile (lockfile: Lockfile) {
return Object.values(lockfile.importers).every((importer) => isEmpty(importer.specifiers ?? {}) && isEmpty(importer.dependencies ?? {}))
}
@@ -240,15 +240,6 @@ export async function writeLockfiles (
const wantedLockfilePath = path.join(opts.wantedLockfileDir, wantedLockfileName)
const currentLockfilePath = path.join(opts.currentLockfileDir, 'lock.yaml')
// empty lockfile is not saved
if (isEmptyLockfile(opts.wantedLockfile)) {
await Promise.all([
rimraf(wantedLockfilePath),
rimraf(currentLockfilePath),
])
return
}
const forceSharedFormat = opts?.forceSharedFormat === true
const isLockfileV6 = opts.wantedLockfile.lockfileVersion.toString().startsWith('6.')
const wantedLockfileToStringify = (Boolean(opts.useInlineSpecifiersFormat) || isLockfileV6)
@@ -267,8 +258,12 @@ export async function writeLockfiles (
await Promise.all([
writeFileAtomic(wantedLockfilePath, yamlDoc),
(async () => {
await fs.mkdir(path.dirname(currentLockfilePath), { recursive: true })
await writeFileAtomic(currentLockfilePath, yamlDoc)
if (isEmptyLockfile(opts.wantedLockfile)) {
await rimraf(currentLockfilePath)
} else {
await fs.mkdir(path.dirname(currentLockfilePath), { recursive: true })
await writeFileAtomic(currentLockfilePath, yamlDoc)
}
})(),
])
return
@@ -287,8 +282,12 @@ export async function writeLockfiles (
await Promise.all([
writeFileAtomic(wantedLockfilePath, yamlDoc),
(async () => {
await fs.mkdir(path.dirname(currentLockfilePath), { recursive: true })
await writeFileAtomic(currentLockfilePath, currentYamlDoc)
if (isEmptyLockfile(opts.wantedLockfile)) {
await rimraf(currentLockfilePath)
} else {
await fs.mkdir(path.dirname(currentLockfilePath), { recursive: true })
await writeFileAtomic(currentLockfilePath, currentYamlDoc)
}
})(),
])
}

View File

@@ -141,16 +141,16 @@ test("lockfile doesn't lock subdependencies that don't satisfy the new specs", a
expect(Object.keys(lockfile.dependencies).length).toBe(1) // resolutions not duplicated
})
test('lockfile not created when no deps in package.json', async () => {
test('a lockfile created even when there are no deps in package.json', async () => {
const project = prepareEmpty()
await install({}, await testDefaults())
expect(await project.readLockfile()).toBeFalsy()
expect(await project.readLockfile()).toBeTruthy()
expect(await exists('node_modules')).toBeFalsy()
})
test('lockfile removed when no deps in package.json', async () => {
test('current lockfile removed when no deps in package.json', async () => {
const project = prepareEmpty()
await writeYamlFile(WANTED_LOCKFILE, {
@@ -172,7 +172,8 @@ test('lockfile removed when no deps in package.json', async () => {
await install({}, await testDefaults())
expect(await project.readLockfile()).toBeFalsy()
expect(await project.readLockfile()).toBeTruthy()
expect(await exists('node_modules')).toBeFalsy()
})
test('lockfile is fixed when it does not match package.json', async () => {

View File

@@ -6,6 +6,7 @@ import {
import {
createLockfileObject,
existsWantedLockfile,
isEmptyLockfile,
Lockfile,
readCurrentLockfile,
readWantedLockfile,
@@ -126,7 +127,7 @@ export async function readLockfiles (
currentLockfile,
currentLockfileIsUpToDate: equals(currentLockfile, wantedLockfile),
existsCurrentLockfile: files[1] != null,
existsWantedLockfile: files[0] != null,
existsWantedLockfile: files[0] != null && !isEmptyLockfile(wantedLockfile),
wantedLockfile,
lockfileHadConflicts,
}