Skip to content

Commit

Permalink
feat(manager/regex): allow defining autoReplaceStringTemplate (#12019)
Browse files Browse the repository at this point in the history
  • Loading branch information
secustor committed Oct 5, 2021
1 parent 8f0fd1d commit e416df1
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 0 deletions.
38 changes: 38 additions & 0 deletions docs/usage/configuration-options.md
Expand Up @@ -2163,6 +2163,44 @@ It will be compiled using Handlebars and the regex `groups` result.
If the `registryUrls` for a dependency is not captured with a named group then it can be defined in config using this field.
It will be compiled using Handlebars and the regex `groups` result.

### autoReplaceStringTemplate

Allows overwriting how the matched string is replaced.
This allows for some migration strategies.
E.g. moving from one Docker image repository to another one.

helm-values.yaml:

```yaml
# The image of the service <registry>/<repo>/<image>:<tag>
image: my.old.registry/aRepository/andImage:1.18-alpine
```

regex definition:

```json
{
"regexManagers": [
{
"fileMatch": ["values.yaml$"],
"matchStrings": [
"image:\\s+(?<depName>my\\.old\\.registry\\/aRepository\\/andImage):(?<currentValue>[^\\s]+)"
],
"depNameTemplate": "my.new.registry/aRepository/andImage",
"autoReplaceStringTemplate": "image: {{{depName}}}:{{{newValue}}}",
"datasourceTemplate": "docker"
}
]
}
```

This will lead to following update where `1.21-alpine` is the newest version of `my.new.registry/aRepository/andImage`:

```yaml
# The image of the service <registry>/<repo>/<image>:<tag>
image: my.new.registry/aRepository/andImage:1.21-alpine
```

## registryUrls

Usually Renovate is able to either (a) use the default registries for a datasource, or (b) automatically detect during the manager extract phase which custom registries are in use.
Expand Down
9 changes: 9 additions & 0 deletions lib/config/options/index.ts
Expand Up @@ -2016,6 +2016,15 @@ const options: RenovateOptions[] = [
cli: false,
env: false,
},
{
name: 'autoReplaceStringTemplate',
description:
'Optional extractVersion for extracted dependencies. Valid only within a `regexManagers` object.',
type: 'string',
parent: 'regexManagers',
cli: false,
env: false,
},
{
name: 'fetchReleaseNotes',
description: 'Allow to disable release notes fetching.',
Expand Down
1 change: 1 addition & 0 deletions lib/config/types.ts
Expand Up @@ -150,6 +150,7 @@ export interface CustomManager {
datasourceTemplate?: string;
lookupNameTemplate?: string;
versioningTemplate?: string;
autoReplaceStringTemplate?: string;
}

// TODO: Proper typings
Expand Down
1 change: 1 addition & 0 deletions lib/config/validation.ts
Expand Up @@ -388,6 +388,7 @@ export async function validateConfig(
'registryUrlTemplate',
'currentValueTemplate',
'extractVersionTemplate',
'autoReplaceStringTemplate',
];
// TODO: fix types
for (const regexManager of val as any[]) {
Expand Down
19 changes: 19 additions & 0 deletions lib/manager/regex/__snapshots__/index.spec.ts.snap
Expand Up @@ -41,6 +41,25 @@ Object {
}
`;

exports[`manager/regex/index extracts dependency with autoReplaceStringTemplate 1`] = `
Object {
"autoReplaceStringTemplate": "image: {{{depName}}}:{{{newValue}}}",
"datasourceTemplate": "docker",
"depNameTemplate": "my.new.registry/aRepository/andImage",
"deps": Array [
Object {
"currentValue": "1.18-alpine",
"datasource": "docker",
"depName": "my.new.registry/aRepository/andImage",
"replaceString": "image: my.old.registry/aRepository/andImage:1.18-alpine",
},
],
"matchStrings": Array [
"image:\\\\s+(?<depName>my\\\\.old\\\\.registry\\\\/aRepository\\\\/andImage):(?<currentValue>[^\\\\s]+)",
],
}
`;

exports[`manager/regex/index extracts extractVersion 1`] = `
Object {
"deps": Array [
Expand Down
19 changes: 19 additions & 0 deletions lib/manager/regex/index.spec.ts
Expand Up @@ -168,6 +168,25 @@ describe('manager/regex/index', () => {
'maven'
);
});

it('extracts dependency with autoReplaceStringTemplate', async () => {
const config = {
matchStrings: [
'image:\\s+(?<depName>my\\.old\\.registry\\/aRepository\\/andImage):(?<currentValue>[^\\s]+)',
],
depNameTemplate: 'my.new.registry/aRepository/andImage',
autoReplaceStringTemplate: 'image: {{{depName}}}:{{{newValue}}}',
datasourceTemplate: 'docker',
};
const res = await extractPackageFile(
'image: my.old.registry/aRepository/andImage:1.18-alpine',
'values.yaml',
config
);
expect(res).toMatchSnapshot();
expect(res.deps).toHaveLength(1);
});

it('extracts with combination strategy', async () => {
const config: CustomExtractConfig = {
matchStrings: [
Expand Down
3 changes: 3 additions & 0 deletions lib/manager/regex/index.ts
Expand Up @@ -221,6 +221,9 @@ export function extractPackageFile(
res[field] = config[field];
}
}
if (config.autoReplaceStringTemplate) {
res.autoReplaceStringTemplate = config.autoReplaceStringTemplate;
}
return res;
}

Expand Down
2 changes: 2 additions & 0 deletions lib/manager/types.ts
Expand Up @@ -27,6 +27,7 @@ export interface ExtractConfig {
}

export interface CustomExtractConfig extends ExtractConfig {
autoReplaceStringTemplate?: string;
matchStrings: string[];
matchStringsStrategy?: MatchStringsStrategy;
depNameTemplate?: string;
Expand Down Expand Up @@ -69,6 +70,7 @@ export interface NpmLockFiles {
export interface PackageFile<T = Record<string, any>>
extends NpmLockFiles,
ManagerData<T> {
autoReplaceStringTemplate?: string;
hasYarnWorkspaces?: boolean;
constraints?: Record<string, string>;
datasource?: string;
Expand Down

0 comments on commit e416df1

Please sign in to comment.