mirror of
https://github.com/renovatebot/renovate.git
synced 2026-10-31 17:51:49 +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()`.
118 lines
4.3 KiB
TypeScript
118 lines
4.3 KiB
TypeScript
import { isNonEmptyArray } from '@sindresorhus/is';
|
|
import { getManagerConfig, mergeChildConfig } from '../../../config/index.ts';
|
|
import type { ManagerConfig, RenovateConfig } from '../../../config/types.ts';
|
|
import { instrument } from '../../../instrumentation/index.ts';
|
|
import { logger } from '../../../logger/index.ts';
|
|
import { isCustomManager } from '../../../modules/manager/custom/index.ts';
|
|
import {
|
|
getEnabledManagersList,
|
|
hashMap,
|
|
} from '../../../modules/manager/index.ts';
|
|
import { scm } from '../../../modules/platform/scm.ts';
|
|
import { coerceArray } from '../../../util/array.ts';
|
|
import type { ExtractResult, WorkerExtractConfig } from '../../types.ts';
|
|
import { getMatchingFiles } from './file-match.ts';
|
|
import { getManagerPackageFiles } from './manager-files.ts';
|
|
import { processSupersedesManagers } from './supersedes.ts';
|
|
|
|
export async function extractAllDependencies(
|
|
config: RenovateConfig,
|
|
): Promise<ExtractResult> {
|
|
const managerList = getEnabledManagersList(config.enabledManagers);
|
|
const extractList: WorkerExtractConfig[] = [];
|
|
const fileList = await scm.getFileList();
|
|
|
|
function tryConfig(managerConfig: ManagerConfig): void {
|
|
const matchingFileList = getMatchingFiles(managerConfig, fileList);
|
|
if (matchingFileList.length) {
|
|
extractList.push({ ...managerConfig, fileList: matchingFileList });
|
|
}
|
|
}
|
|
|
|
instrument('filter packageFiles for managers', () => {
|
|
for (const manager of managerList) {
|
|
const managerConfig = getManagerConfig(config, manager);
|
|
managerConfig.manager = manager;
|
|
if (isCustomManager(manager)) {
|
|
const filteredCustomManagers = coerceArray(
|
|
config.customManagers,
|
|
).filter((mgr) => mgr.customType === manager);
|
|
for (const customManager of filteredCustomManagers) {
|
|
tryConfig(mergeChildConfig(managerConfig, customManager));
|
|
}
|
|
} else {
|
|
tryConfig(managerConfig);
|
|
}
|
|
}
|
|
});
|
|
|
|
const extractResult: ExtractResult = {
|
|
packageFiles: {},
|
|
extractionFingerprints: {},
|
|
};
|
|
|
|
// Store the fingerprint of all managers which match any file (even if they do not find any dependencies)
|
|
// The cached result needs to be invalidated if the fingerprint of any matching manager changes
|
|
for (const { manager } of extractList) {
|
|
extractResult.extractionFingerprints[manager] = hashMap.get(manager);
|
|
}
|
|
|
|
const extractDurations: Record<string, number> = {};
|
|
const extractResults = await Promise.all(
|
|
extractList.map(async (managerConfig) => {
|
|
const start = Date.now();
|
|
const packageFiles = await instrument(
|
|
managerConfig.manager,
|
|
async () => await getManagerPackageFiles(managerConfig),
|
|
);
|
|
const durationMs = Math.round(Date.now() - start);
|
|
extractDurations[managerConfig.manager] = durationMs;
|
|
return { manager: managerConfig.manager, packageFiles };
|
|
}),
|
|
);
|
|
|
|
// De-duplicate results using supersedesManagers
|
|
processSupersedesManagers(extractResults);
|
|
|
|
// Sort alphabetically for stable log output. See #40091
|
|
const sortedExtractDurations = Object.keys(extractDurations)
|
|
.sort()
|
|
.reduce<Record<string, number>>((acc, key) => {
|
|
acc[key] = extractDurations[key];
|
|
return acc;
|
|
}, {});
|
|
|
|
logger.debug(
|
|
{ managers: sortedExtractDurations },
|
|
'manager extract durations (ms)',
|
|
);
|
|
let fileCount = 0;
|
|
for (const { manager, packageFiles } of extractResults) {
|
|
if (packageFiles?.length) {
|
|
fileCount += packageFiles.length;
|
|
logger.debug(`Found ${manager} package files`);
|
|
extractResult.packageFiles[manager] = (
|
|
extractResult.packageFiles[manager] || []
|
|
).concat(packageFiles);
|
|
}
|
|
}
|
|
logger.debug(`Found ${fileCount} package file(s)`);
|
|
|
|
// If enabledManagers is non-empty, check that each of them has at least one extraction.
|
|
// If not, log a warning to indicate possible misconfiguration.
|
|
if (isNonEmptyArray(config.enabledManagers)) {
|
|
for (const enabledManager of config.enabledManagers) {
|
|
if (
|
|
!(enabledManager.replace('custom.', '') in extractResult.packageFiles)
|
|
) {
|
|
logger.debug(
|
|
{ manager: enabledManager },
|
|
`Manager explicitly enabled in "enabledManagers" config, but found no results. Possible config error?`,
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
return extractResult;
|
|
}
|