diff --git a/lib/modules/manager/npm/extract/locked-versions.spec.ts b/lib/modules/manager/npm/extract/locked-versions.spec.ts index 18748268d0d6b435dace3eb845d6cb166805d48e..119eb2faba428bded6a674138e54a9e72c40f2df 100644 --- a/lib/modules/manager/npm/extract/locked-versions.spec.ts +++ b/lib/modules/manager/npm/extract/locked-versions.spec.ts @@ -552,6 +552,145 @@ describe('modules/manager/npm/extract/locked-versions', () => { ]); }); + it('uses pnpm-lock in subfolder', async () => { + pnpm.getPnpmLock.mockReturnValue({ + lockedVersionsWithPath: { + '.': { + dependencies: { + a: '1.0.0', + b: '2.0.0', + c: '3.0.0', + }, + }, + }, + lockfileVersion: 6.0, + }); + const packageFiles = [ + { + managerData: { + pnpmShrinkwrap: 'subfolder/pnpm-lock.yaml', + }, + extractedConstraints: { + pnpm: '>=6.0.0', + }, + deps: [ + { + depName: 'a', + depType: 'dependencies', + currentValue: '1.0.0', + }, + { + depName: 'b', + depType: 'dependencies', + currentValue: '2.0.0', + }, + ], + packageFile: 'subfolder/package.json', + }, + ]; + await getLockedVersions(packageFiles); + expect(packageFiles).toEqual([ + { + extractedConstraints: { pnpm: '>=6.0.0' }, + deps: [ + { + currentValue: '1.0.0', + depName: 'a', + lockedVersion: '1.0.0', + depType: 'dependencies', + }, + { + currentValue: '2.0.0', + depName: 'b', + lockedVersion: '2.0.0', + depType: 'dependencies', + }, + ], + lockFiles: ['subfolder/pnpm-lock.yaml'], + managerData: { pnpmShrinkwrap: 'subfolder/pnpm-lock.yaml' }, + packageFile: 'subfolder/package.json', + }, + ]); + }); + + it('uses pnpm-lock with workspaces', async () => { + pnpm.getPnpmLock.mockReturnValue({ + lockedVersionsWithPath: { + 'workspace-package': { + dependencies: { + a: '1.0.0', + b: '2.0.0', + c: '3.0.0', + }, + }, + }, + lockfileVersion: 6.0, + }); + const packageFiles = [ + { + managerData: { + pnpmShrinkwrap: 'subfolder/pnpm-lock.yaml', + }, + extractedConstraints: { + pnpm: '>=6.0.0', + }, + deps: [], + packageFile: 'subfolder/package.json', + }, + { + managerData: { + pnpmShrinkwrap: 'subfolder/pnpm-lock.yaml', + }, + extractedConstraints: { + pnpm: '>=6.0.0', + }, + deps: [ + { + depName: 'a', + depType: 'dependencies', + currentValue: '1.0.0', + }, + { + depName: 'b', + depType: 'dependencies', + currentValue: '2.0.0', + }, + ], + packageFile: 'subfolder/workspace-package/package.json', + }, + ]; + await getLockedVersions(packageFiles); + expect(packageFiles).toEqual([ + { + extractedConstraints: { pnpm: '>=6.0.0' }, + deps: [], + lockFiles: ['subfolder/pnpm-lock.yaml'], + managerData: { pnpmShrinkwrap: 'subfolder/pnpm-lock.yaml' }, + packageFile: 'subfolder/package.json', + }, + { + extractedConstraints: { pnpm: '>=6.0.0' }, + deps: [ + { + currentValue: '1.0.0', + depName: 'a', + lockedVersion: '1.0.0', + depType: 'dependencies', + }, + { + currentValue: '2.0.0', + depName: 'b', + lockedVersion: '2.0.0', + depType: 'dependencies', + }, + ], + lockFiles: ['subfolder/pnpm-lock.yaml'], + managerData: { pnpmShrinkwrap: 'subfolder/pnpm-lock.yaml' }, + packageFile: 'subfolder/workspace-package/package.json', + }, + ]); + }); + it('should log warning if unsupported lockfileVersion is found', async () => { npm.getNpmLock.mockReturnValue({ lockedVersions: {}, diff --git a/lib/modules/manager/npm/extract/locked-versions.ts b/lib/modules/manager/npm/extract/locked-versions.ts index 17caf3d5080a9c84b0831299d7f97338c82f44a9..676dd13ea252d7071bc03f6477d135e1cbd4508c 100644 --- a/lib/modules/manager/npm/extract/locked-versions.ts +++ b/lib/modules/manager/npm/extract/locked-versions.ts @@ -1,5 +1,6 @@ import is from '@sindresorhus/is'; import semver from 'semver'; +import { dirname, relative } from 'upath'; import { logger } from '../../../../logger'; import type { PackageFile } from '../../types'; import type { NpmManagerData } from '../types'; @@ -124,14 +125,15 @@ export async function getLockedVersions( lockFileCache[pnpmShrinkwrap] = await getPnpmLock(pnpmShrinkwrap); } - const parentDir = packageFile.packageFile - .replace(/\/package\.json$/, '') - .replace(/^package\.json$/, '.'); + const packageDir = dirname(packageFile.packageFile); + const pnpmRootDir = dirname(pnpmShrinkwrap); + const relativeDir = relative(pnpmRootDir, packageDir) || '.'; + for (const dep of packageFile.deps) { const { depName, depType } = dep; // TODO: types (#7154) const lockedVersion = semver.valid( - lockFileCache[pnpmShrinkwrap].lockedVersionsWithPath?.[parentDir]?.[ + lockFileCache[pnpmShrinkwrap].lockedVersionsWithPath?.[relativeDir]?.[ depType! ]?.[depName!] );