Skip to content

Commit

Permalink
feat(npm): support pnpm v9 (#28470)
Browse files Browse the repository at this point in the history
Co-authored-by: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com>
  • Loading branch information
viceice and HonkingGoose committed Apr 17, 2024
1 parent 0a43865 commit b652e85
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 28 deletions.
1 change: 0 additions & 1 deletion lib/modules/manager/npm/post-update/index.spec.ts
Expand Up @@ -217,7 +217,6 @@ describe('modules/manager/npm/post-update/index', () => {
['package-lock.json'],
['yarn.lock'],
['yarn.lock'],
['packages/pnpm/pnpm-lock.yaml'],
]);
});

Expand Down
7 changes: 0 additions & 7 deletions lib/modules/manager/npm/post-update/index.ts
Expand Up @@ -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);
}
}
}

Expand Down
14 changes: 13 additions & 1 deletion lib/modules/manager/npm/post-update/pnpm.spec.ts
Expand Up @@ -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();
Expand All @@ -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');
});
});
});
55 changes: 36 additions & 19 deletions lib/modules/manager/npm/post-update/pnpm.ts
Expand Up @@ -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<PnpmLockFile>(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
Expand All @@ -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 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:
* 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 the upperConstraint
*
* 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
*/

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',
Expand All @@ -212,3 +223,9 @@ const lockToPnpmVersionMapping = [
upperConstraint: '<5.9.3',
},
];

type LockToPnpmVersionMapping = {
lockfileVersion: string | number;
lowerConstraint: string;
upperConstraint?: string;
};

0 comments on commit b652e85

Please sign in to comment.