From ded9a7b00762914d6fa17c4b624714540c424df0 Mon Sep 17 00:00:00 2001
From: RahulGautamSingh <rahultesnik@gmail.com>
Date: Wed, 28 Aug 2024 20:40:52 +0530
Subject: [PATCH] fix(package-rules): migrate matchers with string values
 (#31083)

---
 .../__snapshots__/migration.spec.ts.snap      |  1 +
 .../custom/package-rules-migration.spec.ts    | 45 +++++++++++++++
 .../custom/package-rules-migration.ts         | 57 +++++++++++--------
 3 files changed, 80 insertions(+), 23 deletions(-)

diff --git a/lib/config/__snapshots__/migration.spec.ts.snap b/lib/config/__snapshots__/migration.spec.ts.snap
index 5da56cd976..909c56ff34 100644
--- a/lib/config/__snapshots__/migration.spec.ts.snap
+++ b/lib/config/__snapshots__/migration.spec.ts.snap
@@ -191,6 +191,7 @@ exports[`config/migration migrateConfig(config, parentConfig) migrates config 1`
       "groupName": "angular packages",
       "matchPackageNames": [
         "/^(@angular|typescript)/",
+        "!foo",
       ],
     },
     {
diff --git a/lib/config/migrations/custom/package-rules-migration.spec.ts b/lib/config/migrations/custom/package-rules-migration.spec.ts
index 709991cfd9..24b4ae4177 100644
--- a/lib/config/migrations/custom/package-rules-migration.spec.ts
+++ b/lib/config/migrations/custom/package-rules-migration.spec.ts
@@ -174,6 +174,51 @@ describe('config/migrations/custom/package-rules-migration', () => {
     );
   });
 
+  it('should migrate all match/exclude when value is of type string', () => {
+    expect(PackageRulesMigration).toMigrate(
+      {
+        packageRules: [
+          {
+            matchPackagePatterns: 'pattern',
+            matchPackagePrefixes: 'prefix1',
+            matchSourceUrlPrefixes: 'prefix1',
+            excludePackageNames: 'excluded',
+            excludePackagePatterns: 'excludepattern',
+            excludePackagePrefixes: 'prefix1b',
+            matchDepPatterns: 'pattern',
+            matchDepPrefixes: 'prefix1',
+            excludeDepNames: 'excluded',
+            excludeDepPatterns: 'excludepattern',
+            excludeDepPrefixes: 'prefix1b',
+            automerge: true,
+          },
+        ],
+      },
+      {
+        packageRules: [
+          {
+            matchPackageNames: [
+              '/pattern/',
+              'prefix1{/,}**',
+              '!excluded',
+              '!/excludepattern/',
+              '!prefix1b{/,}**',
+            ],
+            matchDepNames: [
+              '/pattern/',
+              'prefix1{/,}**',
+              '!excluded',
+              '!/excludepattern/',
+              '!prefix1b{/,}**',
+            ],
+            matchSourceUrls: ['prefix1{/,}**'],
+            automerge: true,
+          },
+        ],
+      },
+    );
+  });
+
   it('should migrate all match/exclude at once', () => {
     expect(PackageRulesMigration).toMigrate(
       {
diff --git a/lib/config/migrations/custom/package-rules-migration.ts b/lib/config/migrations/custom/package-rules-migration.ts
index 8ebfc7ec89..40fd6b9301 100644
--- a/lib/config/migrations/custom/package-rules-migration.ts
+++ b/lib/config/migrations/custom/package-rules-migration.ts
@@ -30,52 +30,57 @@ function renameKeys(packageRule: PackageRule): PackageRule {
 function mergeMatchers(packageRule: PackageRule): PackageRule {
   const newPackageRule: PackageRule = { ...packageRule };
   for (const [key, val] of Object.entries(packageRule)) {
+    const patterns = is.string(val) ? [val] : val;
+
     // depName
     if (key === 'matchDepPrefixes') {
-      if (is.array(val, is.string)) {
+      if (is.array(patterns, is.string)) {
         newPackageRule.matchDepNames ??= [];
-        newPackageRule.matchDepNames.push(...val.map((v) => `${v}{/,}**`));
+        newPackageRule.matchDepNames.push(...patterns.map((v) => `${v}{/,}**`));
       }
       delete newPackageRule.matchDepPrefixes;
     }
     if (key === 'matchDepPatterns') {
-      if (is.array(val, is.string)) {
+      if (is.array(patterns, is.string)) {
         newPackageRule.matchDepNames ??= [];
-        newPackageRule.matchDepNames.push(...val.map((v) => `/${v}/`));
+        newPackageRule.matchDepNames.push(...patterns.map((v) => `/${v}/`));
       }
       delete newPackageRule.matchDepPatterns;
     }
     if (key === 'excludeDepNames') {
-      if (is.array(val, is.string)) {
+      if (is.array(patterns, is.string)) {
         newPackageRule.matchDepNames ??= [];
-        newPackageRule.matchDepNames.push(...val.map((v) => `!${v}`));
+        newPackageRule.matchDepNames.push(...patterns.map((v) => `!${v}`));
       }
       delete newPackageRule.excludeDepNames;
     }
     if (key === 'excludeDepPrefixes') {
-      if (is.array(val, is.string)) {
+      if (is.array(patterns, is.string)) {
         newPackageRule.matchDepNames ??= [];
-        newPackageRule.matchDepNames.push(...val.map((v) => `!${v}{/,}**`));
+        newPackageRule.matchDepNames.push(
+          ...patterns.map((v) => `!${v}{/,}**`),
+        );
       }
       delete newPackageRule.excludeDepPrefixes;
     }
     if (key === 'excludeDepPatterns') {
-      if (is.array(val, is.string)) {
+      if (is.array(patterns, is.string)) {
         newPackageRule.matchDepNames ??= [];
-        newPackageRule.matchDepNames.push(...val.map((v) => `!/${v}/`));
+        newPackageRule.matchDepNames.push(...patterns.map((v) => `!/${v}/`));
       }
       delete newPackageRule.excludeDepPatterns;
     }
     // packageName
     if (key === 'matchPackagePrefixes') {
-      if (is.array(val, is.string)) {
+      if (is.array(patterns, is.string)) {
         newPackageRule.matchPackageNames ??= [];
-        newPackageRule.matchPackageNames.push(...val.map((v) => `${v}{/,}**`));
+        newPackageRule.matchPackageNames.push(
+          ...patterns.map((v) => `${v}{/,}**`),
+        );
       }
       delete newPackageRule.matchPackagePrefixes;
     }
     if (key === 'matchPackagePatterns') {
-      const patterns = is.string(val) ? [val] : val;
       if (is.array(patterns, is.string)) {
         newPackageRule.matchPackageNames ??= [];
         newPackageRule.matchPackageNames.push(
@@ -90,39 +95,45 @@ function mergeMatchers(packageRule: PackageRule): PackageRule {
       delete newPackageRule.matchPackagePatterns;
     }
     if (key === 'excludePackageNames') {
-      if (is.array(val, is.string)) {
+      if (is.array(patterns, is.string)) {
         newPackageRule.matchPackageNames ??= [];
-        newPackageRule.matchPackageNames.push(...val.map((v) => `!${v}`));
+        newPackageRule.matchPackageNames.push(...patterns.map((v) => `!${v}`));
       }
       delete newPackageRule.excludePackageNames;
     }
     if (key === 'excludePackagePrefixes') {
-      if (is.array(val, is.string)) {
+      if (is.array(patterns, is.string)) {
         newPackageRule.matchPackageNames ??= [];
-        newPackageRule.matchPackageNames.push(...val.map((v) => `!${v}{/,}**`));
+        newPackageRule.matchPackageNames.push(
+          ...patterns.map((v) => `!${v}{/,}**`),
+        );
       }
       delete newPackageRule.excludePackagePrefixes;
     }
     if (key === 'excludePackagePatterns') {
-      if (is.array(val, is.string)) {
+      if (is.array(patterns, is.string)) {
         newPackageRule.matchPackageNames ??= [];
-        newPackageRule.matchPackageNames.push(...val.map((v) => `!/${v}/`));
+        newPackageRule.matchPackageNames.push(
+          ...patterns.map((v) => `!/${v}/`),
+        );
       }
       delete newPackageRule.excludePackagePatterns;
     }
     // sourceUrl
     if (key === 'matchSourceUrlPrefixes') {
-      if (is.array(val, is.string)) {
+      if (is.array(patterns, is.string)) {
         newPackageRule.matchSourceUrls ??= [];
-        newPackageRule.matchSourceUrls.push(...val.map((v) => `${v}{/,}**`));
+        newPackageRule.matchSourceUrls.push(
+          ...patterns.map((v) => `${v}{/,}**`),
+        );
       }
       delete newPackageRule.matchSourceUrlPrefixes;
     }
     // repository
     if (key === 'excludeRepositories') {
-      if (is.array(val, is.string)) {
+      if (is.array(patterns, is.string)) {
         newPackageRule.matchRepositories ??= [];
-        newPackageRule.matchRepositories.push(...val.map((v) => `!${v}`));
+        newPackageRule.matchRepositories.push(...patterns.map((v) => `!${v}`));
       }
       delete newPackageRule.excludeRepositories;
     }
-- 
GitLab