/
utils.ts
56 lines (52 loc) · 1.69 KB
/
utils.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import { logger } from '../logger';
import { getHighestVulnerabilitySeverity } from '../util/vulnerability/utils';
import * as options from './options';
import type { RenovateConfig } from './types';
export function mergeChildConfig<
T extends Record<string, any>,
TChild extends Record<string, any> | undefined
>(parent: T, child: TChild): T & TChild {
logger.trace({ parent, child }, `mergeChildConfig`);
if (!child) {
return parent as never;
}
const parentConfig = structuredClone(parent);
const childConfig = structuredClone(child);
const config: Record<string, any> = { ...parentConfig, ...childConfig };
// Ensure highest severity survives parent / child merge
if (config?.isVulnerabilityAlert) {
config.vulnerabilitySeverity = getHighestVulnerabilitySeverity(
parent,
child
);
}
for (const option of options.getOptions()) {
if (
option.mergeable &&
childConfig[option.name] &&
parentConfig[option.name]
) {
logger.trace(`mergeable option: ${option.name}`);
if (option.name === 'constraints') {
config[option.name] = {
...parentConfig[option.name],
...childConfig[option.name],
};
} else if (option.type === 'array') {
config[option.name] = (parentConfig[option.name] as unknown[]).concat(
config[option.name]
);
} else {
config[option.name] = mergeChildConfig(
parentConfig[option.name] as RenovateConfig,
childConfig[option.name] as RenovateConfig
);
}
logger.trace(
{ result: config[option.name] },
`Merged config.${option.name}`
);
}
}
return { ...config, ...config.force };
}