Skip to content

Commit

Permalink
fix!: always create a lockfile (#6073)
Browse files Browse the repository at this point in the history
  • Loading branch information
zkochan committed Feb 13, 2023
1 parent 170d975 commit 417c8ac
Show file tree
Hide file tree
Showing 13 changed files with 40 additions and 24 deletions.
6 changes: 6 additions & 0 deletions .changeset/witty-paws-heal.md
@@ -0,0 +1,6 @@
---
"@pnpm/lockfile-file": major
"pnpm": major
---

Create a lockfile even if the project has no dependencies at all.
1 change: 1 addition & 0 deletions __fixtures__/empty/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions __fixtures__/local-pkg/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions __fixtures__/local-scoped-pkg/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions __fixtures__/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions __fixtures__/tar-pkg/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions __fixtures__/workspace-has-shared-yarn-lock/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions lockfile/lockfile-file/src/index.ts
@@ -1,4 +1,5 @@
export {
isEmptyLockfile,
writeLockfiles,
writeCurrentLockfile,
writeWantedLockfile,
Expand Down
37 changes: 18 additions & 19 deletions lockfile/lockfile-file/src/write.ts
Expand Up @@ -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)
}
Expand All @@ -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
Expand All @@ -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 ?? {}))
}

Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand All @@ -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)
}
})(),
])
}
9 changes: 5 additions & 4 deletions pkg-manager/core/test/lockfile.ts
Expand Up @@ -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, {
Expand All @@ -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 () => {
Expand Down
3 changes: 2 additions & 1 deletion pkg-manager/get-context/src/readLockfiles.ts
Expand Up @@ -6,6 +6,7 @@ import {
import {
createLockfileObject,
existsWantedLockfile,
isEmptyLockfile,
Lockfile,
readCurrentLockfile,
readWantedLockfile,
Expand Down Expand Up @@ -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,
}
Expand Down

0 comments on commit 417c8ac

Please sign in to comment.