UNPKG

renovate

Version:

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

168 lines • 7.79 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.extractPackageFile = extractPackageFile; const tslib_1 = require("tslib"); const is_1 = tslib_1.__importDefault(require("@sindresorhus/is")); const logger_1 = require("../../../logger"); const common_1 = require("../../../util/common"); const host_rules_1 = require("../../../util/host-rules"); const regex_1 = require("../../../util/regex"); const yaml_1 = require("../../../util/yaml"); const github_tags_1 = require("../../datasource/github-tags"); const gitlab_tags_1 = require("../../datasource/gitlab-tags"); const utils_1 = require("../pep621/utils"); const parsing_1 = require("./parsing"); /** * Determines the datasource(id) to be used for this dependency * @param repository the full git url, ie git@github.com/user/project. * Used in debug statements to clearly indicate the related dependency. * @param hostname the hostname (ie github.com) * Used to determine which renovate datasource should be used. * Is matched literally against `github.com` and `gitlab.com`. * If that doesn't match, `hostRules.find()` is used to find related sources. * In that case, the hostname is passed on as registryUrl to the corresponding datasource. */ function determineDatasource(repository, hostname) { if (hostname === 'github.com' || (0, common_1.detectPlatform)(repository) === 'github') { logger_1.logger.debug({ repository, hostname }, 'Found github dependency'); return { datasource: github_tags_1.GithubTagsDatasource.id }; } if (hostname === 'gitlab.com') { logger_1.logger.debug({ repository, hostname }, 'Found gitlab dependency'); return { datasource: gitlab_tags_1.GitlabTagsDatasource.id }; } if ((0, common_1.detectPlatform)(repository) === 'gitlab') { logger_1.logger.debug({ repository, hostname }, 'Found gitlab dependency with custom registryUrl'); return { datasource: gitlab_tags_1.GitlabTagsDatasource.id, registryUrls: ['https://' + hostname], }; } const hostUrl = 'https://' + hostname; const res = (0, host_rules_1.find)({ url: hostUrl }); if (is_1.default.emptyObject(res)) { // 1 check, to possibly prevent 3 failures in combined query of hostType & url. logger_1.logger.debug({ repository, hostUrl }, 'Provided hostname does not match any hostRules. Ignoring'); return { skipReason: 'unknown-registry', registryUrls: [hostname] }; } for (const [hostType, sourceId] of [ ['github', github_tags_1.GithubTagsDatasource.id], ['gitlab', gitlab_tags_1.GitlabTagsDatasource.id], ]) { if (is_1.default.nonEmptyObject((0, host_rules_1.find)({ hostType, url: hostUrl }))) { logger_1.logger.debug({ repository, hostUrl, hostType }, `Provided hostname matches a ${hostType} hostrule.`); return { datasource: sourceId, registryUrls: [hostname] }; } } logger_1.logger.debug({ repository, registry: hostUrl }, 'Provided hostname did not match any of the hostRules of hostType github nor gitlab'); return { skipReason: 'unknown-registry', registryUrls: [hostname] }; } function extractDependency(tag, repository) { logger_1.logger.debug(`Found version ${tag}`); const urlMatchers = [ // This splits "http://my.github.com/user/repo" -> "my.github.com" "user/repo (0, regex_1.regEx)('^https?://(?<hostname>[^/]+)/(?<depName>\\S*)'), // This splits "git@private.registry.com:user/repo" -> "private.registry.com" "user/repo (0, regex_1.regEx)('^git@(?<hostname>[^:]+):(?<depName>\\S*)'), // This split "git://github.com/pre-commit/pre-commit-hooks" -> "github.com" "pre-commit/pre-commit-hooks" (0, regex_1.regEx)(/^git:\/\/(?<hostname>[^/]+)\/(?<depName>\S*)/), // This splits "ssh://git@github.com/pre-commit/pre-commit-hooks" -> "github.com" "pre-commit/pre-commit-hooks" (0, regex_1.regEx)(/^ssh:\/\/git@(?<hostname>[^/]+)\/(?<depName>\S*)/), ]; for (const urlMatcher of urlMatchers) { const match = urlMatcher.exec(repository); if (match?.groups) { const hostname = match.groups.hostname; const depName = match.groups.depName.replace((0, regex_1.regEx)(/\.git$/i), ''); // TODO 12071 const sourceDef = determineDatasource(repository, hostname); return { ...sourceDef, depName, depType: 'repository', packageName: depName, currentValue: tag, }; } } logger_1.logger.info({ repository }, 'Could not separate hostname from full dependency url.'); return { depName: undefined, depType: 'repository', datasource: undefined, packageName: undefined, skipReason: 'invalid-url', currentValue: tag, }; } /** * Find all supported dependencies in the pre-commit yaml object. * * @param precommitFile the parsed yaml config file */ function findDependencies(precommitFile) { if (!precommitFile.repos) { logger_1.logger.debug(`No repos section found, skipping file`); return []; } const packageDependencies = []; precommitFile.repos.forEach((item) => { // meta hooks is defined from pre-commit and doesn't support `additional_dependencies` if (item.repo !== 'meta') { item.hooks?.forEach((hook) => { // normally language are not defined in yaml // only support it when it's explicitly defined. // this avoid to parse hooks from pre-commit-hooks.yaml from git repo if (hook.language === 'python') { hook.additional_dependencies?.map((req) => { const dep = (0, utils_1.pep508ToPackageDependency)('pre-commit-python', req); if (dep) { packageDependencies.push(dep); } }); } }); } if ((0, parsing_1.matchesPrecommitDependencyHeuristic)(item)) { logger_1.logger.trace(item, 'Matched pre-commit dependency spec'); const repository = String(item.repo); const tag = String(item.rev); const dep = extractDependency(tag, repository); packageDependencies.push(dep); } else { logger_1.logger.trace(item, 'Did not find pre-commit repo spec'); } }); return packageDependencies; } function extractPackageFile(content, packageFile) { let parsedContent; try { // TODO: use schema (#9610) parsedContent = (0, yaml_1.parseSingleYaml)(content); } catch (err) { logger_1.logger.debug({ filename: packageFile, err }, 'Failed to parse pre-commit config YAML'); return null; } if (!is_1.default.plainObject(parsedContent)) { logger_1.logger.debug({ packageFile }, `Parsing of pre-commit config YAML returned invalid result`); return null; } if (!(0, parsing_1.matchesPrecommitConfigHeuristic)(parsedContent)) { logger_1.logger.debug({ packageFile }, `File does not look like a pre-commit config file`); return null; } try { const deps = findDependencies(parsedContent); if (deps.length) { logger_1.logger.trace({ deps }, 'Found dependencies in pre-commit config'); return { deps }; } } catch (err) /* istanbul ignore next */ { logger_1.logger.debug({ packageFile, err }, 'Error scanning parsed pre-commit config'); } return null; } //# sourceMappingURL=extract.js.map