renovate
Version:
Automated dependency updates. Flexible so you don't need to be.
181 lines • 7.39 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.EXTRACT_CACHE_REVISION = void 0;
exports.isCacheExtractValid = isCacheExtractValid;
exports.extract = extract;
exports.lookup = lookup;
exports.update = update;
const tslib_1 = require("tslib");
const is_1 = tslib_1.__importDefault(require("@sindresorhus/is"));
const logger_1 = require("../../../logger");
const manager_1 = require("../../../modules/manager");
const scm_1 = require("../../../modules/platform/scm");
const memCache = tslib_1.__importStar(require("../../../util/cache/memory"));
const repository_1 = require("../../../util/cache/repository");
const check_token_1 = require("../../../util/check-token");
const fingerprint_1 = require("../../../util/fingerprint");
const extract_1 = require("../extract");
const extract_fingerprint_config_1 = require("../extract/extract-fingerprint-config");
const branchify_1 = require("../updates/branchify");
const fetch_1 = require("./fetch");
const libyear_1 = require("./libyear");
const sort_1 = require("./sort");
const vulnerabilities_1 = require("./vulnerabilities");
const write_1 = require("./write");
// Increment this if needing to cache bust ALL extract caches
exports.EXTRACT_CACHE_REVISION = 1;
// istanbul ignore next
function extractStats(packageFiles) {
if (!packageFiles) {
return null;
}
const stats = {
managers: {},
total: {
fileCount: 0,
depCount: 0,
},
};
for (const [manager, managerPackageFiles] of Object.entries(packageFiles)) {
const fileCount = managerPackageFiles.length;
let depCount = 0;
for (const file of managerPackageFiles) {
depCount += file.deps.length;
}
stats.managers[manager] = {
fileCount,
depCount,
};
stats.total.fileCount += fileCount;
stats.total.depCount += depCount;
}
return stats;
}
function isCacheExtractValid(baseBranchSha, configHash, cachedExtract) {
if (!cachedExtract) {
return false;
}
if (!cachedExtract.revision) {
logger_1.logger.debug('Cached extract is missing revision, so cannot be used');
return false;
}
if (cachedExtract.revision !== exports.EXTRACT_CACHE_REVISION) {
logger_1.logger.debug(`Extract cache revision has changed (old=${cachedExtract.revision}, new=${exports.EXTRACT_CACHE_REVISION})`);
return false;
}
if (!(cachedExtract.sha && cachedExtract.configHash)) {
return false;
}
if (cachedExtract.sha !== baseBranchSha) {
logger_1.logger.debug(`Cached extract result cannot be used due to base branch SHA change (old=${cachedExtract.sha}, new=${baseBranchSha})`);
return false;
}
if (cachedExtract.configHash !== configHash) {
logger_1.logger.debug('Cached extract result cannot be used due to config change');
return false;
}
if (!cachedExtract.extractionFingerprints) {
logger_1.logger.debug('Cached extract is missing extractionFingerprints, so cannot be used');
return false;
}
const changedManagers = new Set();
for (const [manager, fingerprint] of Object.entries(cachedExtract.extractionFingerprints)) {
if (fingerprint !== manager_1.hashMap.get(manager)) {
changedManagers.add(manager);
}
}
if (changedManagers.size > 0) {
logger_1.logger.debug({ changedManagers: [...changedManagers] }, 'Manager fingerprint(s) have changed, extract cache cannot be reused');
return false;
}
logger_1.logger.debug(`Cached extract for sha=${baseBranchSha} is valid and can be used`);
return true;
}
async function extract(config, overwriteCache = true) {
logger_1.logger.debug('extract()');
const { baseBranch } = config;
const baseBranchSha = await scm_1.scm.getBranchCommit(baseBranch);
let packageFiles;
const cache = (0, repository_1.getCache)();
cache.scan ??= {};
const cachedExtract = cache.scan[baseBranch];
const configHash = (0, fingerprint_1.fingerprint)((0, extract_fingerprint_config_1.generateFingerprintConfig)(config));
// istanbul ignore if
if (overwriteCache &&
isCacheExtractValid(baseBranchSha, configHash, cachedExtract)) {
packageFiles = cachedExtract.packageFiles;
try {
for (const files of Object.values(packageFiles)) {
for (const file of files) {
for (const dep of file.deps) {
delete dep.updates;
}
}
}
logger_1.logger.debug('Deleted cached dep updates');
}
catch (err) {
logger_1.logger.info({ err }, 'Error deleting cached dep updates');
}
}
else {
await scm_1.scm.checkoutBranch(baseBranch);
const extractResult = (await (0, extract_1.extractAllDependencies)(config)) || {};
packageFiles = extractResult.packageFiles;
const { extractionFingerprints } = extractResult;
if (overwriteCache) {
// TODO: fix types (#22198)
cache.scan[baseBranch] = {
revision: exports.EXTRACT_CACHE_REVISION,
sha: baseBranchSha,
configHash,
extractionFingerprints,
packageFiles,
};
}
// Clean up cached branch extracts
const baseBranches = is_1.default.nonEmptyArray(config.baseBranchPatterns)
? config.baseBranchPatterns
: [baseBranch];
Object.keys(cache.scan).forEach((branchName) => {
if (!baseBranches.includes(branchName)) {
delete cache.scan[branchName];
}
});
}
const stats = extractStats(packageFiles);
logger_1.logger.info({ baseBranch: config.baseBranch, stats }, `Dependency extraction complete`);
logger_1.logger.trace({ config: packageFiles }, 'packageFiles');
(0, check_token_1.checkGithubToken)(packageFiles);
return packageFiles;
}
async function fetchVulnerabilities(config, packageFiles) {
if (config.osvVulnerabilityAlerts) {
logger_1.logger.debug('fetchVulnerabilities() - osvVulnerabilityAlerts=true');
try {
const vulnerabilities = await vulnerabilities_1.Vulnerabilities.create();
await vulnerabilities.appendVulnerabilityPackageRules(config, packageFiles);
}
catch (err) {
logger_1.logger.warn({ err }, 'Unable to read vulnerability information');
}
}
}
async function lookup(config, packageFiles) {
await fetchVulnerabilities(config, packageFiles);
await (0, fetch_1.fetchUpdates)(config, packageFiles);
memCache.cleanDatasourceKeys();
(0, libyear_1.calculateLibYears)(config, packageFiles);
const { branches, branchList } = await (0, branchify_1.branchifyUpgrades)(config, packageFiles);
logger_1.logger.debug({ baseBranch: config.baseBranch, config: packageFiles }, 'packageFiles with updates');
(0, sort_1.sortBranches)(branches);
return { branches, branchList, packageFiles };
}
async function update(config, branches) {
let res;
if (config.repoIsOnboarded) {
res = await (0, write_1.writeUpdates)(config, branches);
}
return res;
}
//# sourceMappingURL=extract-update.js.map