renovate
Version:
Automated dependency updates. Flexible so you don't need to be.
153 lines • 7.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.updateAtPosition = updateAtPosition;
exports.updateDependency = updateDependency;
exports.bumpPackageVersion = bumpPackageVersion;
const tslib_1 = require("tslib");
const is_1 = tslib_1.__importDefault(require("@sindresorhus/is"));
const semver_1 = tslib_1.__importDefault(require("semver"));
const xmldoc_1 = require("xmldoc");
const logger_1 = require("../../../logger");
const string_1 = require("../../../util/string");
function updateAtPosition(fileContent, upgrade, endingAnchor) {
const { depName, newName, currentValue, newValue, fileReplacePosition } = upgrade;
let leftPart = fileContent.slice(0, fileReplacePosition);
const rightPart = fileContent.slice(fileReplacePosition);
const versionClosePosition = rightPart.indexOf(endingAnchor);
let restPart = rightPart.slice(versionClosePosition);
const versionPart = rightPart.slice(0, versionClosePosition);
const version = versionPart.trim();
if (newName) {
const blockStart = Math.max(leftPart.lastIndexOf('<parent'), leftPart.lastIndexOf('<dependency'), leftPart.lastIndexOf('<plugin'), leftPart.lastIndexOf('<extension'));
let leftBlock = leftPart.slice(blockStart);
const blockEnd = Math.min(restPart.indexOf('</parent'), restPart.indexOf('</dependency'), restPart.indexOf('</plugin'), restPart.indexOf('</extension'));
let rightBlock = restPart.slice(0, blockEnd);
const [groupId, artifactId] = depName.split(':', 2);
const [newGroupId, newArtifactId] = newName.split(':', 2);
if (leftBlock.indexOf('<groupId') > 0) {
leftBlock = updateValue(leftBlock, 'groupId', groupId, newGroupId);
}
else {
rightBlock = updateValue(rightBlock, 'groupId', groupId, newGroupId);
}
if (leftBlock.indexOf('<artifactId') > 0) {
leftBlock = updateValue(leftBlock, 'artifactId', artifactId, newArtifactId);
}
else {
rightBlock = updateValue(rightBlock, 'artifactId', artifactId, newArtifactId);
}
leftPart = leftPart.slice(0, blockStart) + leftBlock;
restPart = rightBlock + restPart.slice(blockEnd);
}
else if (version === newValue) {
return fileContent;
}
if (version === currentValue || upgrade.sharedVariableName) {
// TODO: validate newValue (#22198)
const replacedPart = versionPart.replace(version, newValue);
return leftPart + replacedPart + restPart;
}
else if (upgrade.datasource === 'docker' ||
upgrade.datasource === 'buildpacks-registry') {
// In contrast to maven dependencies, cloud native buildpacks are not contained in specific version tags.
// Instead they are contained in the value of the buildpack tag and we have to update it differently.
let replacedPart = version;
if (currentValue) {
replacedPart = version.replace(currentValue, newValue);
}
if (upgrade.currentDigest && upgrade.newDigest) {
replacedPart = replacedPart.replace(upgrade.currentDigest, upgrade.newDigest);
}
if (replacedPart !== version) {
return leftPart + replacedPart + restPart;
}
}
logger_1.logger.debug({ depName, version, currentValue, newValue }, 'Unknown value');
return null;
}
function updateDependency({ fileContent, upgrade, }) {
const offset = fileContent.indexOf('<');
const spaces = fileContent.slice(0, offset);
const restContent = fileContent.slice(offset);
const updatedContent = updateAtPosition(restContent, upgrade, '</');
if (!updatedContent) {
return null;
}
if (updatedContent === restContent) {
return fileContent;
}
return `${spaces}${updatedContent}`;
}
function bumpPackageVersion(content, currentValue, bumpVersion) {
logger_1.logger.debug({ bumpVersion, currentValue }, 'Checking if we should bump pom.xml version');
let bumpedContent = content;
if (!semver_1.default.valid(currentValue)) {
logger_1.logger.warn({ currentValue }, 'Unable to bump pom.xml version, not a valid semver');
return { bumpedContent };
}
try {
const project = new xmldoc_1.XmlDocument(content);
const versionNode = project.childNamed('version');
const startTagPosition = versionNode.startTagPosition;
const versionPosition = content.indexOf(versionNode.val, startTagPosition);
let newPomVersion = null;
const currentPrereleaseValue = semver_1.default.prerelease(currentValue);
if (isSnapshot(currentPrereleaseValue)) {
// It is already a SNAPSHOT version.
// Therefore the same qualifier (prerelease) will be used as before.
let releaseType = bumpVersion;
if (!bumpVersion.startsWith('pre')) {
releaseType = `pre${bumpVersion}`;
}
newPomVersion = semver_1.default.inc(currentValue, releaseType, currentPrereleaseValue.join('.'), false);
}
else if (currentPrereleaseValue) {
// Some qualifier which is not a SNAPSHOT is present.
// The expected behaviour in this case is unclear and the standard increase will be used.
newPomVersion = semver_1.default.inc(currentValue, bumpVersion);
}
else {
// A release version without any qualifier is present.
// Therefore the SNAPSHOT qualifier will be added if a prerelease is requested.
// This will do a normal increment, ignoring SNAPSHOT, if a non-prerelease bumpVersion is configured
newPomVersion = semver_1.default.inc(currentValue, bumpVersion, 'SNAPSHOT', false);
}
if (!newPomVersion) {
throw new Error('semver inc failed');
}
logger_1.logger.debug({ newPomVersion });
bumpedContent = (0, string_1.replaceAt)(content, versionPosition, currentValue, newPomVersion);
if (bumpedContent === content) {
logger_1.logger.debug('Version was already bumped');
}
else {
logger_1.logger.debug('pom.xml version bumped');
}
}
catch {
logger_1.logger.warn({
content,
currentValue,
bumpVersion,
}, 'Failed to bumpVersion');
}
return { bumpedContent };
}
function isSnapshot(prerelease) {
const lastPart = prerelease?.at(-1);
return is_1.default.string(lastPart) && lastPart.endsWith('SNAPSHOT');
}
function updateValue(content, nodeName, oldValue, newValue) {
const elementStart = content.indexOf('<' + nodeName);
const start = content.indexOf('>', elementStart) + 1;
const end = content.indexOf('</' + nodeName, start);
const elementContent = content.slice(start, end);
if (elementContent.trim() === oldValue) {
return (content.slice(0, start) +
elementContent.replace(oldValue, newValue) +
content.slice(end));
}
logger_1.logger.debug({ content, nodeName, oldValue, newValue }, 'Unknown value');
return content;
}
//# sourceMappingURL=update.js.map