From 4fa199e20d2cce63b269b30f3eee8f6a2e4bac79 Mon Sep 17 00:00:00 2001 From: Michael Kriese Date: Tue, 18 Apr 2023 04:33:30 +0200 Subject: [PATCH] feat(versioning/regex): add `revision` as fifth capture group (#21555) --- lib/modules/versioning/regex/index.spec.ts | 20 +++++++++++++++----- lib/modules/versioning/regex/index.ts | 6 +++++- lib/modules/versioning/regex/readme.md | 5 +++-- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/lib/modules/versioning/regex/index.spec.ts b/lib/modules/versioning/regex/index.spec.ts index e8dd5e3dfab6c9..e9070d7de7fc1c 100644 --- a/lib/modules/versioning/regex/index.spec.ts +++ b/lib/modules/versioning/regex/index.spec.ts @@ -1,9 +1,9 @@ -import { VersioningApi, get } from '..'; +import { get } from '..'; import { CONFIG_VALIDATION } from '../../../constants/error-messages'; describe('modules/versioning/regex/index', () => { describe('regex versioning', () => { - const regex: VersioningApi = get( + const regex = get( 'regex:^(?\\d+)\\.(?\\d+)\\.(?\\d+)(?[^.-]+)?(?:-(?.*))?$' ); @@ -11,6 +11,16 @@ describe('modules/versioning/regex/index', () => { expect(() => get('regex:not a regex')).toThrow(); }); + it('works without config', () => { + const re = get('regex'); + expect(re.isValid('alpine')).toBeFalse(); + }); + + it('works with missing version', () => { + const re = get('regex:^(?\\d+)?(?.+)'); + expect(re.isValid('alpine')).toBeTrue(); + }); + describe('throws', () => { for (const re of [ '^(?\\d+)(', @@ -43,7 +53,7 @@ describe('modules/versioning/regex/index', () => { ${'1.2.aardvark-foo'} | ${false} ${'1.2a2.3'} | ${false} `('isValid("$version") === $expected', ({ version, expected }) => { - expect(!!regex.isValid(version)).toBe(expected); + expect(regex.isValid(version)).toBe(expected); }); test.each` @@ -342,9 +352,9 @@ describe('modules/versioning/regex/index', () => { ); }); - describe('Supported 4th number as build', () => { + describe('Supported 4th number as build and 5th as revision', () => { const re = get( - 'regex:^(?\\d+)\\.(?\\d+)\\.(?\\d+)(:?-(?.*-r)(?\\d+))?$' + 'regex:^(?\\d+)\\.(?\\d+)\\.(?\\d+)(:?-(?.+)(?\\d+)-r(?\\d+))?$' ); test.each` diff --git a/lib/modules/versioning/regex/index.ts b/lib/modules/versioning/regex/index.ts index c77ee139a83c90..a11369635d4817 100644 --- a/lib/modules/versioning/regex/index.ts +++ b/lib/modules/versioning/regex/index.ts @@ -71,7 +71,8 @@ export class RegExpVersioningApi extends GenericVersioningApi { return null; } - const { major, minor, patch, build, prerelease, compatibility } = groups; + const { major, minor, patch, build, revision, prerelease, compatibility } = + groups; const release = [ typeof major === 'undefined' ? 0 : Number.parseInt(major, 10), typeof minor === 'undefined' ? 0 : Number.parseInt(minor, 10), @@ -80,6 +81,9 @@ export class RegExpVersioningApi extends GenericVersioningApi { if (build) { release.push(Number.parseInt(build, 10)); + if (revision) { + release.push(Number.parseInt(revision, 10)); + } } return { diff --git a/lib/modules/versioning/regex/readme.md b/lib/modules/versioning/regex/readme.md index cabd8e88b08db6..9d7f3e17066a59 100644 --- a/lib/modules/versioning/regex/readme.md +++ b/lib/modules/versioning/regex/readme.md @@ -5,6 +5,7 @@ The valid capture groups for `regex` versioning are: - `major`, `minor`, and `patch`: at least one of these must be provided. When determining whether a package has updates, these values will be compared in the standard semantic versioning fashion. If any of these fields are omitted, they will be treated as if they were `0` -- in this way, you can describe versioning schemes with up to three incrementing values. - `build`: this capture group can be used after you've already used the `major`, `minor` and `patch` capture groups and need a fourth version part. `build` updates are handled like `patch` updates. +- `revision`: this capture group can be used after you've already used the `build` capture groups and need a fifth version part. `revision` updates are handled like `patch` updates. - `prerelease`: this value, if captured, will mark a given release as a prerelease (e.g. unstable). If this value is captured and you have configured `"ignoreUnstable": true`, the given release will be skipped. - `compatibility`: this value defines the "build compatibility" of a given dependency. A proposed Renovate update will never change the specified compatibility value. For example, if you are pinning to `1.2.3-linux` (and `linux` is captured as the compatibility value), Renovate will not update you to `1.2.4-osx`. @@ -37,7 +38,7 @@ Here is another example, this time for handling `python` Docker images, which us } ``` -Here is another example, this time for handling Bitnami Docker images, which use build indicators as well as version suffixes for compatibility: +Here is another example, this time for handling Bitnami Docker images, which use `build` and `revision` indicators as well as version suffixes for compatibility: ```json { @@ -45,7 +46,7 @@ Here is another example, this time for handling Bitnami Docker images, which use { "matchDatasources": ["docker"], "matchPackagePrefixes": ["bitnami/"], - "versioning": "regex:^(?\\d+)\\.(?\\d+)\\.(?\\d+)(:?-(?.*-r)(?\\d+))?$" + "versioning": "regex:^(?\\d+)\\.(?\\d+)\\.(?\\d+)(:?-(?.+)(?\\d+)-r(?\\d+))?$" } ] }