UNPKG

renovate

Version:

Automated dependency updates. Flexible so you don't need to be.

285 lines • 12.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.extractPackageFile = extractPackageFile; exports.extractAllPackageFiles = extractAllPackageFiles; const tslib_1 = require("tslib"); const is_1 = tslib_1.__importDefault(require("@sindresorhus/is")); const logger_1 = require("../../../logger"); const array_1 = require("../../../util/array"); const fs_1 = require("../../../util/fs"); const regex_1 = require("../../../util/regex"); const url_1 = require("../../../util/url"); const yaml_1 = require("../../../util/yaml"); const bitbucket_tags_1 = require("../../datasource/bitbucket-tags"); const docker_1 = require("../../datasource/docker"); const git_refs_1 = require("../../datasource/git-refs"); const git_tags_1 = require("../../datasource/git-tags"); const github_releases_1 = require("../../datasource/github-releases"); const github_tags_1 = require("../../datasource/github-tags"); const gitlab_tags_1 = require("../../datasource/gitlab-tags"); const helm_1 = require("../../datasource/helm"); const extract_1 = require("../dockerfile/extract"); const extract_2 = require("../helm-values/extract"); const oci_1 = require("../helmv3/oci"); const extract_3 = require("../kustomize/extract"); const common_1 = require("./common"); const schema_1 = require("./schema"); function readManifest(content, packageFile) { if ((0, common_1.isSystemManifest)(packageFile)) { const versionMatch = (0, regex_1.regEx)(common_1.systemManifestHeaderRegex).exec(content); if (!versionMatch) { return null; } return { kind: 'system', file: packageFile, version: versionMatch[1], components: versionMatch[2], }; } return { kind: 'resource', file: packageFile, resources: (0, yaml_1.parseYaml)(content, { customSchema: schema_1.FluxResource, failureBehaviour: 'filter', }), }; } const githubUrlRegex = (0, regex_1.regEx)(/^(?:https:\/\/|git@)github\.com[/:](?<packageName>[^/]+\/[^/]+?)(?:\.git)?$/); const gitlabUrlRegex = (0, regex_1.regEx)(/^(?:https:\/\/|git@)gitlab\.com[/:](?<packageName>[^/]+\/[^/]+?)(?:\.git)?$/); const bitbucketUrlRegex = (0, regex_1.regEx)(/^(?:https:\/\/|git@)bitbucket\.org[/:](?<packageName>[^/]+\/[^/]+?)(?:\.git)?$/); function resolveGitRepositoryPerSourceTag(dep, gitUrl) { const githubMatchGroups = githubUrlRegex.exec(gitUrl)?.groups; if (githubMatchGroups) { dep.datasource = github_tags_1.GithubTagsDatasource.id; dep.packageName = githubMatchGroups.packageName; dep.sourceUrl = `https://github.com/${dep.packageName}`; return; } const gitlabMatchGroups = gitlabUrlRegex.exec(gitUrl)?.groups; if (gitlabMatchGroups) { dep.datasource = gitlab_tags_1.GitlabTagsDatasource.id; dep.packageName = gitlabMatchGroups.packageName; dep.sourceUrl = `https://gitlab.com/${dep.packageName}`; return; } const bitbucketMatchGroups = bitbucketUrlRegex.exec(gitUrl)?.groups; if (bitbucketMatchGroups) { dep.datasource = bitbucket_tags_1.BitbucketTagsDatasource.id; dep.packageName = bitbucketMatchGroups.packageName; dep.sourceUrl = `https://bitbucket.org/${dep.packageName}`; return; } dep.datasource = git_tags_1.GitTagsDatasource.id; dep.packageName = gitUrl; if ((0, url_1.isHttpUrl)(gitUrl)) { dep.sourceUrl = gitUrl.replace(/\.git$/, ''); } } function resolveHelmRepository(dep, matchingRepositories, registryAliases) { if (matchingRepositories.length) { dep.registryUrls = matchingRepositories .map((repo) => { if (repo.spec.type === 'oci' || (0, oci_1.isOCIRegistry)(repo.spec.url)) { // Change datasource to Docker dep.datasource = docker_1.DockerDatasource.id; // Ensure the URL is a valid OCI path dep.packageName = (0, extract_1.getDep)(`${(0, oci_1.removeOCIPrefix)(repo.spec.url)}/${dep.depName}`, false, registryAliases).packageName; return null; } else { return repo.spec.url; } }) .filter(is_1.default.string); // if registryUrls is empty, delete it from dep if (!dep.registryUrls?.length) { delete dep.registryUrls; } } else { dep.skipReason = 'unknown-registry'; } } function resolveSystemManifest(manifest) { return [ { depName: 'fluxcd/flux2', datasource: github_releases_1.GithubReleasesDatasource.id, currentValue: manifest.version, managerData: { components: manifest.components, }, }, ]; } function resolveResourceManifest(manifest, helmRepositories, registryAliases) { const deps = []; for (const resource of manifest.resources) { switch (resource.kind) { case 'HelmRelease': { if (resource.spec.chartRef) { logger_1.logger.trace('HelmRelease using chartRef was found, skipping as version will be handled via referenced resource directly'); } else if (resource.spec.chart) { const chartSpec = resource.spec.chart.spec; const depName = chartSpec.chart; const dep = { depName, currentValue: resource.spec.chart.spec.version, datasource: helm_1.HelmDatasource.id, }; if (depName.startsWith('./')) { dep.skipReason = 'local-chart'; delete dep.datasource; } else { const matchingRepositories = helmRepositories.filter((rep) => rep.kind === chartSpec.sourceRef?.kind && rep.metadata.name === chartSpec.sourceRef.name && rep.metadata.namespace === (chartSpec.sourceRef.namespace ?? resource.metadata?.namespace)); resolveHelmRepository(dep, matchingRepositories, registryAliases); } deps.push(dep); } else { logger_1.logger.debug(`invalid or incomplete ${resource.metadata.name} HelmRelease spec, skipping`); } if (resource.spec.values) { logger_1.logger.trace('detecting dependencies in HelmRelease values'); deps.push(...(0, extract_2.findDependencies)(resource.spec.values, registryAliases)); } break; } case 'HelmChart': { if (resource.spec.sourceRef.kind === 'GitRepository') { logger_1.logger.trace('HelmChart using GitRepository was found, skipping as version will be handled via referenced resource directly'); continue; } const dep = { depName: resource.spec.chart, }; if (resource.spec.sourceRef.kind === 'HelmRepository') { dep.currentValue = resource.spec.version; dep.datasource = helm_1.HelmDatasource.id; const matchingRepositories = helmRepositories.filter((rep) => rep.kind === resource.spec.sourceRef?.kind && rep.metadata.name === resource.spec.sourceRef.name && rep.metadata.namespace === resource.metadata?.namespace); resolveHelmRepository(dep, matchingRepositories, registryAliases); } else { dep.skipReason = 'unsupported-datasource'; } deps.push(dep); break; } case 'GitRepository': { const dep = { depName: resource.metadata.name, }; if (resource.spec.ref?.commit) { const gitUrl = resource.spec.url; dep.currentDigest = resource.spec.ref.commit; dep.datasource = git_refs_1.GitRefsDatasource.id; dep.packageName = gitUrl; dep.replaceString = resource.spec.ref.commit; if ((0, url_1.isHttpUrl)(gitUrl)) { dep.sourceUrl = gitUrl.replace(/\.git$/, ''); } } else if (resource.spec.ref?.tag) { dep.currentValue = resource.spec.ref.tag; resolveGitRepositoryPerSourceTag(dep, resource.spec.url); } else { dep.skipReason = 'unversioned-reference'; } deps.push(dep); break; } case 'OCIRepository': { const container = (0, oci_1.removeOCIPrefix)(resource.spec.url); let dep = (0, extract_1.getDep)(container, false, registryAliases); if (resource.spec.ref?.digest) { dep = (0, extract_1.getDep)(`${container}@${resource.spec.ref.digest}`, false, registryAliases); if (resource.spec.ref?.tag) { logger_1.logger.debug('A digest and tag was found, ignoring tag'); } } else if (resource.spec.ref?.tag) { dep = (0, extract_1.getDep)(`${container}:${resource.spec.ref.tag}`, false, registryAliases); dep.autoReplaceStringTemplate = '{{#if newValue}}{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}'; dep.replaceString = resource.spec.ref.tag; } else { dep.skipReason = 'unversioned-reference'; } deps.push(dep); break; } case 'Kustomization': { for (const image of (0, array_1.coerceArray)(resource.spec.images)) { const dep = (0, extract_3.extractImage)(image, registryAliases); if (dep) { deps.push(dep); } } } } } return deps; } function extractPackageFile(content, packageFile, config) { const manifest = readManifest(content, packageFile); if (!manifest) { return null; } const helmRepositories = (0, common_1.collectHelmRepos)([manifest]); let deps = null; switch (manifest.kind) { case 'system': deps = resolveSystemManifest(manifest); break; case 'resource': { deps = resolveResourceManifest(manifest, helmRepositories, config?.registryAliases); break; } } return deps?.length ? { deps } : null; } async function extractAllPackageFiles(config, packageFiles) { const manifests = []; const results = []; for (const file of packageFiles) { const content = await (0, fs_1.readLocalFile)(file, 'utf8'); // TODO #22198 const manifest = readManifest(content, file); if (manifest) { manifests.push(manifest); } } const helmRepositories = (0, common_1.collectHelmRepos)(manifests); for (const manifest of manifests) { let deps = null; switch (manifest.kind) { case 'system': deps = resolveSystemManifest(manifest); break; case 'resource': { deps = resolveResourceManifest(manifest, helmRepositories, config.registryAliases); break; } } if (deps?.length) { results.push({ packageFile: manifest.file, deps, }); } } return results.length ? results : null; } //# sourceMappingURL=extract.js.map