From add954f37e28fb33dd340333a3e660fec4d29bc7 Mon Sep 17 00:00:00 2001 From: Michael Kriese Date: Wed, 17 Apr 2024 11:21:26 +0200 Subject: [PATCH 1/2] feat(npm): support pnpm v9 --- .../manager/npm/post-update/index.spec.ts | 1 - lib/modules/manager/npm/post-update/index.ts | 7 --- .../manager/npm/post-update/pnpm.spec.ts | 14 ++++- lib/modules/manager/npm/post-update/pnpm.ts | 55 ++++++++++++------- 4 files changed, 49 insertions(+), 28 deletions(-) diff --git a/lib/modules/manager/npm/post-update/index.spec.ts b/lib/modules/manager/npm/post-update/index.spec.ts index 1acaa10f789899..d2a3ea252aa798 100644 --- a/lib/modules/manager/npm/post-update/index.spec.ts +++ b/lib/modules/manager/npm/post-update/index.spec.ts @@ -217,7 +217,6 @@ describe('modules/manager/npm/post-update/index', () => { ['package-lock.json'], ['yarn.lock'], ['yarn.lock'], - ['packages/pnpm/pnpm-lock.yaml'], ]); }); diff --git a/lib/modules/manager/npm/post-update/index.ts b/lib/modules/manager/npm/post-update/index.ts index 9e31b228843d4e..911e08e91e5bd2 100644 --- a/lib/modules/manager/npm/post-update/index.ts +++ b/lib/modules/manager/npm/post-update/index.ts @@ -226,13 +226,6 @@ export async function writeExistingFiles( if (yarnLock && config.reuseLockFiles === false) { await deleteLocalFile(yarnLock); } - // istanbul ignore next - if ( - packageFile.managerData.pnpmShrinkwrap && - config.reuseLockFiles === false - ) { - await deleteLocalFile(packageFile.managerData.pnpmShrinkwrap); - } } } diff --git a/lib/modules/manager/npm/post-update/pnpm.spec.ts b/lib/modules/manager/npm/post-update/pnpm.spec.ts index 8ba7ba957a3b9c..6c9d28db1b8a50 100644 --- a/lib/modules/manager/npm/post-update/pnpm.spec.ts +++ b/lib/modules/manager/npm/post-update/pnpm.spec.ts @@ -360,7 +360,7 @@ describe('modules/manager/npm/post-update/pnpm', () => { expect(res).toBeNull(); }); - it('returns null if lockfileVersion is not a number', async () => { + it('returns null if lockfileVersion is not a number or numeric string', async () => { fs.readLocalFile.mockResolvedValueOnce('lockfileVersion: foo\n'); const res = await pnpmHelper.getConstraintFromLockFile('some-file-name'); expect(res).toBeNull(); @@ -377,5 +377,17 @@ describe('modules/manager/npm/post-update/pnpm', () => { const res = await pnpmHelper.getConstraintFromLockFile('some-file-name'); expect(res).toBe('>=6 <7'); }); + + it('maps supported versions for v6', async () => { + fs.readLocalFile.mockResolvedValueOnce("lockfileVersion: '6.0'\n"); + const res = await pnpmHelper.getConstraintFromLockFile('some-file-name'); + expect(res).toBe('>=7.24.2 <9'); + }); + + it('maps supported versions for v9', async () => { + fs.readLocalFile.mockResolvedValueOnce("lockfileVersion: '9.0'\n"); + const res = await pnpmHelper.getConstraintFromLockFile('some-file-name'); + expect(res).toBe('>=9'); + }); }); }); diff --git a/lib/modules/manager/npm/post-update/pnpm.ts b/lib/modules/manager/npm/post-update/pnpm.ts index 13348c851fa631..73e5b085e8a1c6 100644 --- a/lib/modules/manager/npm/post-update/pnpm.ts +++ b/lib/modules/manager/npm/post-update/pnpm.ts @@ -144,11 +144,16 @@ export async function getConstraintFromLockFile( try { const lockfileContent = await readLocalFile(lockFileName, 'utf8'); if (!lockfileContent) { + logger.trace(`Empty pnpm lock file: ${lockFileName}`); return null; } // TODO: use schema (#9610) const pnpmLock = parseSingleYaml(lockfileContent); - if (!is.number(pnpmLock?.lockfileVersion)) { + if ( + !is.number(pnpmLock?.lockfileVersion) && + !is.numericString(pnpmLock?.lockfileVersion) + ) { + logger.trace(`Invalid pnpm lockfile version: ${lockFileName}`); return null; } // find matching lockfileVersion and use its constraints @@ -172,25 +177,31 @@ export async function getConstraintFromLockFile( } /** - pnpm lockfiles have corresponding version numbers called "lockfileVersion" - each lockfileVersion can only be generated by a certain pnpm version ranges - eg. lockfileVersion: 5.4 can only be generated by pnpm version >=7 && <8 - official list can be found here : https://github.com/pnpm/spec/tree/master/lockfile - we use the mapping present below to find the compatible pnpm version range for a given lockfileVersion - - the various terms used in the mapping are explained below: - lowerConstriant : lowest pnpm version that can generate the lockfileVersion - upperConstraint : highest pnpm version that can generate the lockfileVersion - lowerBound : highest pnpm version that is less than the lowerConstraint - upperBound : lowest pnpm version that is greater than upperConstraint - - For handling future lockfileVersions, we need to: - 1. add a upperBound and upperConstraint to the current lastest lockfileVersion - 2. add an object for the new lockfileVersion with lowerBound and lowerConstraint + * pnpm lockfiles have corresponding version numbers called "lockfileVersion" + * each lockfileVersion can only be generated by a certain pnpm version ranges + * eg. lockfileVersion: 5.4 can only be generated by pnpm version >=7 && <8 + * official list can be found here : https://github.com/pnpm/spec/tree/master/lockfile + * we use the mapping present below to find the compatible pnpm version range for a given lockfileVersion + * + * the various terms used in the mapping are explained below: + * lowerConstriant : lowest pnpm version that can generate the lockfileVersion + * upperConstraint : highest pnpm version that can generate the lockfileVersion + * lowerBound : highest pnpm version that is less than the lowerConstraint + * upperBound : lowest pnpm version that is greater than upperConstraint + * + * For handling future lockfileVersions, we need to: + * 1. add a upperBound and upperConstraint to the current lastest lockfileVersion + * 2. add an object for the new lockfileVersion with lowerBound and lowerConstraint + * + * lockfileVersion from v6 on are strings */ - -const lockToPnpmVersionMapping = [ - { lockfileVersion: 6.0, lowerConstraint: '>=7.24.2' }, +const lockToPnpmVersionMapping: LockToPnpmVersionMapping[] = [ + { lockfileVersion: '9.0', lowerConstraint: '>=9' }, + { + lockfileVersion: '6.0', + lowerConstraint: '>=7.24.2', + upperConstraint: '<9', + }, { lockfileVersion: 5.4, lowerConstraint: '>=7', @@ -212,3 +223,9 @@ const lockToPnpmVersionMapping = [ upperConstraint: '<5.9.3', }, ]; + +type LockToPnpmVersionMapping = { + lockfileVersion: string | number; + lowerConstraint: string; + upperConstraint?: string; +}; From 2a1f68cdfb44615e2c9a9adc850fb7c34eac7b5d Mon Sep 17 00:00:00 2001 From: Michael Kriese Date: Wed, 17 Apr 2024 11:55:55 +0200 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com> --- lib/modules/manager/npm/post-update/pnpm.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/modules/manager/npm/post-update/pnpm.ts b/lib/modules/manager/npm/post-update/pnpm.ts index 73e5b085e8a1c6..b696dc626cc1e6 100644 --- a/lib/modules/manager/npm/post-update/pnpm.ts +++ b/lib/modules/manager/npm/post-update/pnpm.ts @@ -178,19 +178,19 @@ export async function getConstraintFromLockFile( /** * pnpm lockfiles have corresponding version numbers called "lockfileVersion" - * each lockfileVersion can only be generated by a certain pnpm version ranges + * each lockfileVersion can only be generated by a certain pnpm version range * eg. lockfileVersion: 5.4 can only be generated by pnpm version >=7 && <8 * official list can be found here : https://github.com/pnpm/spec/tree/master/lockfile * we use the mapping present below to find the compatible pnpm version range for a given lockfileVersion * * the various terms used in the mapping are explained below: - * lowerConstriant : lowest pnpm version that can generate the lockfileVersion + * lowerConstraint : lowest pnpm version that can generate the lockfileVersion * upperConstraint : highest pnpm version that can generate the lockfileVersion * lowerBound : highest pnpm version that is less than the lowerConstraint - * upperBound : lowest pnpm version that is greater than upperConstraint + * upperBound : lowest pnpm version that is greater than the upperConstraint * - * For handling future lockfileVersions, we need to: - * 1. add a upperBound and upperConstraint to the current lastest lockfileVersion + * To handle future lockfileVersions, we need to: + * 1. add a upperBound and upperConstraint to the current latest lockfileVersion * 2. add an object for the new lockfileVersion with lowerBound and lowerConstraint * * lockfileVersion from v6 on are strings