mirror of
https://github.com/renovatebot/renovate.git
synced 2026-10-30 17:27:26 +00:00
97327c3d28
* refactor(linters): add prefer-coerce-array rule Refs #45217 `x ?? []` and `coerceArray(x)` say the same thing, but only the second one is searchable and consistent. The rule flags a `??` whose default is a bare `[]` literal; a non-empty default or an asserted `([] as Foo[])` still passes. Applying it across `lib/` surfaced three spots the helper cannot cover, which keep `?? []` with a disable comment or a narrower fix: - `package-files.ts` destructures a tuple, which `coerceArray()` widens - `generate.spec.ts` defaults `matchAll()`, an iterator rather than an array - `mise/upgradeable-tooling.ts` declares a `Record` return, so its `?? []` fallback was wrong to begin with and becomes `coerceObject()` * refactor(platform/github): hoist the GHE version header lookup `Object.entries(...).find()` returns a tuple, and defaulting it with `?? []` only to destructure the second element reads as an array default when it is not one. Name the found entry instead, which drops the `?? []` rather than routing a tuple through `coerceArray()`.
97 lines
3.0 KiB
TypeScript
97 lines
3.0 KiB
TypeScript
import { isArray, isNonEmptyArray, isObject, isString } from '@sindresorhus/is';
|
|
import { coerceArray } from '../util/array.ts';
|
|
import { clone } from '../util/clone.ts';
|
|
import { toMs } from '../util/pretty-time.ts';
|
|
import { getOptions } from './options/index.ts';
|
|
import type { PackageRule, RenovateConfig, UpdateType } from './types.ts';
|
|
|
|
const options = getOptions();
|
|
|
|
let allowedStrings: string[];
|
|
|
|
// Returns a massaged config
|
|
export function massageConfig(config: RenovateConfig): RenovateConfig {
|
|
if (!allowedStrings) {
|
|
allowedStrings = [];
|
|
options.forEach((option) => {
|
|
if (option.allowString) {
|
|
allowedStrings.push(option.name);
|
|
}
|
|
});
|
|
}
|
|
const massagedConfig = clone(config);
|
|
for (const [key, val] of Object.entries(config)) {
|
|
if (key === 'minimumReleaseAge' && isString(val) && toMs(val) === 0) {
|
|
massagedConfig.minimumReleaseAge = null;
|
|
} else if (allowedStrings.includes(key) && isString(val)) {
|
|
// @ts-expect-error -- TODO: fix me
|
|
massagedConfig[key] = [val];
|
|
} else if (isArray(val)) {
|
|
// @ts-expect-error -- TODO: fix me
|
|
massagedConfig[key] = [];
|
|
val.forEach((item) => {
|
|
if (isObject(item)) {
|
|
// @ts-expect-error -- TODO: fix me
|
|
(massagedConfig[key] as RenovateConfig[]).push(massageConfig(item));
|
|
} else {
|
|
// @ts-expect-error -- TODO: fix me
|
|
(massagedConfig[key] as unknown[]).push(item);
|
|
}
|
|
});
|
|
} else if (isObject(val) && key !== 'encrypted') {
|
|
// @ts-expect-error -- TODO: fix me
|
|
massagedConfig[key] = massageConfig(val);
|
|
}
|
|
}
|
|
if (isNonEmptyArray(massagedConfig.packageRules)) {
|
|
let newRules: PackageRule[] = [];
|
|
const updateTypes: UpdateType[] = [
|
|
'major',
|
|
'minor',
|
|
'patch',
|
|
'pin',
|
|
'digest',
|
|
'rollback',
|
|
];
|
|
for (const rule of massagedConfig.packageRules) {
|
|
newRules.push(rule);
|
|
for (const [key, val] of Object.entries(rule) as [
|
|
UpdateType,
|
|
PackageRule,
|
|
][]) {
|
|
if (updateTypes.includes(key)) {
|
|
let newRule = clone(rule);
|
|
Object.keys(newRule).forEach((newKey) => {
|
|
if (!(newKey.startsWith(`match`) || newKey.startsWith('exclude'))) {
|
|
// @ts-expect-error -- TODO: fix me
|
|
delete newRule[newKey];
|
|
}
|
|
});
|
|
newRule.matchUpdateTypes = coerceArray(rule.matchUpdateTypes);
|
|
newRule.matchUpdateTypes.push(key);
|
|
newRule = { ...newRule, ...val };
|
|
newRules.push(newRule);
|
|
}
|
|
}
|
|
}
|
|
for (const rule of newRules) {
|
|
updateTypes.forEach((updateType) => {
|
|
delete rule[updateType];
|
|
});
|
|
}
|
|
newRules = newRules.filter((rule) => {
|
|
if (
|
|
Object.keys(rule).every(
|
|
(key) => key.startsWith('match') || key.startsWith('exclude'),
|
|
)
|
|
) {
|
|
// Exclude rules which contain only match or exclude options
|
|
return false;
|
|
}
|
|
return true;
|
|
});
|
|
massagedConfig.packageRules = newRules;
|
|
}
|
|
return massagedConfig;
|
|
}
|