UNPKG

renovate

Version:

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

236 lines • 9.93 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.replaceArgs = replaceArgs; exports.getPreset = getPreset; exports.resolveConfigPresets = resolveConfigPresets; const tslib_1 = require("tslib"); const is_1 = tslib_1.__importDefault(require("@sindresorhus/is")); const error_messages_1 = require("../../constants/error-messages"); const logger_1 = require("../../logger"); const external_host_error_1 = require("../../types/errors/external-host-error"); const memCache = tslib_1.__importStar(require("../../util/cache/memory")); const packageCache = tslib_1.__importStar(require("../../util/cache/package")); const clone_1 = require("../../util/clone"); const regex_1 = require("../../util/regex"); const template = tslib_1.__importStar(require("../../util/template")); const global_1 = require("../global"); const massage = tslib_1.__importStar(require("../massage")); const migration = tslib_1.__importStar(require("../migration")); const utils_1 = require("../utils"); const common_1 = require("./common"); const forgejo = tslib_1.__importStar(require("./forgejo")); const gitea = tslib_1.__importStar(require("./gitea")); const github = tslib_1.__importStar(require("./github")); const gitlab = tslib_1.__importStar(require("./gitlab")); const http = tslib_1.__importStar(require("./http")); const internal = tslib_1.__importStar(require("./internal")); const local = tslib_1.__importStar(require("./local")); const npm = tslib_1.__importStar(require("./npm")); const parse_1 = require("./parse"); const util_1 = require("./util"); const presetSources = { forgejo, gitea, github, gitlab, http, internal, local, npm, }; const presetCacheNamespace = 'preset'; function replaceArgs(obj, argMapping) { if (is_1.default.string(obj)) { let returnStr = obj; for (const [arg, argVal] of Object.entries(argMapping)) { const re = (0, regex_1.regEx)(`{{${arg}}}`, 'g', false); returnStr = returnStr.replace(re, argVal); } return returnStr; } if (is_1.default.array(obj)) { const returnArray = []; for (const item of obj) { returnArray.push(replaceArgs(item, argMapping)); } return returnArray; } if (is_1.default.object(obj)) { const returnObj = {}; for (const [key, val] of Object.entries(obj)) { returnObj[key] = replaceArgs(val, argMapping); } return returnObj; } return obj; } async function getPreset(preset, baseConfig) { logger_1.logger.trace(`getPreset(${preset})`); // Check if the preset has been removed or replaced const newPreset = common_1.removedPresets[preset]; if (newPreset) { return getPreset(newPreset, baseConfig); } if (newPreset === null) { return {}; } const { presetSource, repo, presetPath, presetName, tag, params, rawParams } = (0, parse_1.parsePreset)(preset); const cacheKey = `preset:${preset}`; const presetCachePersistence = global_1.GlobalConfig.get('presetCachePersistence', false); let presetConfig; if (presetCachePersistence) { presetConfig = await packageCache.get(presetCacheNamespace, cacheKey); } else { presetConfig = memCache.get(cacheKey); } if (is_1.default.nullOrUndefined(presetConfig)) { presetConfig = await presetSources[presetSource].getPreset({ repo, presetPath, presetName, tag, }); if (presetCachePersistence) { await packageCache.set(presetCacheNamespace, cacheKey, presetConfig, 15); } else { memCache.set(cacheKey, presetConfig); } } if (!presetConfig) { throw new Error(util_1.PRESET_DEP_NOT_FOUND); } logger_1.logger.trace({ presetConfig }, `Found preset ${preset}`); if (params) { const argMapping = {}; for (const [index, value] of params.entries()) { argMapping[`arg${index}`] = value; } if (rawParams) { argMapping.args = rawParams; } presetConfig = replaceArgs(presetConfig, argMapping); } logger_1.logger.trace({ presetConfig }, `Applied params to preset ${preset}`); const presetKeys = Object.keys(presetConfig); if (presetKeys.length === 2 && presetKeys.includes('description') && presetKeys.includes('extends')) { // preset is just a collection of other presets delete presetConfig.description; } const packageListKeys = ['description', 'matchPackageNames']; if (presetKeys.every((key) => packageListKeys.includes(key))) { delete presetConfig.description; } const { migratedConfig } = migration.migrateConfig(presetConfig); return massage.massageConfig(migratedConfig); } async function resolveConfigPresets(inputConfig, baseConfig, _ignorePresets, existingPresets = []) { let ignorePresets = (0, clone_1.clone)(_ignorePresets); if (!ignorePresets || ignorePresets.length === 0) { ignorePresets = inputConfig.ignorePresets ?? []; } logger_1.logger.trace({ config: inputConfig, existingPresets }, 'resolveConfigPresets'); let config = {}; // First, merge all the preset configs from left to right if (inputConfig.extends?.length) { // Compile templates inputConfig.extends = inputConfig.extends.map((tmpl) => template.compile(tmpl, {})); for (const preset of inputConfig.extends) { if (shouldResolvePreset(preset, existingPresets, ignorePresets)) { logger_1.logger.trace(`Resolving preset "${preset}"`); const fetchedPreset = await fetchPreset(preset, baseConfig, inputConfig, existingPresets); const presetConfig = await resolveConfigPresets(fetchedPreset, baseConfig ?? inputConfig, ignorePresets, existingPresets.concat([preset])); if (inputConfig?.ignoreDeps?.length === 0) { delete presetConfig.description; } config = (0, utils_1.mergeChildConfig)(config, presetConfig); } } } logger_1.logger.trace({ config }, `Post-preset resolve config`); // Now assign "regular" config on top config = (0, utils_1.mergeChildConfig)(config, inputConfig); delete config.extends; delete config.ignorePresets; logger_1.logger.trace({ config }, `Post-merge resolve config`); for (const [key, val] of Object.entries(config)) { const ignoredKeys = ['content', 'onboardingConfig']; if (is_1.default.array(val)) { // Resolve nested objects inside arrays config[key] = []; for (const element of val) { if (is_1.default.object(element)) { config[key].push(await resolveConfigPresets(element, baseConfig, ignorePresets, existingPresets)); } else { config[key].push(element); } } } else if (is_1.default.object(val) && !ignoredKeys.includes(key)) { // Resolve nested objects logger_1.logger.trace(`Resolving object "${key}"`); config[key] = await resolveConfigPresets(val, baseConfig, ignorePresets, existingPresets); } } logger_1.logger.trace({ config: inputConfig }, 'Input config'); logger_1.logger.trace({ config }, 'Resolved config'); return config; } async function fetchPreset(preset, baseConfig, inputConfig, existingPresets) { try { return await getPreset(preset, baseConfig ?? inputConfig); } catch (err) { logger_1.logger.debug({ preset, err }, 'Preset fetch error'); if (err instanceof external_host_error_1.ExternalHostError) { throw err; } if (err.message === error_messages_1.PLATFORM_RATE_LIMIT_EXCEEDED) { throw err; } const error = new Error(error_messages_1.CONFIG_VALIDATION); if (err.message === util_1.PRESET_DEP_NOT_FOUND) { error.validationError = `Cannot find preset's package (${preset})`; } else if (err.message === util_1.PRESET_RENOVATE_CONFIG_NOT_FOUND) { error.validationError = `Preset package is missing a renovate-config entry (${preset})`; } else if (err.message === util_1.PRESET_NOT_FOUND) { error.validationError = `Preset name not found within published preset config (${preset})`; } else if (err.message === util_1.PRESET_INVALID) { error.validationError = `Preset is invalid (${preset})`; } else if (err.message === util_1.PRESET_PROHIBITED_SUBPRESET) { error.validationError = `Sub-presets cannot be combined with a custom path (${preset})`; } else if (err.message === util_1.PRESET_INVALID_JSON) { error.validationError = `Preset is invalid JSON (${preset})`; } else { error.validationError = `Preset caused unexpected error (${preset})`; } if (existingPresets.length) { error.validationError += '. Note: this is a *nested* preset so please contact the preset author if you are unable to fix it yourself.'; } logger_1.logger.info({ validationError: error.validationError }, 'Throwing preset error'); throw error; } } function shouldResolvePreset(preset, existingPresets, ignorePresets) { if (existingPresets.includes(preset)) { logger_1.logger.debug(`Already seen preset ${preset} in [${existingPresets.join(', ')}]`); return false; } if (ignorePresets.includes(preset)) { logger_1.logger.debug(`Ignoring preset ${preset} in [${existingPresets.join(', ')}]`); return false; } return true; } //# sourceMappingURL=index.js.map