UNPKG

@eagleoutice/flowr-dev

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

119 lines 4.95 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.dayToMillis = dayToMillis; exports.parseDateWindow = parseDateWindow; exports.isDateBound = isDateBound; exports.releaseDateBound = releaseDateBound; exports.releasesOf = releasesOf; exports.newestVersion = newestVersion; exports.resolveVersion = resolveVersion; /** * Version/date resolution over a {@link PkgBlob}: parsing stored version strings into comparable * {@link RVersion}s, decoding the day-granularity release dates, and picking the effective version for a query. * Split out of `../sigdb` so the reader/writer there stays focused on the byte format. */ const r_version_1 = require("../../util/r-version"); /** milliseconds since the Unix epoch for a stored day count (dates are stored at day granularity to save space) */ function dayToMillis(day) { return day * 86_400_000; } const DatePartsRegex = /^((?:19|20)\d{2})(?:\.(\d{1,2}))?(?:\.(\d{1,2}))?$/; /** the comparators + `YYYY.MM.DD` date a release-date bound may use (a comparator disambiguates from a calendar version) */ const DateBoundRegex = /^(<=|>=|<|>|=)\s*((?:19|20)\d{2}(?:\.\d{1,2}){0,2})$/; /** * Parse a `YYYY`, `YYYY.MM`, or `YYYY.MM.DD` spec into its inclusive `[lower, upper]` millisecond window (the whole * year / month / day named), or `undefined` when malformed or out of range (month `1..12`, day `1..31`). */ function parseDateWindow(spec) { const m = DatePartsRegex.exec(spec.trim()); if (!m) { return undefined; } const year = Number(m[1]); const month = m[2] !== undefined ? Number(m[2]) : undefined; const day = m[3] !== undefined ? Number(m[3]) : undefined; // reject impossible month/day rather than letting Date.UTC silently roll over (`2021.13` -> Jan 2022) if ((month !== undefined && (month < 1 || month > 12)) || (day !== undefined && (day < 1 || day > 31))) { return undefined; } const lower = Date.UTC(year, (month ?? 1) - 1, day ?? 1); const upper = day !== undefined ? lower + 86_400_000 - 1 : month !== undefined ? Date.UTC(year, month, 1) - 1 : Date.UTC(year + 1, 0, 1) - 1; return { lower, upper }; } /** whether `spec` is a release-date bound like `<=2026` or `>=2021.05` (a comparator is required) */ function isDateBound(spec) { return DateBoundRegex.test(spec.trim()); } /** * A release-date predicate for a bound like `<=2026`, `>=2021.05.03` (`YYYY.MM.DD`, comparator required), or * `undefined` when `spec` is not a date bound. An undated release (or an impossible date) never matches. */ function releaseDateBound(spec) { const m = DateBoundRegex.exec(spec.trim()); if (!m) { return undefined; } const cmp = m[1]; const window = parseDateWindow(m[2]); if (!window) { return () => false; // a valid comparator but an impossible date matches nothing } const { lower, upper } = window; return date => { if (date === undefined) { return false; } const t = date.getTime(); switch (cmp) { case '<=': return t <= upper; case '<': return t < lower; case '>=': return t >= lower; case '>': return t > upper; default: return t >= lower && t <= upper; } }; } /** * The known releases of a blob, ascending by R-version order (empty when no dates were stored). Versions that * differ in writing but not in order (`1.2` and `1.2.0`) compare equal, so their dates settle them. */ function releasesOf(blob) { if (!blob) { return []; } return Object.entries(blob.dates) .map(([ver, day]) => ({ version: r_version_1.RVersion.parseOrZero(ver), date: new Date(dayToMillis(day)) })) .sort((a, b) => r_version_1.RVersion.compare(a.version.str, b.version.str) || (a.date.getTime() - b.date.getTime())); } /** the version with the newest release date (falling back to `latest`, then the highest by R-version order) */ function newestVersion(blob, latest) { let best; let bestDay = -Infinity; for (const [ver, day] of Object.entries(blob.dates)) { if (day > bestDay) { bestDay = day; best = ver; } } if (best !== undefined) { return best; } if (blob.versions[latest]) { return latest; } // no dates and no recorded latest: pick the highest by R's numeric-version order (not string order) return r_version_1.RVersion.highest(Object.keys(blob.versions)); } /** pick the version tuple: requested, else the package's latest, else the highest present by R-version order */ function resolveVersion(blob, latest, version) { if (version && blob.versions[version]) { return version; } if (blob.versions[latest]) { return latest; } return r_version_1.RVersion.highest(Object.keys(blob.versions)); } //# sourceMappingURL=sigdb-version.js.map