mirror of
https://github.com/renovatebot/renovate.git
synced 2026-11-01 10:09:50 +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()`.
100 lines
3.4 KiB
TypeScript
100 lines
3.4 KiB
TypeScript
import { isArray, isNonEmptyStringAndNotWhitespace } from '@sindresorhus/is';
|
|
import { dequal } from 'dequal';
|
|
import type { RenovateConfig } from '../../../../config/types.ts';
|
|
import { logger } from '../../../../logger/index.ts';
|
|
import { platform } from '../../../../modules/platform/index.ts';
|
|
import { coerceArray } from '../../../../util/array.ts';
|
|
import * as template from '../../../../util/template/index.ts';
|
|
|
|
/**
|
|
* Filter labels that go over the maximum char limit, based on platform limits.
|
|
*/
|
|
function trimLabel(label: string, limit: number): string {
|
|
const trimmed = label.trim();
|
|
if (trimmed.length <= limit) {
|
|
return trimmed;
|
|
}
|
|
|
|
return trimmed.slice(0, limit).trim();
|
|
}
|
|
|
|
export function prepareLabels(config: RenovateConfig): string[] {
|
|
const labelCharLimit = platform.labelCharLimit?.() ?? 50;
|
|
const labels = coerceArray(config.labels);
|
|
const addLabels = coerceArray(config.addLabels);
|
|
return [...new Set([...labels, ...addLabels])]
|
|
.filter(isNonEmptyStringAndNotWhitespace)
|
|
.map((label) => template.compile(label, config))
|
|
.filter(isNonEmptyStringAndNotWhitespace)
|
|
.map((label) => trimLabel(label, labelCharLimit))
|
|
.sort();
|
|
}
|
|
|
|
/**
|
|
* Determine changed labels between old and new label arrays.
|
|
*
|
|
* This function takes two arrays of labels, 'oldLabels' and 'newLabels', and calculates the labels
|
|
* that need to be added and removed to transition from 'oldLabels' to 'newLabels'.
|
|
*/
|
|
export function getChangedLabels(
|
|
oldLabels: string[] | undefined,
|
|
newLabels: string[] | undefined,
|
|
): [string[] | undefined, string[] | undefined] {
|
|
const labelsToAdd = newLabels?.filter((l) => !oldLabels?.includes(l));
|
|
const labelsToRemove = oldLabels?.filter((l) => !newLabels?.includes(l));
|
|
|
|
return [labelsToAdd, labelsToRemove];
|
|
}
|
|
|
|
/**
|
|
* Check if labels in the PR have been modified.
|
|
*
|
|
* This function compares two arrays of labels, 'prInitialLabels' and 'prCurrentLabels',
|
|
* to determine if they are different, indicating that labels in the PR have been modified.
|
|
*/
|
|
export function areLabelsModified(
|
|
prInitialLabels: string[],
|
|
prCurrentLabels: string[],
|
|
): boolean {
|
|
const modified = !dequal(prInitialLabels.sort(), prCurrentLabels.sort());
|
|
|
|
if (modified) {
|
|
logger.debug(
|
|
{ prInitialLabels, prCurrentLabels },
|
|
'PR labels have been modified by user, skipping labels update',
|
|
);
|
|
}
|
|
|
|
return modified;
|
|
}
|
|
|
|
/**
|
|
* Determine if labels should be updated in the Pull Request.
|
|
*/
|
|
export function shouldUpdateLabels(
|
|
prInitialLabels: string[] | undefined,
|
|
prCurrentLabels: string[] | undefined,
|
|
configuredLabels: string[] | undefined,
|
|
): boolean {
|
|
// If the 'labelsInDebugData' field is undefined
|
|
// it means the PR was created before the update-labels logic was merged, and labels should not be updated.
|
|
// Reference: https://github.com/renovatebot/renovate/pull/25340
|
|
if (!isArray(prInitialLabels)) {
|
|
return false;
|
|
}
|
|
|
|
// If the labels are unchanged, they should not be updated
|
|
if (dequal(coerceArray(configuredLabels).sort(), prInitialLabels.sort())) {
|
|
return false;
|
|
}
|
|
|
|
// If the labels in the PR have been modified by the user, they should not be updated
|
|
if (areLabelsModified(prInitialLabels, coerceArray(prCurrentLabels))) {
|
|
logger.debug('Labels have been modified by user - skipping labels update.');
|
|
return false;
|
|
}
|
|
|
|
logger.debug('Labels have been changed in repo config- updating labels.');
|
|
return true;
|
|
}
|