From 1dcb7cc7d95ce82fea31a5d7ac5a4d0d929e2aaf Mon Sep 17 00:00:00 2001 From: Fotis Papadogeorgopoulos Date: Fri, 24 Jan 2025 13:49:41 +0200 Subject: [PATCH] fix(npm): extract pnpm overrides with version ranges correctly (#33727) --- .../npm/extract/common/package-file.ts | 4 +- lib/modules/manager/npm/extract/index.spec.ts | 81 +++++++++++++++++++ lib/modules/manager/npm/readme.md | 3 + package.json | 1 + pnpm-lock.yaml | 73 ++++++++++++++++- 5 files changed, 160 insertions(+), 2 deletions(-) diff --git a/lib/modules/manager/npm/extract/common/package-file.ts b/lib/modules/manager/npm/extract/common/package-file.ts index b81fbf137fbdec..0e59b57cf70e96 100644 --- a/lib/modules/manager/npm/extract/common/package-file.ts +++ b/lib/modules/manager/npm/extract/common/package-file.ts @@ -1,3 +1,4 @@ +import { parsePkgAndParentSelector } from '@pnpm/parse-overrides'; import is from '@sindresorhus/is'; import { CONFIG_VALIDATION } from '../../../../../constants/error-messages'; import { logger } from '../../../../../logger'; @@ -91,7 +92,8 @@ export function extractPackageJson( )) { if (is.string(overridesVal)) { // Newer flat syntax: `parent>parent>child` - const packageName = overridesKey.split('>').pop()!; + const packageName = + parsePkgAndParentSelector(overridesKey).targetPkg.name; dep = { depName: overridesKey, packageName, diff --git a/lib/modules/manager/npm/extract/index.spec.ts b/lib/modules/manager/npm/extract/index.spec.ts index 715692c11896e8..ec54ac88b183d7 100644 --- a/lib/modules/manager/npm/extract/index.spec.ts +++ b/lib/modules/manager/npm/extract/index.spec.ts @@ -1027,6 +1027,87 @@ describe('modules/manager/npm/extract/index', () => { ], }); }); + + it('extracts dependencies from pnpm.overrides, with version ranges in flat syntax', async () => { + const content = codeBlock`{ + "pnpm": { + "overrides": { + "foo>bar": "2.0.0", + "foo@1.0.0": "2.0.0", + "foo@>1.0.0": "2.0.0", + "foo@>=1.0.0": "2.0.0", + "foo@1.0.0>bar": "2.0.0", + "foo@>1.0.0>bar": "2.0.0", + "foo@>=1.0.0 <2.0.0": ">=2.0.0" + } + } + }`; + const res = await npmExtract.extractPackageFile( + content, + 'package.json', + defaultExtractConfig, + ); + expect(res).toMatchObject({ + deps: [ + { + currentValue: '2.0.0', + datasource: 'npm', + depName: 'foo>bar', + depType: 'pnpm.overrides', + packageName: 'bar', + prettyDepType: 'overrides', + }, + { + currentValue: '2.0.0', + datasource: 'npm', + depName: 'foo@1.0.0', + depType: 'pnpm.overrides', + packageName: 'foo', + prettyDepType: 'overrides', + }, + { + currentValue: '2.0.0', + datasource: 'npm', + depName: 'foo@>1.0.0', + depType: 'pnpm.overrides', + packageName: 'foo', + prettyDepType: 'overrides', + }, + { + currentValue: '2.0.0', + datasource: 'npm', + depName: 'foo@>=1.0.0', + depType: 'pnpm.overrides', + packageName: 'foo', + prettyDepType: 'overrides', + }, + { + currentValue: '2.0.0', + datasource: 'npm', + depName: 'foo@1.0.0>bar', + depType: 'pnpm.overrides', + packageName: 'bar', + prettyDepType: 'overrides', + }, + { + currentValue: '2.0.0', + datasource: 'npm', + depName: 'foo@>1.0.0>bar', + depType: 'pnpm.overrides', + packageName: 'bar', + prettyDepType: 'overrides', + }, + { + currentValue: '>=2.0.0', + datasource: 'npm', + depName: 'foo@>=1.0.0 <2.0.0', + depType: 'pnpm.overrides', + packageName: 'foo', + prettyDepType: 'overrides', + }, + ], + }); + }); }); describe('.extractAllPackageFiles()', () => { diff --git a/lib/modules/manager/npm/readme.md b/lib/modules/manager/npm/readme.md index a5d8549e57ab5f..daf5ec9582bf7d 100644 --- a/lib/modules/manager/npm/readme.md +++ b/lib/modules/manager/npm/readme.md @@ -7,6 +7,9 @@ The following `depTypes` are currently supported by the npm manager : - `engines` : Renovate will update any `node`, `npm` and `yarn` version specified under `engines`. - `volta` : Renovate will update any `node`, `npm`, `pnpm` and `yarn` version specified under `volta`. - `packageManager` +- `overrides` +- `resolutions` +- `pnpm.overrides` ### Yarn diff --git a/package.json b/package.json index 1b91e586ad4fcf..052f6d353f8667 100644 --- a/package.json +++ b/package.json @@ -162,6 +162,7 @@ "@opentelemetry/sdk-trace-base": "1.30.1", "@opentelemetry/sdk-trace-node": "1.30.1", "@opentelemetry/semantic-conventions": "1.28.0", + "@pnpm/parse-overrides": "1000.0.1", "@qnighy/marshal": "0.1.3", "@renovatebot/detect-tools": "1.1.0", "@renovatebot/kbpgp": "4.0.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0db12ec4b7bc1c..b256727caa72e8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -65,6 +65,9 @@ importers: '@opentelemetry/semantic-conventions': specifier: 1.28.0 version: 1.28.0 + '@pnpm/parse-overrides': + specifier: 1000.0.1 + version: 1000.0.1 '@qnighy/marshal': specifier: 0.1.3 version: 0.1.3 @@ -1187,7 +1190,6 @@ packages: '@ls-lint/ls-lint@2.2.3': resolution: {integrity: sha512-ekM12jNm/7O2I/hsRv9HvYkRdfrHpiV1epVuI2NP+eTIcEgdIdKkKCs9KgQydu/8R5YXTov9aHdOgplmCHLupw==} - cpu: [x64, arm64, s390x] os: [darwin, linux, win32] hasBin: true @@ -1431,14 +1433,34 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} + '@pnpm/catalogs.protocol-parser@1000.0.0': + resolution: {integrity: sha512-8eC25RAiu8BTaEseQmbo5xemlSwl06pMsUVORiYGX7JZEDb0UQVXOnbqFFJMPe/dyO8uwGXnDb350nauMzaraA==} + engines: {node: '>=18.12'} + + '@pnpm/catalogs.resolver@1000.0.1': + resolution: {integrity: sha512-A6KdGQMYNiwBe7N4CuQXfxhHnHo1MBX+d+EiAm+CEXeVrKPhm2RmVHRcKkF+pBlr6vV/KHp9z5tF2B3+jFnnRw==} + engines: {node: '>=18.12'} + + '@pnpm/catalogs.types@1000.0.0': + resolution: {integrity: sha512-xRf72lk7xHNvbenA4sp4Of/90QDdRW0CRYT+V+EbqpUXu1xsXtedHai34cTU6VGe7C1hUukxxE9eYTtIpYrx5g==} + engines: {node: '>=18.12'} + '@pnpm/config.env-replace@1.1.0': resolution: {integrity: sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==} engines: {node: '>=12.22.0'} + '@pnpm/constants@1001.0.0': + resolution: {integrity: sha512-yg+S/e8goJoUC4CxyKAplT2fuI94G/nynshPCNkLsi69bUMim5iDMuiiiMo/LeMoOjuyfByealD3u1mqNXrl+A==} + engines: {node: '>=18.12'} + '@pnpm/constants@6.1.0': resolution: {integrity: sha512-L6AiU3OXv9kjKGTJN9j8n1TeJGDcLX9atQlZvAkthlvbXjvKc5SKNWESc/eXhr5nEfuMWhQhiKHDJCpYejmeCQ==} engines: {node: '>=14.19'} + '@pnpm/error@1000.0.1': + resolution: {integrity: sha512-FdDMjp9ORXK/JlxwjlNF7mRohVKx5pvM01bxsVUSLFLZ9/oMBtDceWlntUTLhvr2MwYcr69mGilTojnXEbsjQA==} + engines: {node: '>=18.12'} + '@pnpm/error@4.0.0': resolution: {integrity: sha512-NI4DFCMF6xb1SA0bZiiV5KrMCaJM2QmPJFC6p78FXujn7FpiRSWhT9r032wpuQumsl7DEmN4s3wl/P8TA+bL8w==} engines: {node: '>=14.6'} @@ -1455,6 +1477,14 @@ packages: resolution: {integrity: sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==} engines: {node: '>=12'} + '@pnpm/parse-overrides@1000.0.1': + resolution: {integrity: sha512-dr7dBAFYsS2XS483/Z2bwk1ng8OwK4ixK3H7/RIptG1yD1GgYf4rZR1jAvQdmyuyTttKE9jSAdJLNFPo0bTRug==} + engines: {node: '>=18.12'} + + '@pnpm/parse-wanted-dependency@1000.0.0': + resolution: {integrity: sha512-SKK9m7leIQ0u6S+/LXREF0wTrFnyKiirLza6Dt0l7CL9pZdZtuI3mMvz6gNBFnIjTKJPwacdqRywT3bfK8W+FQ==} + engines: {node: '>=18.12'} + '@pnpm/read-project-manifest@4.1.1': resolution: {integrity: sha512-jGNoofG8kkUlgAMX8fqbUwRRXYf4WcWdvi/y1Sv1abUfcoVgXW6GdGVm0MIJ+enaong3hXHjaLl/AwmSj6O1Uw==} engines: {node: '>=14.6'} @@ -2575,6 +2605,9 @@ packages: buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + builtins@5.1.0: + resolution: {integrity: sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==} + bunyan@1.8.15: resolution: {integrity: sha512-0tECWShh6wUysgucJcBAoYegf3JJoZWibxdqhTm7OHPeT42qdjkZ29QCMcKwbgU1kiH+auSIasNRXMLWXafXig==} engines: {'0': node >=0.10.0} @@ -6245,6 +6278,10 @@ packages: validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + validate-npm-package-name@5.0.0: + resolution: {integrity: sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + validate-npm-package-name@6.0.0: resolution: {integrity: sha512-d7KLgL1LD3U3fgnvWEY1cQXoO/q6EQ1BSz48Sa149V/5zVTAbgmZIpyI8TRi6U9/JNyeYLlTKsEMPtLC27RFUg==} engines: {node: ^18.17.0 || >=20.5.0} @@ -7997,10 +8034,25 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true + '@pnpm/catalogs.protocol-parser@1000.0.0': {} + + '@pnpm/catalogs.resolver@1000.0.1': + dependencies: + '@pnpm/catalogs.protocol-parser': 1000.0.0 + '@pnpm/error': 1000.0.1 + + '@pnpm/catalogs.types@1000.0.0': {} + '@pnpm/config.env-replace@1.1.0': {} + '@pnpm/constants@1001.0.0': {} + '@pnpm/constants@6.1.0': {} + '@pnpm/error@1000.0.1': + dependencies: + '@pnpm/constants': 1001.0.0 + '@pnpm/error@4.0.0': dependencies: '@pnpm/constants': 6.1.0 @@ -8019,6 +8071,17 @@ snapshots: '@pnpm/network.ca-file': 1.0.2 config-chain: 1.1.13 + '@pnpm/parse-overrides@1000.0.1': + dependencies: + '@pnpm/catalogs.resolver': 1000.0.1 + '@pnpm/catalogs.types': 1000.0.0 + '@pnpm/error': 1000.0.1 + '@pnpm/parse-wanted-dependency': 1000.0.0 + + '@pnpm/parse-wanted-dependency@1000.0.0': + dependencies: + validate-npm-package-name: 5.0.0 + '@pnpm/read-project-manifest@4.1.1': dependencies: '@gwhitney/detect-indent': 7.0.1 @@ -9419,6 +9482,10 @@ snapshots: ieee754: 1.2.1 optional: true + builtins@5.1.0: + dependencies: + semver: 7.6.3 + bunyan@1.8.15: {} bzip-deflate@1.0.0: {} @@ -13653,6 +13720,10 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 + validate-npm-package-name@5.0.0: + dependencies: + builtins: 5.1.0 + validate-npm-package-name@6.0.0: {} vfile-message@2.0.4: