Files
renovate/lib/modules/manager/circleci/extract.ts
Sebastian Poxhofer c32e2391a0 refactor(linters): add prefer-coerce-object rule (#45493)
Refs #45216

The object counterpart to `prefer-coerce-array`: `x ?? {}` becomes
`coerceObject(x)`. The rule flags a `??` whose default is a bare `{}`
literal, so a populated default or an asserted `({} as Foo)` still
passes; a `x ?? y ?? {}` chain maps onto `coerceObject(x, y)`.

Every hit across `lib/` converted cleanly, so no disable comments were
needed.
2026-08-28 09:27:59 +00:00

82 lines
2.3 KiB
TypeScript

import { isString } from '@sindresorhus/is';
import { logger } from '../../../logger/index.ts';
import { coerceObject } from '../../../util/object.ts';
import { Result } from '../../../util/result.ts';
import { parseSingleYaml } from '../../../util/yaml.ts';
import { OrbDatasource } from '../../datasource/orb/index.ts';
import * as npmVersioning from '../../versioning/npm/index.ts';
import { getDep } from '../dockerfile/extract.ts';
import type {
ExtractConfig,
PackageDependency,
PackageFileContent,
} from '../types.ts';
import { CircleCiFile, type CircleCiOrb } from './schema.ts';
function extractDefinition(
deps: PackageDependency[],
definition: CircleCiOrb | CircleCiFile,
registryAliases: Record<string, string>,
): void {
for (const [key, orb] of Object.entries(definition.orbs)) {
if (isString(orb)) {
const [packageName, currentValue] = orb.split('@');
deps.push({
depName: key,
packageName,
depType: 'orb',
currentValue,
versioning: npmVersioning.id,
datasource: OrbDatasource.id,
});
} else {
extractDefinition(deps, orb, registryAliases);
}
}
// extract environments
const environments = [...definition.executors, ...definition.jobs];
for (const dockerImage of environments) {
deps.push({
...getDep(dockerImage, true, registryAliases),
depType: 'docker',
});
}
}
export function extractPackageFile(
content: string,
packageFile?: string,
config?: ExtractConfig,
): PackageFileContent | null {
const { val: parsed, err } = Result.wrap(() =>
// Parse as YAML 1.1 so anchor merge keys (`<<`) work, matching CircleCI's
// own behavior. Under YAML 1.2 a mapping with multiple `<<` keys is
// rejected as a duplicate key, which causes the whole file to be skipped.
CircleCiFile.parse(parseSingleYaml(content, { version: '1.1' })),
).unwrap();
if (err) {
logger.debug({ err, packageFile }, 'Error extracting circleci images');
return null;
}
const registryAliases = coerceObject(config?.registryAliases);
const deps: PackageDependency[] = [];
extractDefinition(deps, parsed, registryAliases);
for (const alias of parsed.aliases) {
deps.push({
...getDep(alias, true, registryAliases),
depType: 'docker',
});
}
if (!deps.length) {
return null;
}
return { deps };
}