@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
109 lines • 3.93 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseRVersion = parseRVersion;
exports.parseRRange = parseRRange;
const semver_1 = require("semver");
const assert_1 = require("./assert");
function makeVersion(version, original) {
const semver = new semver_1.SemVer(version);
semver.str = original;
return semver;
}
function tryNormalizeNumberPart(part) {
try {
const res = Number(part);
if (!Number.isNaN(res)) {
return String(res);
}
}
catch {
return part;
}
return part;
}
function normalizeVersion(version) {
version = version.trim();
let comparator = '';
// extract comparator if present
const comparatorMatch = version.match(/^([<>=~^]+)/);
if (comparatorMatch) {
comparator = comparatorMatch[1].replace('==', '=');
version = version.slice(comparatorMatch[1].length).trim();
}
const [mainVersion, ...preReleaseParts] = version.split('-');
const mainVersionParts = mainVersion.split('.');
if (mainVersionParts.length > 3) {
const newPreReleasePart = mainVersionParts.splice(3).join('.');
preReleaseParts.unshift(newPreReleasePart);
}
else {
while (mainVersionParts.length < 3) {
mainVersionParts.push('0');
}
}
let prerelease = '';
if (preReleaseParts.length > 0) {
prerelease = '-' + preReleaseParts.join('-').split('.').map(part => tryNormalizeNumberPart(part)).join('.');
}
return comparator + mainVersionParts.map(tryNormalizeNumberPart).join('.') + prerelease;
}
const AnyVerWithMaybeRangeRegex = /(\s*[<>=~^]*\s*\d+(\.\d*)*(-[0-9A-Za-z-.]+)?)/g;
function normalizeVersions(versions) {
const parts = [];
// extract all version-like parts and normalize them individually
let match;
let index = 0;
while ((match = AnyVerWithMaybeRangeRegex.exec(versions)) !== null) {
const prefix = versions.slice(index, match.index);
if (prefix.length > 0) {
parts.push(prefix);
}
const versionPart = match[1];
parts.push(normalizeVersion(versionPart));
index = match.index + versionPart.length;
}
if (index < versions.length) {
parts.push(versions.slice(index));
}
return parts.join('');
}
/**
* This parses an R version string and returns a SemVer object.
* In contrast to just using `new SemVer(version)`, this function also tries to
* normalize R's much free-er versioning scheme into valid SemVer versions.
* You can always access the original version string via the `str` property on the returned object.
*/
function parseRVersion(version) {
try {
return makeVersion(version, version);
}
catch { /* do nothing */ }
try {
const normalized = normalizeVersions(version);
return makeVersion(normalized, version);
}
catch { /* do nothing */ }
const coerced = (0, semver_1.coerce)(version, { loose: true, includePrerelease: true });
(0, assert_1.guard)(coerced !== null, `Could not coerce R version "${version}" to SemVer`);
return makeVersion(coerced.version, version);
}
function makeRange(range, original) {
const semverRange = new semver_1.Range(range);
semverRange.str = original;
return semverRange;
}
/**
* This parses an R version range string and returns a SemVer Range object.
* In contrast to just using `new Range(range)`, this function also tries to
* normalize R's much free-er versioning scheme into valid SemVer ranges.
* You can always access the original range string via the `str` property on the returned object.
*/
function parseRRange(range) {
try {
return makeRange(range, range);
}
catch { /* try to normalize R range to SemVer */ }
const normalized = normalizeVersions(range);
return makeRange(normalized, range);
}
//# sourceMappingURL=r-version.js.map