UNPKG

renovate

Version:

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

200 lines • 8.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.api = exports.supportsRanges = exports.urls = exports.displayName = exports.id = void 0; const tslib_1 = require("tslib"); const is_1 = tslib_1.__importDefault(require("@sindresorhus/is")); const regex_1 = require("../../../util/regex"); const generic_1 = require("../generic"); exports.id = 'rpm'; exports.displayName = 'RPM version'; exports.urls = [ 'https://docs.fedoraproject.org/en-US/packaging-guidelines/Versioning/', 'https://fedoraproject.org/wiki/Package_Versioning_Examples', 'https://fedoraproject.org/wiki/User:Tibbs/TildeCaretVersioning', ]; exports.supportsRanges = false; const alphaNumPattern = (0, regex_1.regEx)(/([a-zA-Z]+)|(\d+)|(~)/g); const epochPattern = (0, regex_1.regEx)(/^\d+$/); class RpmVersioningApi extends generic_1.GenericVersioningApi { /** * https://github.com/rpm-software-management/rpm/blob/e3c11a790367016aed7ea48cfcc78751a71ce862/rpmio/rpmvercmp.c#L16 */ _parse(version) { let remainingVersion = version; let epoch = 0; const epochIndex = remainingVersion.indexOf(':'); if (epochIndex !== -1) { const epochStr = remainingVersion.slice(0, epochIndex); if (epochPattern.test(epochStr)) { epoch = parseInt(epochStr); } else { return null; } remainingVersion = remainingVersion.slice(epochIndex + 1); } let upstreamVersion; let rpmRelease = ''; let rpmPreRelease = ''; let snapshot = ''; const releaseIndex = remainingVersion.indexOf('-'); const prereleaseIndex = remainingVersion.indexOf('~'); // Note: There can be a snapshot if there is no prerelease. Snapshot always beat no snapshot, // so if there is 3.12.0-1 vs 3.12.0-1^20231110, the snapshot wins. // The logic below only creates snapshot IF there is a prerleease version. This logic is NOT // correct, but the result is still correct due to the caret being ignored in release, and // release continue comparing // // Note: If there IS a tilde preceding the caret, then snapshot DOES NOT win // Example: 3.12.0-1~^20231001 LOSES to 3.12.0-1 and // 3.12.0-1~^20231001 LOSES to 3.12.0-1^20231001 const snapshotIndex = remainingVersion.indexOf('^'); if (releaseIndex >= 0) { upstreamVersion = remainingVersion.slice(0, releaseIndex); // Do NOT splice out prerelease, we need to distinguish if the flag is set or not, regardless if there is a version. // The tilde will get filtered out during regex if (prereleaseIndex >= 0) { rpmRelease = remainingVersion.slice(releaseIndex, prereleaseIndex); if (snapshotIndex >= 0) { rpmPreRelease = remainingVersion.slice(prereleaseIndex, snapshotIndex); snapshot = remainingVersion.slice(snapshotIndex + 1); } else { rpmPreRelease = remainingVersion.slice(prereleaseIndex); } } else { rpmRelease = remainingVersion.slice(releaseIndex + 1); } } else { upstreamVersion = remainingVersion; } const release = [...remainingVersion.matchAll((0, regex_1.regEx)(/\d+/g))].map((m) => parseInt(m[0])); return { epoch, upstreamVersion, rpmRelease, release, rpmPreRelease, snapshot, }; } _compare_string(s1, s2) { if (s1 === s2) { return 0; } const minLength = Math.min(s1.length, s2.length); for (let i = 0; i < minLength; i++) { const c1 = s1[i]; const c2 = s2[i]; if (c1 === c2) { continue; } if (c1 > c2) { return 1; } else if (c1 < c2) { return -1; } } // Okay, they've been the exact same up until now, so return the longer one return s1.length > s2.length ? 1 : -1; } /** * Taken from https://github.com/rpm-software-management/rpm/blob/master/rpmio/rpmvercmp.c */ _compare_glob(v1, v2) { if (v1 === v2) { return 0; } const matchesv1 = v1.match(alphaNumPattern) ?? []; const matchesv2 = v2.match(alphaNumPattern) ?? []; const matches = Math.min(matchesv1.length, matchesv2.length); for (let i = 0; i < matches; i++) { const matchv1 = matchesv1[i]; const matchv2 = matchesv2[i]; // compare tildes if (matchv1?.startsWith('~') || matchv2?.startsWith('~')) { if (!matchv1?.startsWith('~')) { return 1; } if (!matchv2?.startsWith('~')) { return -1; } } if (is_1.default.numericString(matchv1?.[0])) { // numbers are greater than letters if (!is_1.default.numericString(matchv2?.[0])) { return 1; } //We clearly have a number here, so return which is greater const result = matchv1.localeCompare(matchv2, undefined, { numeric: true, }); if (result === 0) { continue; } return Math.sign(result); } else if (is_1.default.numericString(matchv2?.[0])) { return -1; } // We have two string globs, compare them const compared_value = this._compare_string(matchv1, matchv2); if (compared_value !== 0) { return compared_value; } } // segments were all the same, but separators were different if (matchesv1.length === matchesv2.length) { return 0; } // If there is a tilde in a segment past the minimum number of segments, find it if (matchesv1.length > matches && matchesv1[matches].startsWith('~')) { return -1; } if (matchesv2.length > matches && matchesv2[matches].startsWith('~')) { return 1; } // whichever has the most segments wins return matchesv1.length > matchesv2.length ? 1 : -1; } _compare(version, other) { const parsed1 = this._parse(version); const parsed2 = this._parse(other); if (!(parsed1 && parsed2)) { return 1; } // Greater epoch wins if (parsed1.epoch !== parsed2.epoch) { return Math.sign(parsed1.epoch - parsed2.epoch); } // Greater upstream version wins const upstreamVersionDifference = this._compare_glob(parsed1.upstreamVersion, parsed2.upstreamVersion); if (upstreamVersionDifference !== 0) { return upstreamVersionDifference; } // Greater release version wins const releaseVersionDifference = this._compare_glob(parsed1.rpmRelease, parsed2.rpmRelease); if (releaseVersionDifference !== 0) { return releaseVersionDifference; } // No Prerelease wins if (parsed1.rpmPreRelease === '' && parsed2.rpmPreRelease !== '') { return 1; } else if (parsed1.rpmPreRelease !== '' && parsed2.rpmPreRelease === '') { return -1; } const preReleaseDifference = this._compare_glob(parsed1.rpmPreRelease, parsed2.rpmPreRelease); if (preReleaseDifference !== 0) { return releaseVersionDifference; } // Greater Snapshot wins return this._compare_glob(parsed1.snapshot, parsed2.snapshot); } } exports.api = new RpmVersioningApi(); exports.default = exports.api; //# sourceMappingURL=index.js.map