Files
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

68 lines
2.1 KiB
TypeScript

import { isObject, isString } from '@sindresorhus/is';
import { logger } from '../../../logger/index.ts';
import { coerceObject } from '../../../util/object.ts';
import { parseSingleYaml } from '../../../util/yaml.ts';
import { getDep } from '../dockerfile/extract.ts';
import type { ExtractConfig, PackageFileContent } from '../types.ts';
import type { WoodpeckerConfig } from './types.ts';
function woodpeckerVersionDecider(
woodpeckerConfig: WoodpeckerConfig,
): (keyof WoodpeckerConfig)[] {
const keys = ['clone', 'steps', 'pipeline', 'services'];
return Object.keys(woodpeckerConfig).filter((key) =>
keys.includes(key),
) as (keyof WoodpeckerConfig)[];
}
export function extractPackageFile(
content: string,
packageFile: string,
extractConfig: ExtractConfig,
): PackageFileContent | null {
logger.debug('woodpecker.extractPackageFile()');
let config: WoodpeckerConfig;
try {
// TODO: use schema (#9610)
config = parseSingleYaml(content);
if (!config) {
logger.debug(
{ packageFile },
'Null config when parsing Woodpecker Configuration content',
);
return null;
}
if (!isObject(config)) {
logger.debug(
{ packageFile, type: typeof config },
'Unexpected type for Woodpecker Configuration content',
);
return null;
}
} catch (err) {
logger.debug(
{ packageFile, err },
'Error parsing Woodpecker Configuration config YAML',
);
return null;
}
const pipelineKeys = woodpeckerVersionDecider(config);
if (pipelineKeys.length === 0) {
logger.debug({ packageFile }, "Couldn't identify dependencies");
return null;
}
// Image name/tags for services are only eligible for update if they don't
// use variables and if the image is not built locally
const deps = pipelineKeys.flatMap((pipelineKey) =>
Object.values(coerceObject(config[pipelineKey]))
.filter((step) => isString(step?.image))
.map((step) => getDep(step.image, true, extractConfig.registryAliases)),
);
logger.trace({ deps }, 'Woodpecker Configuration image');
return deps.length ? { deps } : null;
}