UNPKG

renovate

Version:

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

297 lines • 15 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.confirmIfDepUpdated = confirmIfDepUpdated; exports.checkBranchDepsMatchBaseDeps = checkBranchDepsMatchBaseDeps; exports.doAutoReplace = doAutoReplace; const tslib_1 = require("tslib"); // TODO #22198 const is_1 = tslib_1.__importDefault(require("@sindresorhus/is")); const error_messages_1 = require("../../../../constants/error-messages"); const logger_1 = require("../../../../logger"); const manager_1 = require("../../../../modules/manager"); const fs_1 = require("../../../../util/fs"); const regex_1 = require("../../../../util/regex"); const string_1 = require("../../../../util/string"); const template_1 = require("../../../../util/template"); async function confirmIfDepUpdated(upgrade, newContent) { const { manager, packageFile, depIndex } = upgrade; let newUpgrade; try { const newExtract = await (0, manager_1.extractPackageFile)(manager, newContent, packageFile, upgrade); // istanbul ignore if if (!newExtract) { // TODO: fix types (#22198) logger_1.logger.debug(`Could not extract ${packageFile} (manager=${manager}) after autoreplace. Did the autoreplace make the file unparseable?`); logger_1.logger.trace({ packageFile, content: newContent }, 'packageFile content after autoreplace'); return false; } // istanbul ignore if if (!newExtract.deps?.length) { logger_1.logger.debug(`Extracted ${packageFile} after autoreplace has no deps array. Did the autoreplace make the file unparseable?`); return false; } // istanbul ignore if if (is_1.default.number(depIndex) && depIndex >= newExtract.deps.length) { logger_1.logger.debug(`Extracted ${packageFile} after autoreplace has fewer deps than expected.`); return false; } newUpgrade = newExtract.deps[depIndex]; } catch (err) /* istanbul ignore next */ { logger_1.logger.debug({ manager, packageFile, err }, 'Failed to parse newContent'); } if (!newUpgrade) { logger_1.logger.debug(`No newUpgrade in ${packageFile}`); return false; } if (upgrade.depName !== newUpgrade.depName && upgrade.newName !== newUpgrade.depName) { logger_1.logger.debug({ manager, packageFile, currentDepName: upgrade.depName, newDepName: newUpgrade.depName, }, 'depName mismatch'); return false; } if (upgrade.newName && upgrade.newName !== newUpgrade.depName) { logger_1.logger.debug({ manager, packageFile, currentDepName: upgrade.depName, newDepName: newUpgrade.depName, }, 'depName is not updated'); return false; } if (upgrade.newValue && upgrade.newValue !== newUpgrade.currentValue) { logger_1.logger.debug({ depName: upgrade.depName, manager, packageFile, expectedValue: upgrade.newValue, foundValue: newUpgrade.currentValue, }, 'Value is not updated'); return false; } if (upgrade.newDigest && (upgrade.isPinDigest === true || upgrade.currentDigest) && upgrade.newDigest !== newUpgrade.currentDigest) { logger_1.logger.debug({ depName: upgrade.depName, manager, packageFile, expectedValue: upgrade.newDigest, foundValue: newUpgrade.currentDigest, }, 'Digest is not updated'); return false; } return true; } function getDepsSignature(deps) { // TODO: types (#22198) return deps .map((dep) => `${(dep.depName ?? dep.packageName)}${(dep.packageName ?? dep.depName)}`) .join(','); } function firstIndexOf(existingContent, depName, currentValue, position = 0) { const depIndex = existingContent.indexOf(depName, position); const valIndex = existingContent.indexOf(currentValue, position); const index = depIndex < valIndex ? depIndex : valIndex; if (index < 0) { return position === 0 ? -1 : existingContent.length; } return index; } async function checkBranchDepsMatchBaseDeps(upgrade, branchContent) { const { baseDeps, manager, packageFile } = upgrade; try { const res = await (0, manager_1.extractPackageFile)(manager, branchContent, packageFile, upgrade); const branchDeps = res.deps; return getDepsSignature(baseDeps) === getDepsSignature(branchDeps); } catch /* istanbul ignore next */ { logger_1.logger.info({ manager, packageFile }, 'Failed to parse branchContent - rebasing'); return false; } } async function checkExistingBranch(upgrade, existingContent) { const { packageFile, depName } = upgrade; if (!(await checkBranchDepsMatchBaseDeps(upgrade, existingContent))) { logger_1.logger.debug({ packageFile, depName }, 'Rebasing branch after deps list has changed'); return null; } if (!(await confirmIfDepUpdated(upgrade, existingContent))) { logger_1.logger.debug({ packageFile, depName }, 'Rebasing after outdated branch dep found'); return null; } // TODO: fix types (#22198) logger_1.logger.debug(`Branch dep ${depName} in ${packageFile} is already updated`); return existingContent; } async function doAutoReplace(upgrade, existingContent, reuseExistingBranch, firstUpdate = true) { const { packageFile, depName, depNameTemplate, newName, currentValue, currentValueTemplate, newValue, currentDigest, currentDigestShort, newDigest, autoReplaceGlobalMatch, autoReplaceStringTemplate, } = upgrade; /* If replacement support for more managers is added, please also update the list in docs/usage/configuration-options.md at replacementName and replacementVersion */ if (reuseExistingBranch) { return await checkExistingBranch(upgrade, existingContent); } const replaceWithoutReplaceString = is_1.default.string(newName) && newName !== depName && (is_1.default.undefined(upgrade.replaceString) || !upgrade.replaceString?.includes(depName)); const replaceString = upgrade.replaceString ?? currentValue ?? currentDigest; logger_1.logger.trace({ depName, replaceString }, 'autoReplace replaceString'); let searchIndex; if (replaceWithoutReplaceString) { searchIndex = firstIndexOf(existingContent, depName, currentValue); } else { searchIndex = existingContent.indexOf(replaceString); } if (searchIndex === -1) { logger_1.logger.info({ packageFile, depName, existingContent, replaceString }, 'Cannot find replaceString in current file content. Was it already updated?'); return existingContent; } try { let newString; if (autoReplaceStringTemplate && !newName) { newString = (0, template_1.compile)(autoReplaceStringTemplate, upgrade, false); } else { newString = replaceString; const autoReplaceRegExpFlag = autoReplaceGlobalMatch ? 'g' : ''; if (currentValue && newValue && currentValue !== newValue) { if (!newString.includes(currentValue)) { logger_1.logger.debug({ stringToReplace: newString, currentValue, currentValueTemplate }, 'currentValue not found in string to replace'); } newString = newString.replace((0, regex_1.regEx)((0, regex_1.escapeRegExp)(currentValue), autoReplaceRegExpFlag), newValue); } if (depName && newName && depName !== newName) { if (!newString.includes(depName)) { logger_1.logger.debug({ stringToReplace: newString, depName, depNameTemplate }, 'depName not found in string to replace'); } newString = newString.replace((0, regex_1.regEx)((0, regex_1.escapeRegExp)(depName), autoReplaceRegExpFlag), newName); } if (currentDigest && newDigest && currentDigest !== newDigest) { if (!newString.includes(currentDigest)) { logger_1.logger.debug({ stringToReplace: newString, currentDigest }, 'currentDigest not found in string to replace'); } newString = newString.replace((0, regex_1.regEx)((0, regex_1.escapeRegExp)(currentDigest), autoReplaceRegExpFlag), newDigest); } else if (currentDigestShort && newDigest && currentDigestShort !== newDigest) { if (!newString.includes(currentDigestShort)) { logger_1.logger.debug({ stringToReplace: newString, currentDigestShort }, 'currentDigestShort not found in string to replace'); } newString = newString.replace((0, regex_1.regEx)((0, regex_1.escapeRegExp)(currentDigestShort), autoReplaceRegExpFlag), newDigest); } } if (!firstUpdate && (await confirmIfDepUpdated(upgrade, existingContent))) { logger_1.logger.debug({ packageFile, depName }, 'Package file is already updated - no work to do'); return existingContent; } logger_1.logger.debug({ packageFile, depName }, `Starting search at index ${searchIndex}`); let newContent = existingContent; let nameReplaced = !newName; let valueReplaced = !newValue; let digestReplaced = !newDigest; let startIndex = searchIndex; // Iterate through the rest of the file for (; searchIndex < newContent.length; searchIndex += 1) { // First check if we have a hit for the old version if (replaceWithoutReplaceString) { // look for depName and currentValue if (newName && (0, string_1.matchAt)(newContent, searchIndex, depName)) { logger_1.logger.debug({ packageFile, depName }, `Found depName at index ${searchIndex}`); if (nameReplaced) { startIndex = firstIndexOf(existingContent, depName, currentValue, startIndex + 1); searchIndex = startIndex - 1; await (0, fs_1.writeLocalFile)(upgrade.packageFile, existingContent); newContent = existingContent; nameReplaced = !newName; valueReplaced = !newValue; digestReplaced = !newDigest; continue; } // replace with newName newContent = (0, string_1.replaceAt)(newContent, searchIndex, depName, newName); await (0, fs_1.writeLocalFile)(upgrade.packageFile, newContent); nameReplaced = true; searchIndex += newName.length - 1; } else if (newValue && (0, string_1.matchAt)(newContent, searchIndex, currentValue)) { logger_1.logger.debug({ packageFile, currentValue }, `Found currentValue at index ${searchIndex}`); if (valueReplaced) { startIndex = firstIndexOf(existingContent, depName, currentValue, startIndex + 1); searchIndex = startIndex - 1; await (0, fs_1.writeLocalFile)(upgrade.packageFile, existingContent); newContent = existingContent; nameReplaced = !newName; valueReplaced = !newValue; digestReplaced = !newDigest; continue; } // Now test if the result matches newContent = (0, string_1.replaceAt)(newContent, searchIndex, currentValue, newValue); await (0, fs_1.writeLocalFile)(upgrade.packageFile, newContent); valueReplaced = true; searchIndex += newValue.length - 1; } else if (newDigest && (0, string_1.matchAt)(newContent, searchIndex, currentDigest)) { logger_1.logger.debug({ packageFile, currentDigest }, `Found currentDigest at index ${searchIndex}`); if (digestReplaced) { startIndex = firstIndexOf(existingContent, depName, currentValue, startIndex + 1); searchIndex = startIndex - 1; await (0, fs_1.writeLocalFile)(upgrade.packageFile, existingContent); newContent = existingContent; nameReplaced = !newName; valueReplaced = !newValue; digestReplaced = !newDigest; continue; } // Now test if the result matches newContent = (0, string_1.replaceAt)(newContent, searchIndex, currentDigest, newDigest); await (0, fs_1.writeLocalFile)(upgrade.packageFile, newContent); digestReplaced = true; searchIndex += newDigest.length - 1; } if (nameReplaced && valueReplaced && digestReplaced) { if (await confirmIfDepUpdated(upgrade, newContent)) { return newContent; } startIndex = firstIndexOf(existingContent, depName, currentValue, startIndex + 1); searchIndex = startIndex - 1; await (0, fs_1.writeLocalFile)(upgrade.packageFile, existingContent); newContent = existingContent; nameReplaced = !newName; valueReplaced = !newValue; digestReplaced = !newDigest; } } else if ((0, string_1.matchAt)(newContent, searchIndex, replaceString)) { logger_1.logger.debug({ packageFile, depName }, `Found match at index ${searchIndex}`); // Now test if the result matches newContent = (0, string_1.replaceAt)(newContent, searchIndex, replaceString, newString); await (0, fs_1.writeLocalFile)(upgrade.packageFile, newContent); if (await confirmIfDepUpdated(upgrade, newContent)) { return newContent; } await (0, fs_1.writeLocalFile)(upgrade.packageFile, existingContent); newContent = existingContent; } } } catch (err) /* istanbul ignore next */ { logger_1.logger.debug({ packageFile, depName, err }, 'doAutoReplace error'); } // istanbul ignore next throw new Error(error_messages_1.WORKER_FILE_UPDATE_FAILED); } //# sourceMappingURL=auto-replace.js.map