From 91fd1757f604df263a7c39cec818bbc2bfcd5ded Mon Sep 17 00:00:00 2001 From: Adam Setch <adam.setch@outlook.com> Date: Fri, 31 Mar 2023 01:39:06 -0400 Subject: [PATCH] feat(template): indentation capture group (#21193) --- lib/modules/manager/regex/index.spec.ts | 52 +++++++++++++++++++++++++ lib/modules/manager/regex/readme.md | 2 + lib/modules/manager/regex/utils.ts | 4 ++ lib/modules/manager/types.ts | 1 + lib/util/template/index.ts | 1 + 5 files changed, 60 insertions(+) diff --git a/lib/modules/manager/regex/index.spec.ts b/lib/modules/manager/regex/index.spec.ts index 1146c533f2..e5374ea511 100644 --- a/lib/modules/manager/regex/index.spec.ts +++ b/lib/modules/manager/regex/index.spec.ts @@ -214,6 +214,58 @@ describe('modules/manager/regex/index', () => { expect(res?.deps).toHaveLength(1); }); + it('extracts indentation: maintains indentation value if whitespace or empty', async () => { + const config = { + matchStrings: [ + '(?<indentation>\\s*)image:\\s+(?<depName>[^\\s]+):(?<currentValue>[^\\s]+)', + ], + autoReplaceStringTemplate: + 'image:\n{{{indentation}}} name: {{{depName}}}:{{{newValue}}}', + datasourceTemplate: 'docker', + }; + const res = await extractPackageFile( + ' image: eclipse-temurin:17.0.0-alpine', + 'bitbucket-pipelines.yml', + config + ); + expect(res).toMatchObject({ + deps: [ + { + depName: 'eclipse-temurin', + currentValue: '17.0.0-alpine', + datasource: 'docker', + indentation: ' ', + }, + ], + }); + }); + + it('extracts indentation: discards non-whitespace content', async () => { + const config = { + matchStrings: [ + '(?<indentation>.*)image:\\s+(?<depName>[^\\s]+):(?<currentValue>[^\\s]+)', + ], + autoReplaceStringTemplate: + 'image:\n{{{indentation}}} name: {{{depName}}}:{{{newValue}}}', + datasourceTemplate: 'docker', + }; + const res = await extractPackageFile( + 'name: image: eclipse-temurin:17.0.0-alpine', + 'bitbucket-pipelines.yml', + config + ); + expect(res).toMatchObject({ + deps: [ + { + depName: 'eclipse-temurin', + currentValue: '17.0.0-alpine', + datasource: 'docker', + indentation: '', + }, + ], + }); + }); + it('extracts with combination strategy', async () => { const config: CustomExtractConfig = { matchStrings: [ diff --git a/lib/modules/manager/regex/readme.md b/lib/modules/manager/regex/readme.md index e2a7efe66f..e2c0fe27f1 100644 --- a/lib/modules/manager/regex/readme.md +++ b/lib/modules/manager/regex/readme.md @@ -34,6 +34,8 @@ Configuration-wise, it works like this: - You can optionally have a `currentDigest` capture group. - You can optionally have a `registryUrl` capture group or a `registryUrlTemplate` config field - If it's a valid URL, it will be converted to the `registryUrls` field as a single-length array. +- You can optionally have an `indentation` capture group. + - If it's not empty or whitespace, it will be reset to an empty string. ### Regular Expression Capture Groups diff --git a/lib/modules/manager/regex/utils.ts b/lib/modules/manager/regex/utils.ts index 1d909a6e80..8f9a2743fc 100644 --- a/lib/modules/manager/regex/utils.ts +++ b/lib/modules/manager/regex/utils.ts @@ -17,6 +17,7 @@ export const validMatchFields = [ 'extractVersion', 'registryUrl', 'depType', + 'indentation', ] as const; type ValidMatchFields = (typeof validMatchFields)[number]; @@ -39,6 +40,9 @@ function updateDependency( case 'datasource': dependency.datasource = migrateDatasource(value); break; + case 'indentation': + dependency.indentation = is.emptyStringOrWhitespace(value) ? value : ''; + break; default: dependency[field] = value; break; diff --git a/lib/modules/manager/types.ts b/lib/modules/manager/types.ts index 80f84fe480..abd361b4b1 100644 --- a/lib/modules/manager/types.ts +++ b/lib/modules/manager/types.ts @@ -150,6 +150,7 @@ export interface PackageDependency<T = Record<string, any>> extractVersion?: string; isInternal?: boolean; variableName?: string; + indentation?: string; } export interface Upgrade<T = Record<string, any>> extends PackageDependency<T> { diff --git a/lib/util/template/index.ts b/lib/util/template/index.ts index 6034e2ce38..c1b72dc9b8 100644 --- a/lib/util/template/index.ts +++ b/lib/util/template/index.ts @@ -87,6 +87,7 @@ export const allowedFields = { displayPending: 'Latest pending update, if internalChecksFilter is in use', displayTo: 'The to value, formatted for display', hasReleaseNotes: 'true if the upgrade has release notes', + indentation: 'The indentation of the dependency being updated', isLockfileUpdate: 'true if the branch is a lock file update', isMajor: 'true if the upgrade is major', isPatch: 'true if the upgrade is a patch upgrade', -- GitLab