From 2a08238f046d65dafb9a0338fbfd9948faf609fd Mon Sep 17 00:00:00 2001 From: Miles Budnek Date: Fri, 7 Jun 2024 02:11:39 -0400 Subject: [PATCH] feat(pip-compile): Treat included paths as relative to the package file (#29499) --- .../manager/pip-compile/extract.spec.ts | 56 +++++++++++++++++++ lib/modules/manager/pip-compile/extract.ts | 8 +++ 2 files changed, 64 insertions(+) diff --git a/lib/modules/manager/pip-compile/extract.spec.ts b/lib/modules/manager/pip-compile/extract.spec.ts index daabb05c5edb42..cab96c8f09c36e 100644 --- a/lib/modules/manager/pip-compile/extract.spec.ts +++ b/lib/modules/manager/pip-compile/extract.spec.ts @@ -602,4 +602,60 @@ describe('modules/manager/pip-compile/extract', () => { ['dash_r.txt'], ]); }); + + it('handles -r dependency on file with relative path same dir', async () => { + fs.readLocalFile.mockImplementation((name): any => { + if (name === 'dir/1.in') { + return 'foo'; + } else if (name === 'dir/2.in') { + return '-r 1.in\nbar'; + } else if (name === 'dir/1.txt') { + return getSimpleRequirementsFile( + 'pip-compile --output-file=1.txt 1.in', + ['foo==1.0.1'], + ); + } else if (name === 'dir/2.txt') { + return getSimpleRequirementsFile( + 'pip-compile --output-file=2.txt 2.in', + ['foo==1.0.1', 'bar==2.0.0'], + ); + } + return null; + }); + + const lockFiles = ['dir/1.txt', 'dir/2.txt']; + const packageFiles = await extractAllPackageFiles({}, lockFiles); + expect(packageFiles).toMatchObject([ + { packageFile: 'dir/1.in', lockFiles: ['dir/1.txt', 'dir/2.txt'] }, + { packageFile: 'dir/2.in', lockFiles: ['dir/2.txt'] }, + ]); + }); + + it('handles -r dependency on file with relative path above', async () => { + fs.readLocalFile.mockImplementation((name): any => { + if (name === 'common/1.in') { + return 'foo'; + } else if (name === 'dir/2.in') { + return '-r ../common/1.in\nbar'; + } else if (name === 'common/1.txt') { + return getSimpleRequirementsFile( + 'pip-compile --output-file=1.txt 1.in', + ['foo==1.0.1'], + ); + } else if (name === 'dir/2.txt') { + return getSimpleRequirementsFile( + 'pip-compile --output-file=2.txt 2.in', + ['foo==1.0.1', 'bar==2.0.0'], + ); + } + return null; + }); + + const lockFiles = ['common/1.txt', 'dir/2.txt']; + const packageFiles = await extractAllPackageFiles({}, lockFiles); + expect(packageFiles).toMatchObject([ + { packageFile: 'common/1.in', lockFiles: ['common/1.txt', 'dir/2.txt'] }, + { packageFile: 'dir/2.in', lockFiles: ['dir/2.txt'] }, + ]); + }); }); diff --git a/lib/modules/manager/pip-compile/extract.ts b/lib/modules/manager/pip-compile/extract.ts index 8381113fb41ce1..9960fb3b4c7b9c 100644 --- a/lib/modules/manager/pip-compile/extract.ts +++ b/lib/modules/manager/pip-compile/extract.ts @@ -138,6 +138,10 @@ export async function extractAllPackageFiles( ); if (packageFileContent) { if (packageFileContent.managerData?.requirementsFiles) { + packageFileContent.managerData.requirementsFiles = + packageFileContent.managerData.requirementsFiles.map( + (file: string) => upath.normalize(upath.join(compileDir, file)), + ); for (const file of packageFileContent.managerData.requirementsFiles) { depsBetweenFiles.push({ sourceFile: file, @@ -147,6 +151,10 @@ export async function extractAllPackageFiles( } } if (packageFileContent.managerData?.constraintsFiles) { + packageFileContent.managerData.constraintsFiles = + packageFileContent.managerData.constraintsFiles.map( + (file: string) => upath.normalize(upath.join(compileDir, file)), + ); for (const file of packageFileContent.managerData.constraintsFiles) { depsBetweenFiles.push({ sourceFile: file,