0
0
Fork 0
mirror of https://github.com/renovatebot/renovate.git synced 2025-01-11 13:48:55 +00:00
renovatebot_renovate/lib/modules/manager/gitlabci-include/extract.ts

107 lines
3 KiB
TypeScript

import is from '@sindresorhus/is';
import { GlobalConfig } from '../../../config/global';
import { logger } from '../../../logger';
import { regEx } from '../../../util/regex';
import { parseYaml } from '../../../util/yaml';
import { GitlabTagsDatasource } from '../../datasource/gitlab-tags';
import {
filterIncludeFromGitlabPipeline,
isGitlabIncludeProject,
isNonEmptyObject,
} from '../gitlabci/common';
import type {
GitlabInclude,
GitlabIncludeProject,
GitlabPipeline,
} from '../gitlabci/types';
import type { PackageDependency, PackageFileContent } from '../types';
function extractDepFromIncludeFile(
includeObj: GitlabIncludeProject,
): PackageDependency {
const dep: PackageDependency = {
datasource: GitlabTagsDatasource.id,
depName: includeObj.project,
depType: 'repository',
};
if (!includeObj.ref) {
dep.skipReason = 'unspecified-version';
return dep;
}
dep.currentValue = includeObj.ref;
return dep;
}
function getIncludeProjectsFromInclude(
includeValue: GitlabInclude[] | GitlabInclude,
): GitlabIncludeProject[] {
const includes = is.array(includeValue) ? includeValue : [includeValue];
// Filter out includes that dont have a file & project.
return includes.filter(isGitlabIncludeProject);
}
function getAllIncludeProjects(data: GitlabPipeline): GitlabIncludeProject[] {
// If Array, search each element.
if (is.array(data)) {
return (data as GitlabPipeline[])
.filter(isNonEmptyObject)
.map(getAllIncludeProjects)
.flat();
}
const childrenData = Object.values(filterIncludeFromGitlabPipeline(data))
.filter(isNonEmptyObject)
.map(getAllIncludeProjects)
.flat();
// Process include key.
if (data.include) {
childrenData.push(...getIncludeProjectsFromInclude(data.include));
}
return childrenData;
}
export function extractPackageFile(
content: string,
packageFile?: string,
): PackageFileContent | null {
const deps: PackageDependency[] = [];
const platform = GlobalConfig.get('platform');
const endpoint = GlobalConfig.get('endpoint');
const registryUrls =
platform === 'gitlab' && endpoint
? [endpoint.replace(regEx(/\/api\/v4\/?/), '')]
: null;
try {
// TODO: use schema (#9610)
const docs = parseYaml<GitlabPipeline>(content, {
uniqueKeys: false,
});
for (const doc of docs) {
if (is.object(doc)) {
const includes = getAllIncludeProjects(doc);
for (const includeObj of includes) {
const dep = extractDepFromIncludeFile(includeObj);
if (registryUrls) {
dep.registryUrls = registryUrls;
}
deps.push(dep);
}
}
}
} catch (err) /* istanbul ignore next */ {
if (err.stack?.startsWith('YAMLException:')) {
logger.debug(
{ err, packageFile },
'YAML exception extracting GitLab CI includes',
);
} else {
logger.debug({ err, packageFile }, 'Error extracting GitLab CI includes');
}
}
if (!deps.length) {
return null;
}
return { deps };
}