import { isObject } from '@sindresorhus/is'; import { logger } from '../../../logger/index.ts'; import { parseYaml } from '../../../util/yaml.ts'; import { id as dockerVersioning } from '../../versioning/docker/index.ts'; import { getDep } from '../dockerfile/extract.ts'; import type { ExtractConfig, PackageDependency, PackageFileContent, } from '../types.ts'; import type { HelmDockerImageDependency } from './types.ts'; import { matchesHelmValuesDockerHeuristic, matchesHelmValuesInlineImage, } from './util.ts'; function getHelmDep( registry: string, repository: string, tag: string, registryAliases: Record | undefined, ): PackageDependency { const dep = getDep(`${registry}${repository}:${tag}`, false, registryAliases); dep.replaceString = tag; dep.versioning = dockerVersioning; dep.autoReplaceStringTemplate = '{{newValue}}{{#if newDigest}}@{{newDigest}}{{/if}}'; return dep; } /** * Recursively find all supported dependencies in the yaml object. * * @param parsedContent */ export function findDependencies( parsedContent: Record | HelmDockerImageDependency, registryAliases: Record | undefined, ): PackageDependency[] { return findDependenciesInternal(parsedContent, [], registryAliases); } export function findDependenciesInternal( parsedContent: Record | HelmDockerImageDependency, packageDependencies: PackageDependency[], registryAliases: Record | undefined, ): PackageDependency[] { if (!isObject(parsedContent)) { return packageDependencies; } Object.entries(parsedContent).forEach(([key, value]) => { if (matchesHelmValuesDockerHeuristic(key, value)) { const currentItem = value; let registry = currentItem.registry; registry = registry ? `${registry}/` : ''; const repository = String(currentItem.repository); const tag = `${currentItem.tag ?? currentItem.version}`; packageDependencies.push( getHelmDep(registry, repository, tag, registryAliases), ); } else if (matchesHelmValuesInlineImage(key, value)) { packageDependencies.push(getDep(value, true, registryAliases)); } else { findDependenciesInternal( value as Record, packageDependencies, registryAliases, ); } }); return packageDependencies; } export function extractPackageFile( content: string, packageFile: string, config: ExtractConfig, ): PackageFileContent | null { let parsedContent: Record[] | HelmDockerImageDependency[]; try { // a parser that allows extracting line numbers would be preferable, with // the current approach we need to match anything we find again during the update // TODO: fix me (#9610) parsedContent = parseYaml(content) as any; } catch (err) { logger.debug({ err, packageFile }, 'Failed to parse helm-values YAML'); return null; } try { const deps: PackageDependency[] = []; for (const con of parsedContent) { deps.push(...findDependencies(con, config.registryAliases)); } if (deps.length) { return { deps }; } } catch (err) /* istanbul ignore next */ { logger.debug( { err, packageFile }, 'Error parsing helm-values parsed content', ); } return null; }