From 06af3eeb581a4ce3e50e8b3e400dcaeff2c14846 Mon Sep 17 00:00:00 2001
From: Norbert Szulc <norbert@not7cd.net>
Date: Sat, 10 Feb 2024 16:04:43 +0100
Subject: [PATCH] feat(manager/pip_requirements): Add managerData with layered
 requirements (#27217)

---
 .../manager/pip_requirements/extract.spec.ts  | 22 ++++++++++++++++++
 .../manager/pip_requirements/extract.ts       | 23 ++++++++++++++++++-
 lib/modules/manager/pip_requirements/types.ts |  4 ++++
 3 files changed, 48 insertions(+), 1 deletion(-)
 create mode 100644 lib/modules/manager/pip_requirements/types.ts

diff --git a/lib/modules/manager/pip_requirements/extract.spec.ts b/lib/modules/manager/pip_requirements/extract.spec.ts
index 62aa0ae7a3..84eface817 100644
--- a/lib/modules/manager/pip_requirements/extract.spec.ts
+++ b/lib/modules/manager/pip_requirements/extract.spec.ts
@@ -65,6 +65,28 @@ some-package==0.3.1`;
       });
     });
 
+    it('extracts --requirement short code option', () => {
+      const requirements = `-r base.txt
+some-package==0.3.1`;
+
+      const res = extractPackageFile(requirements);
+
+      expect(res).toHaveProperty('managerData', {
+        requirementsFiles: ['base.txt'],
+      });
+    });
+
+    it('extracts --constraints short code option', () => {
+      const requirements = `-c constrain.txt
+some-package==0.3.1`;
+
+      const res = extractPackageFile(requirements);
+
+      expect(res).toHaveProperty('managerData', {
+        constraintsFiles: ['constrain.txt'],
+      });
+    });
+
     it('extracts multiple dependencies', () => {
       const res = extractPackageFile(requirements2)?.deps;
       expect(res).toMatchSnapshot();
diff --git a/lib/modules/manager/pip_requirements/extract.ts b/lib/modules/manager/pip_requirements/extract.ts
index 61e97e375a..bf29df3577 100644
--- a/lib/modules/manager/pip_requirements/extract.ts
+++ b/lib/modules/manager/pip_requirements/extract.ts
@@ -8,6 +8,7 @@ import { newlineRegex, regEx } from '../../../util/regex';
 import { GitTagsDatasource } from '../../datasource/git-tags';
 import { PypiDatasource } from '../../datasource/pypi';
 import type { PackageDependency, PackageFileContent } from '../types';
+import type { PipRequirementsManagerData } from './types';
 
 export const packagePattern =
   '[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9]';
@@ -46,11 +47,15 @@ export function cleanRegistryUrls(registryUrls: string[]): string[] {
   });
 }
 
-export function extractPackageFile(content: string): PackageFileContent | null {
+export function extractPackageFile(
+  content: string,
+): PackageFileContent<PipRequirementsManagerData> | null {
   logger.trace('pip_requirements.extractPackageFile()');
 
   let registryUrls: string[] = [];
   const additionalRegistryUrls: string[] = [];
+  const additionalRequirementsFiles: string[] = [];
+  const additionalConstraintsFiles: string[] = [];
   content.split(newlineRegex).forEach((line) => {
     if (line.startsWith('-i ') || line.startsWith('--index-url ')) {
       registryUrls = [line.split(' ')[1]];
@@ -59,6 +64,10 @@ export function extractPackageFile(content: string): PackageFileContent | null {
         .substring('--extra-index-url '.length)
         .split(' ')[0];
       additionalRegistryUrls.push(extraUrl);
+    } else if (line.startsWith('-r ')) {
+      additionalRequirementsFiles.push(line.split(' ')[1]);
+    } else if (line.startsWith('-c ')) {
+      additionalConstraintsFiles.push(line.split(' ')[1]);
     }
   });
 
@@ -132,5 +141,17 @@ export function extractPackageFile(content: string): PackageFileContent | null {
   if (additionalRegistryUrls.length) {
     res.additionalRegistryUrls = cleanRegistryUrls(additionalRegistryUrls);
   }
+  if (additionalRequirementsFiles.length) {
+    if (!res.managerData) {
+      res.managerData = {};
+    }
+    res.managerData.requirementsFiles = additionalRequirementsFiles;
+  }
+  if (additionalConstraintsFiles.length) {
+    if (!res.managerData) {
+      res.managerData = {};
+    }
+    res.managerData.constraintsFiles = additionalConstraintsFiles;
+  }
   return res;
 }
diff --git a/lib/modules/manager/pip_requirements/types.ts b/lib/modules/manager/pip_requirements/types.ts
new file mode 100644
index 0000000000..5cd5e79db6
--- /dev/null
+++ b/lib/modules/manager/pip_requirements/types.ts
@@ -0,0 +1,4 @@
+export interface PipRequirementsManagerData {
+  requirementsFiles?: string[];
+  constraintsFiles?: string[];
+}
-- 
GitLab