From ab09e25e9cefe8327cd852dc3193c09f2f74ab1a Mon Sep 17 00:00:00 2001
From: Sergei Zharinov <zharinov@users.noreply.github.com>
Date: Sun, 8 Dec 2024 04:33:31 -0300
Subject: [PATCH] refactor: Simplify lookup function (#32968)

---
 .../process/__snapshots__/fetch.spec.ts.snap  | 56 --------------
 lib/workers/repository/process/fetch.spec.ts  | 45 ++++++++++-
 lib/workers/repository/process/fetch.ts       | 77 ++++++++++++-------
 3 files changed, 92 insertions(+), 86 deletions(-)
 delete mode 100644 lib/workers/repository/process/__snapshots__/fetch.spec.ts.snap

diff --git a/lib/workers/repository/process/__snapshots__/fetch.spec.ts.snap b/lib/workers/repository/process/__snapshots__/fetch.spec.ts.snap
deleted file mode 100644
index 8352aa00ba..0000000000
--- a/lib/workers/repository/process/__snapshots__/fetch.spec.ts.snap
+++ /dev/null
@@ -1,56 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`workers/repository/process/fetch fetchUpdates() fetches updates 1`] = `
-{
-  "maven": [
-    {
-      "deps": [
-        {
-          "datasource": "maven",
-          "depName": "bbb",
-          "packageName": "bbb",
-          "updates": [
-            "a",
-            "b",
-          ],
-        },
-      ],
-      "extractedConstraints": {
-        "other": "constraint",
-        "some": "constraint",
-      },
-      "packageFile": "pom.xml",
-    },
-  ],
-}
-`;
-
-exports[`workers/repository/process/fetch fetchUpdates() handles ignored, skipped and disabled 1`] = `
-{
-  "npm": [
-    {
-      "deps": [
-        {
-          "depName": "abcd",
-          "packageName": "abcd",
-          "skipReason": "ignored",
-          "updates": [],
-        },
-        {
-          "depName": "foo",
-          "packageName": "foo",
-          "skipReason": "disabled",
-          "updates": [],
-        },
-        {
-          "depName": "skipped",
-          "packageName": "skipped",
-          "skipReason": "some-reason",
-          "updates": [],
-        },
-      ],
-      "packageFile": "package.json",
-    },
-  ],
-}
-`;
diff --git a/lib/workers/repository/process/fetch.spec.ts b/lib/workers/repository/process/fetch.spec.ts
index 172a6cb456..0ad23785fe 100644
--- a/lib/workers/repository/process/fetch.spec.ts
+++ b/lib/workers/repository/process/fetch.spec.ts
@@ -50,7 +50,33 @@ describe('workers/repository/process/fetch', () => {
         ],
       };
       await fetchUpdates(config, packageFiles);
-      expect(packageFiles).toMatchSnapshot();
+      expect(packageFiles).toEqual({
+        npm: [
+          {
+            deps: [
+              {
+                depName: 'abcd',
+                packageName: 'abcd',
+                skipReason: 'ignored',
+                updates: [],
+              },
+              {
+                depName: 'foo',
+                packageName: 'foo',
+                skipReason: 'disabled',
+                updates: [],
+              },
+              {
+                depName: 'skipped',
+                packageName: 'skipped',
+                skipReason: 'some-reason',
+                updates: [],
+              },
+            ],
+            packageFile: 'package.json',
+          },
+        ],
+      });
       expect(packageFiles.npm[0].deps[0].skipReason).toBe('ignored');
       expect(packageFiles.npm[0].deps[0].updates).toHaveLength(0);
       expect(packageFiles.npm[0].deps[1].skipReason).toBe('disabled');
