renovate
Version:
Automated dependency updates. Flexible so you don't need to be.
230 lines • 8.21 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.extractResource = extractResource;
exports.extractImage = extractImage;
exports.extractHelmChart = extractHelmChart;
exports.parseKustomize = parseKustomize;
exports.extractPackageFile = extractPackageFile;
const tslib_1 = require("tslib");
const node_querystring_1 = tslib_1.__importDefault(require("node:querystring"));
const is_1 = tslib_1.__importDefault(require("@sindresorhus/is"));
const logger_1 = require("../../../logger");
const array_1 = require("../../../util/array");
const regex_1 = require("../../../util/regex");
const yaml_1 = require("../../../util/yaml");
const git_tags_1 = require("../../datasource/git-tags");
const github_tags_1 = require("../../datasource/github-tags");
const helm_1 = require("../../datasource/helm");
const extract_1 = require("../dockerfile/extract");
const oci_1 = require("../helmv3/oci");
// URL specifications should follow the hashicorp URL format
// https://github.com/hashicorp/go-getter#url-format
const gitUrl = (0, regex_1.regEx)(/^(?:git::)?(?<url>(?:(?:(?:http|https|ssh):\/\/)?(?:.*@)?)?(?<path>(?:[^:/\s]+(?::[0-9]+)?[:/])?(?<project>[^/\s]+\/[^/\s]+)))(?<subdir>[^?\s]*)\?(?<queryString>.+)$/);
// regex to match URLs with ".git" delimiter
const dotGitRegex = (0, regex_1.regEx)(/^(?:git::)?(?<url>(?:(?:(?:http|https|ssh):\/\/)?(?:.*@)?)?(?<path>(?:[^:/\s]+(?::[0-9]+)?[:/])?(?<project>[^?\s]*(\.git))))(?<subdir>[^?\s]*)\?(?<queryString>.+)$/);
// regex to match URLs with "_git" delimiter
const underscoreGitRegex = (0, regex_1.regEx)(/^(?:git::)?(?<url>(?:(?:(?:http|https|ssh):\/\/)?(?:.*@)?)?(?<path>(?:[^:/\s]+(?::[0-9]+)?[:/])?(?<project>[^?\s]*)(_git\/[^/\s]+)))(?<subdir>[^?\s]*)\?(?<queryString>.+)$/);
// regex to match URLs having an extra "//"
const gitUrlWithPath = (0, regex_1.regEx)(/^(?:git::)?(?<url>(?:(?:(?:http|https|ssh):\/\/)?(?:.*@)?)?(?<path>(?:[^:/\s]+(?::[0-9]+)?[:/])(?<project>[^?\s]+)))(?:\/\/)(?<subdir>[^?\s]+)\?(?<queryString>.+)$/);
function extractResource(base) {
let match;
if (base.includes('_git')) {
match = underscoreGitRegex.exec(base);
}
else if (base.includes('.git')) {
match = dotGitRegex.exec(base);
}
else if (gitUrlWithPath.test(base)) {
match = gitUrlWithPath.exec(base);
}
else {
match = gitUrl.exec(base);
}
if (!match?.groups) {
return null;
}
const { path, queryString } = match.groups;
const params = node_querystring_1.default.parse(queryString);
const refParam = Array.isArray(params.ref) ? params.ref[0] : params.ref;
const versionParam = Array.isArray(params.version)
? params.version[0]
: params.version;
const currentValue = refParam ?? versionParam;
if (!currentValue) {
return null;
}
if ((0, regex_1.regEx)(/(?:github\.com)(:|\/)/).test(path)) {
return {
currentValue,
datasource: github_tags_1.GithubTagsDatasource.id,
depName: match.groups.project.replace('.git', ''),
};
}
return {
datasource: git_tags_1.GitTagsDatasource.id,
depName: path.replace('.git', ''),
packageName: match.groups.url,
currentValue,
};
}
function extractImage(image, aliases) {
if (!image.name) {
return null;
}
const nameToSplit = image.newName ?? image.name;
if (!is_1.default.string(nameToSplit)) {
logger_1.logger.debug({ image }, 'Invalid image name');
return null;
}
const nameDep = (0, extract_1.getDep)(nameToSplit, false, aliases);
const { depName } = nameDep;
const { digest, newTag } = image;
if (digest && newTag) {
logger_1.logger.debug({ newTag, digest }, 'Kustomize ignores newTag when digest is provided. Pick one, or use `newTag: tag@digest`');
return {
depName,
currentValue: newTag,
currentDigest: digest,
skipReason: 'invalid-dependency-specification',
};
}
if (digest) {
if (!is_1.default.string(digest) || !digest.startsWith('sha256:')) {
return {
depName,
currentValue: digest,
skipReason: 'invalid-value',
};
}
return {
...nameDep,
currentDigest: digest,
replaceString: digest,
};
}
if (newTag) {
if (!is_1.default.string(newTag) || newTag.startsWith('sha256:')) {
return {
depName,
currentValue: newTag,
skipReason: 'invalid-value',
};
}
const dep = (0, extract_1.getDep)(`${depName}:${newTag}`, false, aliases);
return {
...dep,
replaceString: newTag,
autoReplaceStringTemplate: '{{newValue}}{{#if newDigest}}@{{newDigest}}{{/if}}',
};
}
if (image.newName) {
return {
...nameDep,
replaceString: image.newName,
};
}
return null;
}
function extractHelmChart(helmChart, aliases) {
if (!helmChart.name) {
return null;
}
if ((0, oci_1.isOCIRegistry)(helmChart.repo)) {
const dep = (0, extract_1.getDep)(`${(0, oci_1.removeOCIPrefix)(helmChart.repo)}/${helmChart.name}:${helmChart.version}`, false, aliases);
return {
...dep,
depName: helmChart.name,
// https://github.com/helm/helm/issues/10312
// https://github.com/helm/helm/issues/10678
pinDigests: false,
};
}
return {
depName: helmChart.name,
currentValue: helmChart.version,
registryUrls: [helmChart.repo],
datasource: helm_1.HelmDatasource.id,
};
}
function parseKustomize(content, packageFile) {
let pkg = null;
try {
// TODO: use schema (#9610)
pkg = (0, yaml_1.parseSingleYaml)(content);
}
catch /* istanbul ignore next */ {
logger_1.logger.debug({ packageFile }, 'Error parsing kustomize file');
return null;
}
if (!pkg || is_1.default.string(pkg)) {
return null;
}
pkg.kind ??= 'Kustomization';
if (!['Kustomization', 'Component'].includes(pkg.kind)) {
return null;
}
return pkg;
}
function extractPackageFile(content, packageFile, config) {
logger_1.logger.trace(`kustomize.extractPackageFile(${packageFile})`);
const deps = [];
const pkg = parseKustomize(content, packageFile);
if (!pkg) {
return null;
}
// grab the remote bases
for (const base of (0, array_1.coerceArray)(pkg.bases).filter(is_1.default.string)) {
const dep = extractResource(base);
if (dep) {
deps.push({
...dep,
depType: pkg.kind,
});
}
}
// grab the remote resources
for (const resource of (0, array_1.coerceArray)(pkg.resources).filter(is_1.default.string)) {
const dep = extractResource(resource);
if (dep) {
deps.push({
...dep,
depType: pkg.kind,
});
}
}
// grab the remote components
for (const component of (0, array_1.coerceArray)(pkg.components).filter(is_1.default.string)) {
const dep = extractResource(component);
if (dep) {
deps.push({
...dep,
depType: pkg.kind,
});
}
}
// grab the image tags
for (const image of (0, array_1.coerceArray)(pkg.images)) {
const dep = extractImage(image, config.registryAliases);
if (dep) {
deps.push({
...dep,
depType: pkg.kind,
});
}
}
// grab the helm charts
for (const helmChart of (0, array_1.coerceArray)(pkg.helmCharts)) {
const dep = extractHelmChart(helmChart, config.registryAliases);
if (dep) {
deps.push({
...dep,
depType: 'HelmChart',
});
}
}
if (!deps.length) {
return null;
}
return { deps };
}
//# sourceMappingURL=extract.js.map