From 4a21eb063b3869f20a0fbe92e1a09a9c4d9829c8 Mon Sep 17 00:00:00 2001 From: Rahul Gautam Singh Date: Fri, 26 Apr 2024 23:42:32 +0545 Subject: [PATCH 01/14] add new field regexOrGlob --- lib/config/options/index.ts | 4 ++++ lib/config/types.ts | 2 ++ 2 files changed, 6 insertions(+) diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts index 14448f0fa8ff6c..6e2ef77a838f4a 100644 --- a/lib/config/options/index.ts +++ b/lib/config/options/index.ts @@ -13,6 +13,7 @@ const options: RenovateOptions[] = [ default: ['X-*'], subType: 'string', globalOnly: true, + regexOrGlob: true, }, { name: 'allowedEnv', @@ -22,6 +23,7 @@ const options: RenovateOptions[] = [ default: [], subType: 'string', globalOnly: true, + regexOrGlob: true, }, { name: 'detectGlobalManagerConfig', @@ -949,6 +951,7 @@ const options: RenovateOptions[] = [ default: null, globalOnly: true, supportedPlatforms: ['bitbucket'], + regexOrGlob: true, }, { name: 'autodiscoverTopics', @@ -1230,6 +1233,7 @@ const options: RenovateOptions[] = [ mergeable: true, cli: false, env: false, + regexOrGlob: true, }, { name: 'excludeRepositories', diff --git a/lib/config/types.ts b/lib/config/types.ts index 2e55575c98927a..81088cc9fbc27a 100644 --- a/lib/config/types.ts +++ b/lib/config/types.ts @@ -442,6 +442,8 @@ export interface RenovateOptionBase { * This is used to add depreciation message in the docs */ deprecationMsg?: string; + + regexOrGlob?: boolean; } export interface RenovateArrayOption< From 31cb0014b3c45ba39880f3fc1cf6e24984a654ec Mon Sep 17 00:00:00 2001 From: Rahul Gautam Singh Date: Sat, 27 Apr 2024 02:56:01 +0545 Subject: [PATCH 02/14] rename and ignore from docs --- lib/config/options/index.ts | 8 ++++---- lib/config/types.ts | 5 ++++- tools/docs/config.ts | 1 + 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts index 6e2ef77a838f4a..4ec83c2a32111d 100644 --- a/lib/config/options/index.ts +++ b/lib/config/options/index.ts @@ -13,7 +13,7 @@ const options: RenovateOptions[] = [ default: ['X-*'], subType: 'string', globalOnly: true, - regexOrGlob: true, + patternMatch: true, }, { name: 'allowedEnv', @@ -23,7 +23,7 @@ const options: RenovateOptions[] = [ default: [], subType: 'string', globalOnly: true, - regexOrGlob: true, + patternMatch: true, }, { name: 'detectGlobalManagerConfig', @@ -951,7 +951,7 @@ const options: RenovateOptions[] = [ default: null, globalOnly: true, supportedPlatforms: ['bitbucket'], - regexOrGlob: true, + patternMatch: true, }, { name: 'autodiscoverTopics', @@ -1233,7 +1233,7 @@ const options: RenovateOptions[] = [ mergeable: true, cli: false, env: false, - regexOrGlob: true, + patternMatch: true, }, { name: 'excludeRepositories', diff --git a/lib/config/types.ts b/lib/config/types.ts index 81088cc9fbc27a..064ad4e4179f20 100644 --- a/lib/config/types.ts +++ b/lib/config/types.ts @@ -443,7 +443,10 @@ export interface RenovateOptionBase { */ deprecationMsg?: string; - regexOrGlob?: boolean; + /** + * For internal use only: helps with regexOrGlob option validation + */ + patternMatch?: boolean; } export interface RenovateArrayOption< diff --git a/tools/docs/config.ts b/tools/docs/config.ts index ad573f39fff1df..cac650c7101e8e 100644 --- a/tools/docs/config.ts +++ b/tools/docs/config.ts @@ -94,6 +94,7 @@ function genTable(obj: [string, string][], type: string, def: any): string { 'experimentalIssues', 'advancedUse', 'deprecationMsg', + 'patternMatch', ]; obj.forEach(([key, val]) => { const el = [key, val]; From 472af4579dbf6c6bdd00e870eb3db786bddc45d1 Mon Sep 17 00:00:00 2001 From: Rahul Gautam Singh Date: Sat, 27 Apr 2024 03:14:58 +0545 Subject: [PATCH 03/14] redo ts comment --- lib/config/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/config/types.ts b/lib/config/types.ts index 064ad4e4179f20..790fd663b101c1 100644 --- a/lib/config/types.ts +++ b/lib/config/types.ts @@ -444,7 +444,7 @@ export interface RenovateOptionBase { deprecationMsg?: string; /** - * For internal use only: helps with regexOrGlob option validation + * For internal use only: add it any option that supports regex or glob matching */ patternMatch?: boolean; } From 42d03c12cb85f801f29a602e266d233390f26e50 Mon Sep 17 00:00:00 2001 From: Rahul Gautam Singh Date: Mon, 29 Apr 2024 11:54:34 +0545 Subject: [PATCH 04/14] add validation --- .../regex-glob-matchers.spec.ts | 25 ++++++++ .../validation-helpers/regex-glob-matchers.ts | 30 +++++++++ lib/config/validation-helpers/types.ts | 5 ++ lib/config/validation.spec.ts | 64 +++++++++++++++++++ lib/config/validation.ts | 32 +++++++++- 5 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 lib/config/validation-helpers/regex-glob-matchers.spec.ts create mode 100644 lib/config/validation-helpers/regex-glob-matchers.ts diff --git a/lib/config/validation-helpers/regex-glob-matchers.spec.ts b/lib/config/validation-helpers/regex-glob-matchers.spec.ts new file mode 100644 index 00000000000000..e268209e7155b8 --- /dev/null +++ b/lib/config/validation-helpers/regex-glob-matchers.spec.ts @@ -0,0 +1,25 @@ +import { check } from './regex-glob-matchers'; + +describe('config/validation-helpers/regex-glob-matchers', () => { + it('should have errors', () => { + const res = check({ + val: ['*', '**'], + currentPath: 'hostRules[0].allowedHeaders', + }); + expect(res).toHaveLength(1); + }); + + it('should have errors - 2', () => { + const res = check({ + val: ['*', 2] as never, + currentPath: 'hostRules[0].allowedHeaders', + }); + expect(res).toMatchObject([ + { + message: + 'hostRules[0].allowedHeaders: should be an array of strings. You have included object.', + topic: 'Configuration Error', + }, + ]); + }); +}); diff --git a/lib/config/validation-helpers/regex-glob-matchers.ts b/lib/config/validation-helpers/regex-glob-matchers.ts new file mode 100644 index 00000000000000..27f5225aa0dc12 --- /dev/null +++ b/lib/config/validation-helpers/regex-glob-matchers.ts @@ -0,0 +1,30 @@ +import is from '@sindresorhus/is'; +import type { ValidationMessage } from '../types'; +import type { CheckMatcherArgs } from './types'; + +/** + * Only if type condition or context condition violated then errors array will be mutated to store metadata + */ +export function check({ + val, + currentPath, +}: CheckMatcherArgs): ValidationMessage[] { + let errMessage: string | undefined; + + if (is.array(val, is.string)) { + if ((val.includes('*') || val.includes('**')) && val.length > 1) { + errMessage = `${currentPath}: Your input contains * or ** along with other patterns. Please remove them, as * or ** matches all patterns.`; + } + } else { + errMessage = `${currentPath}: should be an array of strings. You have included ${typeof val}.`; + } + + return errMessage + ? [ + { + topic: 'Configuration Error', + message: errMessage, + }, + ] + : []; +} diff --git a/lib/config/validation-helpers/types.ts b/lib/config/validation-helpers/types.ts index 05f70826cfe420..d9df560775bed7 100644 --- a/lib/config/validation-helpers/types.ts +++ b/lib/config/validation-helpers/types.ts @@ -4,3 +4,8 @@ export interface CheckManagerArgs { resolvedRule: PackageRule; currentPath: string; } + +export interface CheckMatcherArgs { + val: string[]; + currentPath: string; +} diff --git a/lib/config/validation.spec.ts b/lib/config/validation.spec.ts index d1ca81e1a876d4..95eb138ee53e39 100644 --- a/lib/config/validation.spec.ts +++ b/lib/config/validation.spec.ts @@ -1225,6 +1225,30 @@ describe('config/validation', () => { expect(warnings).toHaveLength(0); expect(errors).toHaveLength(2); }); + + it('catches when * or ** is combined with others patterns in a regexOrGlob option', async () => { + const config = { + packageRules: [ + { + matchRepositories: ['*', 'repo'], + enabled: false, + }, + ], + }; + const { errors, warnings } = await configValidation.validateConfig( + 'repo', + config, + ); + expect(errors).toMatchObject([ + { + message: + 'packageRules[0].matchRepositories: Your input contains * or ** along with other patterns. Please remove them, as * or ** matches all patterns.', + topic: 'Configuration Error', + }, + ]); + expect(errors).toHaveLength(1); + expect(warnings).toHaveLength(0); + }); }); describe('validateConfig() -> globaOnly options', () => { @@ -1706,5 +1730,45 @@ describe('config/validation', () => { expect(warnings).toHaveLength(0); expect(errors).toHaveLength(0); }); + + it('catches when * or ** is combined with others patterns in a regexOrGlob option', async () => { + const config = { + packageRules: [ + { + matchRepositories: ['*', 'repo'], // invalid + enabled: false, + }, + ], + allowedHeaders: ['*', '**'], // invalid + autodiscoverProjects: ['**', 'project'], // invalid + allowedEnv: ['env_var'], // valid + }; + const { errors, warnings } = await configValidation.validateConfig( + 'global', + config, + ); + expect(warnings).toMatchObject([ + { + message: + 'allowedHeaders: Your input contains * or ** along with other patterns. Please remove them, as * or ** matches all patterns.', + topic: 'Configuration Error', + }, + { + message: + 'autodiscoverProjects: Your input contains * or ** along with other patterns. Please remove them, as * or ** matches all patterns.', + topic: 'Configuration Error', + }, + ]); + + expect(errors).toMatchObject([ + { + message: + 'packageRules[0].matchRepositories: Your input contains * or ** along with other patterns. Please remove them, as * or ** matches all patterns.', + topic: 'Configuration Error', + }, + ]); + expect(warnings).toHaveLength(2); + expect(errors).toHaveLength(1); + }); }); }); diff --git a/lib/config/validation.ts b/lib/config/validation.ts index e12b7fb67bf816..9bcab9d32f852c 100644 --- a/lib/config/validation.ts +++ b/lib/config/validation.ts @@ -34,6 +34,7 @@ import { allowedStatusCheckStrings, } from './types'; import * as managerValidator from './validation-helpers/managers'; +import * as regexOrGlobValidator from './validation-helpers/regex-glob-matchers'; const options = getOptions(); @@ -41,6 +42,7 @@ let optionTypes: Record; let optionParents: Record; let optionGlobals: Set; let optionInherits: Set; +let optionRegexOrGlob: Set; const managerList = getManagerList(); @@ -111,6 +113,18 @@ function isInhertConfigOption(key: string): boolean { return optionInherits.has(key); } +function isRegexOrGlobOption(key: string): boolean { + if (!optionRegexOrGlob) { + optionRegexOrGlob = new Set(); + for (const option of options) { + if (option.patternMatch) { + optionRegexOrGlob.add(option.name); + } + } + } + return optionRegexOrGlob.has(key); +} + function isGlobalOption(key: string): boolean { if (!optionGlobals) { optionGlobals = new Set(); @@ -354,6 +368,14 @@ export async function validateConfig( errors = errors.concat(subValidation.errors); } } + if (isRegexOrGlobOption(key)) { + errors.push( + ...regexOrGlobValidator.check({ + val: val as string[], + currentPath, + }), + ); + } if (key === 'extends') { for (const subval of val) { if (is.string(subval)) { @@ -951,9 +973,17 @@ async function validateGlobalConfig( } } else if (type === 'array') { if (is.array(val)) { + if (isRegexOrGlobOption(key)) { + warnings.push( + ...regexOrGlobValidator.check({ + val: val as string[], + currentPath: currentPath!, + }), + ); + } if (key === 'gitNoVerify') { const allowedValues = ['commit', 'push']; - for (const value of val as string[]) { + for (const value of val) { if (!allowedValues.includes(value)) { warnings.push({ topic: 'Configuration Error', From fc1847471262c3d5f521a6f1c7b8bfed6f961a99 Mon Sep 17 00:00:00 2001 From: Rahul Gautam Singh Date: Tue, 30 Apr 2024 12:13:51 +0545 Subject: [PATCH 05/14] apply suggestions --- lib/config/types.ts | 2 +- lib/config/validation-helpers/regex-glob-matchers.spec.ts | 2 +- lib/config/validation-helpers/types.ts | 2 +- lib/config/validation.ts | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/config/types.ts b/lib/config/types.ts index 790fd663b101c1..b128b39d4da6bd 100644 --- a/lib/config/types.ts +++ b/lib/config/types.ts @@ -444,7 +444,7 @@ export interface RenovateOptionBase { deprecationMsg?: string; /** - * For internal use only: add it any option that supports regex or glob matching + * For internal use only: add it to any config option that supports regex or glob matching */ patternMatch?: boolean; } diff --git a/lib/config/validation-helpers/regex-glob-matchers.spec.ts b/lib/config/validation-helpers/regex-glob-matchers.spec.ts index e268209e7155b8..e958befe908857 100644 --- a/lib/config/validation-helpers/regex-glob-matchers.spec.ts +++ b/lib/config/validation-helpers/regex-glob-matchers.spec.ts @@ -11,7 +11,7 @@ describe('config/validation-helpers/regex-glob-matchers', () => { it('should have errors - 2', () => { const res = check({ - val: ['*', 2] as never, + val: ['*', 2], currentPath: 'hostRules[0].allowedHeaders', }); expect(res).toMatchObject([ diff --git a/lib/config/validation-helpers/types.ts b/lib/config/validation-helpers/types.ts index d9df560775bed7..f587ad3de33950 100644 --- a/lib/config/validation-helpers/types.ts +++ b/lib/config/validation-helpers/types.ts @@ -6,6 +6,6 @@ export interface CheckManagerArgs { } export interface CheckMatcherArgs { - val: string[]; + val: unknown[]; currentPath: string; } diff --git a/lib/config/validation.ts b/lib/config/validation.ts index 9bcab9d32f852c..8d3c3101df2efa 100644 --- a/lib/config/validation.ts +++ b/lib/config/validation.ts @@ -371,7 +371,7 @@ export async function validateConfig( if (isRegexOrGlobOption(key)) { errors.push( ...regexOrGlobValidator.check({ - val: val as string[], + val, currentPath, }), ); @@ -976,7 +976,7 @@ async function validateGlobalConfig( if (isRegexOrGlobOption(key)) { warnings.push( ...regexOrGlobValidator.check({ - val: val as string[], + val, currentPath: currentPath!, }), ); From 833fd559eedf2dee144d28120180946753f0cf14 Mon Sep 17 00:00:00 2001 From: Rahul Gautam Singh Date: Wed, 1 May 2024 07:09:16 +0545 Subject: [PATCH 06/14] refactor: move options initialization to a single function --- lib/config/validation.ts | 69 +++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 36 deletions(-) diff --git a/lib/config/validation.ts b/lib/config/validation.ts index 8d3c3101df2efa..bcff8f8b64fc5f 100644 --- a/lib/config/validation.ts +++ b/lib/config/validation.ts @@ -38,6 +38,7 @@ import * as regexOrGlobValidator from './validation-helpers/regex-glob-matchers' const options = getOptions(); +let optionsInitialized = false; let optionTypes: Record; let optionParents: Record; let optionGlobals: Set; @@ -102,39 +103,45 @@ function getDeprecationMessage(option: string): string | undefined { } function isInhertConfigOption(key: string): boolean { - if (!optionInherits) { - optionInherits = new Set(); - for (const option of options) { - if (option.inheritConfigSupport) { - optionInherits.add(option.name); - } - } - } return optionInherits.has(key); } function isRegexOrGlobOption(key: string): boolean { - if (!optionRegexOrGlob) { - optionRegexOrGlob = new Set(); - for (const option of options) { - if (option.patternMatch) { - optionRegexOrGlob.add(option.name); - } - } - } return optionRegexOrGlob.has(key); } function isGlobalOption(key: string): boolean { - if (!optionGlobals) { - optionGlobals = new Set(); - for (const option of options) { - if (option.globalOnly) { - optionGlobals.add(option.name); - } + return optionGlobals.has(key); +} + +function initOptions(): void { + optionParents = {}; + optionInherits = new Set(); + optionTypes = {}; + optionRegexOrGlob = new Set(); + optionGlobals = new Set(); + + for (const option of options) { + optionTypes[option.name] = option.type; + + if (option.parents) { + optionParents[option.name] = option.parents; + } + + if (option.inheritConfigSupport) { + optionInherits.add(option.name); + } + + if (option.patternMatch) { + optionRegexOrGlob.add(option.name); + } + + if (option.globalOnly) { + optionGlobals.add(option.name); } } - return optionGlobals.has(key); + + optionsInitialized = true; } export function getParentName(parentPath: string | undefined): string { @@ -153,20 +160,10 @@ export async function validateConfig( isPreset?: boolean, parentPath?: string, ): Promise { - if (!optionTypes) { - optionTypes = {}; - options.forEach((option) => { - optionTypes[option.name] = option.type; - }); - } - if (!optionParents) { - optionParents = {}; - options.forEach((option) => { - if (option.parents) { - optionParents[option.name] = option.parents; - } - }); + if (!optionsInitialized) { + initOptions(); } + let errors: ValidationMessage[] = []; let warnings: ValidationMessage[] = []; From 811e7a6840b3131c706ee365d0e8502dac8b72f6 Mon Sep 17 00:00:00 2001 From: Rahul Gautam Singh Date: Wed, 1 May 2024 07:10:06 +0545 Subject: [PATCH 07/14] apply suggestion: convert type to unknown --- lib/config/validation-helpers/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/config/validation-helpers/types.ts b/lib/config/validation-helpers/types.ts index f587ad3de33950..68e10825820310 100644 --- a/lib/config/validation-helpers/types.ts +++ b/lib/config/validation-helpers/types.ts @@ -6,6 +6,6 @@ export interface CheckManagerArgs { } export interface CheckMatcherArgs { - val: unknown[]; + val: unknown; currentPath: string; } From 5516623c64b063cda355afb944731cd47a67bc49 Mon Sep 17 00:00:00 2001 From: Rahul Gautam Singh Date: Wed, 1 May 2024 07:12:50 +0545 Subject: [PATCH 08/14] revert unrelated change --- lib/config/validation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/config/validation.ts b/lib/config/validation.ts index bcff8f8b64fc5f..dba59923d2b3d0 100644 --- a/lib/config/validation.ts +++ b/lib/config/validation.ts @@ -980,7 +980,7 @@ async function validateGlobalConfig( } if (key === 'gitNoVerify') { const allowedValues = ['commit', 'push']; - for (const value of val) { + for (const value of val as string[]) { if (!allowedValues.includes(value)) { warnings.push({ topic: 'Configuration Error', From ff82e366386bad02170180fd4f5b0e3f8ceae74c Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Wed, 1 May 2024 17:05:14 +0545 Subject: [PATCH 09/14] Update lib/config/validation.spec.ts Co-authored-by: Sebastian Poxhofer --- lib/config/validation.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/config/validation.spec.ts b/lib/config/validation.spec.ts index 95eb138ee53e39..604e43bde9d050 100644 --- a/lib/config/validation.spec.ts +++ b/lib/config/validation.spec.ts @@ -1230,7 +1230,7 @@ describe('config/validation', () => { const config = { packageRules: [ { - matchRepositories: ['*', 'repo'], + matchRepositories: ['groupA/**', 'groupB/**'], enabled: false, }, ], From d2bc770bb46e1137e5824d519f1a0da249beba78 Mon Sep 17 00:00:00 2001 From: Rahul Gautam Singh Date: Thu, 2 May 2024 00:45:21 +0545 Subject: [PATCH 10/14] fix test --- lib/config/validation.spec.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/config/validation.spec.ts b/lib/config/validation.spec.ts index 604e43bde9d050..fb517bd0bb65bc 100644 --- a/lib/config/validation.spec.ts +++ b/lib/config/validation.spec.ts @@ -1230,9 +1230,13 @@ describe('config/validation', () => { const config = { packageRules: [ { - matchRepositories: ['groupA/**', 'groupB/**'], + matchRepositories: ['groupA/**', 'groupB/**'], // valid enabled: false, }, + { + matchRepositories: ['*', 'repo'], // invalid + enabled: true, + }, ], }; const { errors, warnings } = await configValidation.validateConfig( @@ -1242,7 +1246,7 @@ describe('config/validation', () => { expect(errors).toMatchObject([ { message: - 'packageRules[0].matchRepositories: Your input contains * or ** along with other patterns. Please remove them, as * or ** matches all patterns.', + 'packageRules[1].matchRepositories: Your input contains * or ** along with other patterns. Please remove them, as * or ** matches all patterns.', topic: 'Configuration Error', }, ]); From 3f6c83768e26946674fda4497fe1d11c54635f2c Mon Sep 17 00:00:00 2001 From: Rahul Gautam Singh Date: Fri, 3 May 2024 01:09:32 +0545 Subject: [PATCH 11/14] apply suggestions --- lib/config/validation.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/config/validation.ts b/lib/config/validation.ts index dba59923d2b3d0..b629a44774e0bf 100644 --- a/lib/config/validation.ts +++ b/lib/config/validation.ts @@ -115,6 +115,10 @@ function isGlobalOption(key: string): boolean { } function initOptions(): void { + if (optionsInitialized) { + return; + } + optionParents = {}; optionInherits = new Set(); optionTypes = {}; @@ -160,9 +164,7 @@ export async function validateConfig( isPreset?: boolean, parentPath?: string, ): Promise { - if (!optionsInitialized) { - initOptions(); - } + initOptions(); let errors: ValidationMessage[] = []; let warnings: ValidationMessage[] = []; From 9bc85f9dd12ce7f9a862b46ab9ee723563bdd15c Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Sun, 5 May 2024 09:14:36 +0200 Subject: [PATCH 12/14] validate regex too --- .../regex-glob-matchers.spec.ts | 12 +++++-- .../validation-helpers/regex-glob-matchers.ts | 34 +++++++++++++------ 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/lib/config/validation-helpers/regex-glob-matchers.spec.ts b/lib/config/validation-helpers/regex-glob-matchers.spec.ts index e958befe908857..570128326ec09c 100644 --- a/lib/config/validation-helpers/regex-glob-matchers.spec.ts +++ b/lib/config/validation-helpers/regex-glob-matchers.spec.ts @@ -1,7 +1,7 @@ import { check } from './regex-glob-matchers'; describe('config/validation-helpers/regex-glob-matchers', () => { - it('should have errors', () => { + it('should error for multiple match alls', () => { const res = check({ val: ['*', '**'], currentPath: 'hostRules[0].allowedHeaders', @@ -9,7 +9,15 @@ describe('config/validation-helpers/regex-glob-matchers', () => { expect(res).toHaveLength(1); }); - it('should have errors - 2', () => { + it('should error for invalid regex', () => { + const res = check({ + val: ['[', '/[/', '/.*[/'], + currentPath: 'hostRules[0].allowedHeaders', + }); + expect(res).toHaveLength(2); + }); + + it('should error for non-strings', () => { const res = check({ val: ['*', 2], currentPath: 'hostRules[0].allowedHeaders', diff --git a/lib/config/validation-helpers/regex-glob-matchers.ts b/lib/config/validation-helpers/regex-glob-matchers.ts index 27f5225aa0dc12..06360183ff7813 100644 --- a/lib/config/validation-helpers/regex-glob-matchers.ts +++ b/lib/config/validation-helpers/regex-glob-matchers.ts @@ -1,4 +1,5 @@ import is from '@sindresorhus/is'; +import { getRegexPredicate, isRegexMatch } from '../../util/string-match'; import type { ValidationMessage } from '../types'; import type { CheckMatcherArgs } from './types'; @@ -9,22 +10,33 @@ export function check({ val, currentPath, }: CheckMatcherArgs): ValidationMessage[] { - let errMessage: string | undefined; + const res: ValidationMessage[] = []; if (is.array(val, is.string)) { if ((val.includes('*') || val.includes('**')) && val.length > 1) { - errMessage = `${currentPath}: Your input contains * or ** along with other patterns. Please remove them, as * or ** matches all patterns.`; + res.push({ + topic: 'Configuration Error', + message: `${currentPath}: Your input contains * or ** along with other patterns. Please remove them, as * or ** matches all patterns.`, + }); + } + for (const pattern of val) { + // Validate regex pattern + if (isRegexMatch(pattern)) { + const autodiscoveryPred = getRegexPredicate(pattern); + if (!autodiscoveryPred) { + res.push({ + topic: 'Configuration Error', + message: `Failed to parse regex pattern "${pattern}"`, + }); + } + } } } else { - errMessage = `${currentPath}: should be an array of strings. You have included ${typeof val}.`; + res.push({ + topic: 'Configuration Error', + message: `${currentPath}: should be an array of strings. You have included ${typeof val}.`, + }); } - return errMessage - ? [ - { - topic: 'Configuration Error', - message: errMessage, - }, - ] - : []; + return res; } From 8d331ef81ceb98159b2cb30c18c22595a47ffb3e Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Sun, 5 May 2024 09:19:47 +0200 Subject: [PATCH 13/14] rename --- .../validation-helpers/regex-glob-matchers.ts | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/lib/config/validation-helpers/regex-glob-matchers.ts b/lib/config/validation-helpers/regex-glob-matchers.ts index 06360183ff7813..b91e6669e48af3 100644 --- a/lib/config/validation-helpers/regex-glob-matchers.ts +++ b/lib/config/validation-helpers/regex-glob-matchers.ts @@ -7,26 +7,29 @@ import type { CheckMatcherArgs } from './types'; * Only if type condition or context condition violated then errors array will be mutated to store metadata */ export function check({ - val, + val: matchers, currentPath, }: CheckMatcherArgs): ValidationMessage[] { const res: ValidationMessage[] = []; - if (is.array(val, is.string)) { - if ((val.includes('*') || val.includes('**')) && val.length > 1) { + if (is.array(matchers, is.string)) { + if ( + (matchers.includes('*') || matchers.includes('**')) && + matchers.length > 1 + ) { res.push({ topic: 'Configuration Error', message: `${currentPath}: Your input contains * or ** along with other patterns. Please remove them, as * or ** matches all patterns.`, }); } - for (const pattern of val) { + for (const matcher of matchers) { // Validate regex pattern - if (isRegexMatch(pattern)) { - const autodiscoveryPred = getRegexPredicate(pattern); + if (isRegexMatch(matcher)) { + const autodiscoveryPred = getRegexPredicate(matcher); if (!autodiscoveryPred) { res.push({ topic: 'Configuration Error', - message: `Failed to parse regex pattern "${pattern}"`, + message: `Failed to parse regex pattern "${matcher}"`, }); } } @@ -34,7 +37,7 @@ export function check({ } else { res.push({ topic: 'Configuration Error', - message: `${currentPath}: should be an array of strings. You have included ${typeof val}.`, + message: `${currentPath}: should be an array of strings. You have included ${typeof matchers}.`, }); } From 40d62d4cfdc10edc9ac5efa8a113d49bde8f8f5a Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Sun, 5 May 2024 09:36:16 +0200 Subject: [PATCH 14/14] Update lib/config/validation-helpers/regex-glob-matchers.ts Co-authored-by: RahulGautamSingh --- lib/config/validation-helpers/regex-glob-matchers.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/config/validation-helpers/regex-glob-matchers.ts b/lib/config/validation-helpers/regex-glob-matchers.ts index b91e6669e48af3..a1c25cb82f3839 100644 --- a/lib/config/validation-helpers/regex-glob-matchers.ts +++ b/lib/config/validation-helpers/regex-glob-matchers.ts @@ -25,8 +25,7 @@ export function check({ for (const matcher of matchers) { // Validate regex pattern if (isRegexMatch(matcher)) { - const autodiscoveryPred = getRegexPredicate(matcher); - if (!autodiscoveryPred) { + if (!getRegexPredicate(matcher)) { res.push({ topic: 'Configuration Error', message: `Failed to parse regex pattern "${matcher}"`,