@@ -71,7 +97,22 @@ describe('workers/repository/process/fetch', () => {
       };
       lookupUpdates.mockResolvedValue({ updates: ['a', 'b'] } as never);
       await fetchUpdates(config, packageFiles);
-      expect(packageFiles).toMatchSnapshot();
+      expect(packageFiles).toEqual({
+        maven: [
+          {
+            deps: [
+              {
+                datasource: 'maven',
+                depName: 'bbb',
+                packageName: 'bbb',
+                updates: ['a', 'b'],
+              },
+            ],
+            extractedConstraints: { other: 'constraint', some: 'constraint' },
+            packageFile: 'pom.xml',
+          },
+        ],
+      });
     });
 
     it('skips deps with empty names', async () => {
diff --git a/lib/workers/repository/process/fetch.ts b/lib/workers/repository/process/fetch.ts
index 4a4aed2c31..6b3fcb3860 100644
--- a/lib/workers/repository/process/fetch.ts
+++ b/lib/workers/repository/process/fetch.ts
@@ -17,27 +17,38 @@ import { Result } from '../../../util/result';
 import { LookupStats } from '../../../util/stats';
 import { PackageFiles } from '../package-files';
 import { lookupUpdates } from './lookup';
-import type { LookupUpdateConfig } from './lookup/types';
+import type { LookupUpdateConfig, UpdateResult } from './lookup/types';
 
-async function fetchDepUpdates(
+type LookupResult = Result<PackageDependency, Error>;
+
+async function lookup(
   packageFileConfig: RenovateConfig & PackageFile,
   indep: PackageDependency,
-): Promise<Result<PackageDependency, Error>> {
+): Promise<LookupResult> {
   const dep = clone(indep);
+
   dep.updates = [];
+
   if (is.string(dep.depName)) {
     dep.depName = dep.depName.trim();
   }
+
   dep.packageName ??= dep.depName;
+
+  if (dep.skipReason) {
+    return Result.ok(dep);
+  }
+
   if (!is.nonEmptyString(dep.packageName)) {
     dep.skipReason = 'invalid-name';
+    return Result.ok(dep);
   }
+
   if (dep.isInternal && !packageFileConfig.updateInternalDeps) {
     dep.skipReason = 'internal-package';
-  }
-  if (dep.skipReason) {
     return Result.ok(dep);
   }
+
   const { depName } = dep;
   // TODO: fix types
   let depConfig = mergeChildConfig(packageFileConfig, dep);
@@ -46,24 +57,33 @@ async function fetchDepUpdates(
   depConfig.versioning ??= getDefaultVersioning(depConfig.datasource);
   depConfig = await applyPackageRules(depConfig, 'pre-lookup');
   depConfig.packageName ??= depConfig.depName;
+
   if (depConfig.ignoreDeps!.includes(depName!)) {
     // TODO: fix types (#22198)
     logger.debug(`Dependency: ${depName!}, is ignored`);
     dep.skipReason = 'ignored';
-  } else if (depConfig.enabled === false) {
+    return Result.ok(dep);
+  }
+
+  if (depConfig.enabled === false) {
     logger.debug(`Dependency: ${depName!}, is disabled`);
     dep.skipReason = 'disabled';
-  } else {
-    if (depConfig.datasource) {
-      const { val: updateResult, err } = await LookupStats.wrap(
-        depConfig.datasource,
-        () =>
-          Result.wrap(lookupUpdates(depConfig as LookupUpdateConfig)).unwrap(),
-      );
-
-      if (updateResult) {
-        Object.assign(dep, updateResult);
-      } else {
+    return Result.ok(dep);
+  }
+
+  if (!depConfig.datasource) {
+    return Result.ok(dep);
+  }
+
+  return LookupStats.wrap(depConfig.datasource, async () => {
+    return await Result.wrap(lookupUpdates(depConfig as LookupUpdateConfig))
+      .onValue((dep) => {
+        logger.trace({ dep }, 'Dependency lookup success');
+      })
+      .onError((err) => {
+        logger.trace({ err, depName }, 'Dependency lookup error');
+      })
+      .catch((err): Result<UpdateResult, Error> => {
         if (
           packageFileConfig.repoIsOnboarded === true ||
           !(err instanceof ExternalHostError)
@@ -72,17 +92,18 @@ async function fetchDepUpdates(
         }
 
         const cause = err.err;
-        dep.warnings ??= [];
-        dep.warnings.push({
-          topic: 'Lookup Error',
-          // TODO: types (#22198)
-          message: `${depName!}: ${cause.message}`,
+        return Result.ok({
+          updates: [],
+          warnings: [
+            {
+              topic: 'Lookup Error',
+              message: `${depName}: ${cause.message}`,
+            },
+          ],
         });
-      }
-    }
-    dep.updates ??= [];
-  }
-  return Result.ok(dep);
+      })
+      .transform((upd): PackageDependency => Object.assign(dep, upd));
+  });
 }
 
 async function fetchManagerPackagerFileUpdates(
@@ -101,7 +122,7 @@ async function fetchManagerPackagerFileUpdates(
   const { manager } = packageFileConfig;
   const queue = pFile.deps.map(
     (dep) => async (): Promise<PackageDependency> => {
-      const updates = await fetchDepUpdates(packageFileConfig, dep);
+      const updates = await lookup(packageFileConfig, dep);
       return updates.unwrapOrThrow();
     },
   );
-- 
GitLab