From 015391c70e7eed35ab610e4f3c484899acf5ef97 Mon Sep 17 00:00:00 2001
From: Rhys Arkins <rhys@arkins.net>
Date: Mon, 14 Jun 2021 08:55:38 +0200
Subject: [PATCH] refactor(pip_requirements): extractAllPackageFiles (#10414)

---
 .../__fixtures__/requirements1.txt            |  2 +-
 .../__snapshots__/extract.spec.ts.snap        | 31 +++++++++++++++++++
 lib/manager/pip_requirements/extract.spec.ts  | 16 ++++++++--
 lib/manager/pip_requirements/extract.ts       | 24 ++++++++++++++
 lib/manager/pip_requirements/index.ts         |  2 +-
 5 files changed, 71 insertions(+), 4 deletions(-)

diff --git a/lib/manager/pip_requirements/__fixtures__/requirements1.txt b/lib/manager/pip_requirements/__fixtures__/requirements1.txt
index 23aaa25e90..fbee0f3f42 100644
--- a/lib/manager/pip_requirements/__fixtures__/requirements1.txt
+++ b/lib/manager/pip_requirements/__fixtures__/requirements1.txt
@@ -3,4 +3,4 @@
 some-package==0.3.1
 some-other-package==1.0.0
 not_semver==1.9
-
+unconstrained
diff --git a/lib/manager/pip_requirements/__snapshots__/extract.spec.ts.snap b/lib/manager/pip_requirements/__snapshots__/extract.spec.ts.snap
index 325dfdbde1..b0c232a42c 100644
--- a/lib/manager/pip_requirements/__snapshots__/extract.spec.ts.snap
+++ b/lib/manager/pip_requirements/__snapshots__/extract.spec.ts.snap
@@ -63,6 +63,37 @@ Array [
 ]
 `;
 
+exports[`manager/pip_requirements/extract extractPackageFile() extracts using extractAllPackageFiles 1`] = `
+Array [
+  Object {
+    "deps": Array [
+      Object {
+        "currentValue": "==0.3.1",
+        "currentVersion": "0.3.1",
+        "datasource": "pypi",
+        "depName": "some-package",
+      },
+      Object {
+        "currentValue": "==1.0.0",
+        "currentVersion": "1.0.0",
+        "datasource": "pypi",
+        "depName": "some-other-package",
+      },
+      Object {
+        "currentValue": "==1.9",
+        "currentVersion": "1.9",
+        "datasource": "pypi",
+        "depName": "not_semver",
+      },
+    ],
+    "packageFile": "unused_file_name",
+    "registryUrls": Array [
+      "http://example.com/private-pypi/",
+    ],
+  },
+]
+`;
+
 exports[`manager/pip_requirements/extract extractPackageFile() handles comments and commands 1`] = `
 Array [
   Object {
diff --git a/lib/manager/pip_requirements/extract.spec.ts b/lib/manager/pip_requirements/extract.spec.ts
index b73af574fa..471d7bd72b 100644
--- a/lib/manager/pip_requirements/extract.spec.ts
+++ b/lib/manager/pip_requirements/extract.spec.ts
@@ -1,6 +1,8 @@
-import { getName, loadFixture } from '../../../test/util';
+import { fs, getName, loadFixture } from '../../../test/util';
 import { setAdminConfig } from '../../config/admin';
-import { extractPackageFile } from './extract';
+import { extractAllPackageFiles, extractPackageFile } from './extract';
+
+jest.mock('../../util/fs');
 
 const requirements1 = loadFixture('requirements1.txt');
 const requirements2 = loadFixture('requirements2.txt');
@@ -41,6 +43,16 @@ describe(getName(), () => {
       expect(res.registryUrls).toEqual(['http://example.com/private-pypi/']);
       expect(res.deps).toHaveLength(3);
     });
+    it('extracts using extractAllPackageFiles', async () => {
+      fs.readLocalFile.mockResolvedValueOnce(requirements1);
+      const outerRes = await extractAllPackageFiles(config, [
+        'unused_file_name',
+      ]);
+      expect(outerRes).toMatchSnapshot();
+      const [res] = outerRes;
+      expect(res.registryUrls).toEqual(['http://example.com/private-pypi/']);
+      expect(res.deps).toHaveLength(3);
+    });
     it('extracts multiple dependencies', () => {
       const res = extractPackageFile(
         requirements2,
diff --git a/lib/manager/pip_requirements/extract.ts b/lib/manager/pip_requirements/extract.ts
index f5e357bbea..64070e88b1 100644
--- a/lib/manager/pip_requirements/extract.ts
+++ b/lib/manager/pip_requirements/extract.ts
@@ -4,6 +4,7 @@ import { getAdminConfig } from '../../config/admin';
 import * as datasourcePypi from '../../datasource/pypi';
 import { logger } from '../../logger';
 import { SkipReason } from '../../types';
+import { readLocalFile } from '../../util/fs';
 import { isSkipComment } from '../../util/ignore';
 import type { ExtractConfig, PackageDependency, PackageFile } from '../types';
 
@@ -101,3 +102,26 @@ export function extractPackageFile(
   }
   return res;
 }
+
+export async function extractAllPackageFiles(
+  config: ExtractConfig,
+  packageFiles: string[]
+): Promise<PackageFile[]> {
+  const requirementsFiles: PackageFile[] = [];
+  for (const packageFile of packageFiles) {
+    const content = await readLocalFile(packageFile, 'utf8');
+    // istanbul ignore else
+    if (content) {
+      const deps = extractPackageFile(content, packageFile, config);
+      if (deps) {
+        requirementsFiles.push({
+          packageFile,
+          ...deps,
+        });
+      }
+    } else {
+      logger.debug({ packageFile }, 'requirements file has no content');
+    }
+  }
+  return requirementsFiles;
+}
diff --git a/lib/manager/pip_requirements/index.ts b/lib/manager/pip_requirements/index.ts
index b2c951aa37..b57282d7f9 100644
--- a/lib/manager/pip_requirements/index.ts
+++ b/lib/manager/pip_requirements/index.ts
@@ -1,7 +1,7 @@
 import { LANGUAGE_PYTHON } from '../../constants/languages';
 
 export { updateArtifacts } from './artifacts';
-export { extractPackageFile } from './extract';
+export { extractAllPackageFiles } from './extract';
 export { getRangeStrategy } from './range';
 
 export const language = LANGUAGE_PYTHON;
-- 
GitLab