UNPKG

renovate

Version:

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

111 lines (110 loc) 3.8 kB
import { regEx } from "../../../util/regex.js"; import { RANGE_COMPARATOR_PATTERN, VERSION_PATTERN } from "./patterns.js"; import semver from "semver"; //#region lib/modules/versioning/poetry/transform.ts function parseLetterTag(letter, number) { if (letter !== void 0) return { letter: { alpha: "a", beta: "b", c: "rc", pre: "rc", preview: "rc", r: "post", rev: "post" }[letter] || letter, number: number ?? "0" }; if (letter === void 0 && number !== void 0) return { letter: "post", number }; return null; } function notEmpty(s) { return s !== ""; } /** * Parse versions like poetry.core.masonry.version.Version does (union of SemVer * and PEP440, with normalization of certain prerelease tags), and emit in SemVer * format. NOTE: this silently discards the epoch field in PEP440 versions, as * it has no equivalent in SemVer. */ function poetry2semver(poetry_version, padRelease = true) { const matchGroups = VERSION_PATTERN.exec(poetry_version)?.groups; if (!matchGroups) return null; const releaseParts = matchGroups.release.split(".").map((segment) => parseInt(segment, 10)); while (padRelease && releaseParts.length < 3) releaseParts.push(0); const pre = parseLetterTag(matchGroups.pre_l, matchGroups.pre_n); const post = matchGroups.post_n1 ? parseLetterTag(void 0, matchGroups.post_n1) : parseLetterTag(matchGroups.post_l, matchGroups.post_n); const dev = parseLetterTag(matchGroups.dev_l, matchGroups.dev_n); const parts = [releaseParts.map((num) => num.toString()).join(".")]; if (pre !== null) { pre.number = pre.number.replace(regEx(/^0+(\d+)/), "$1"); parts.push(`-${pre.letter}.${pre.number}`); } if (post !== null) { post.number = post.number.replace(regEx(/^0+(\d+)/), "$1"); parts.push(`-${post.letter}.${post.number}`); } if (dev !== null) { dev.number = dev.number.replace(regEx(/^0+(\d+)/), "$1"); parts.push(`-${dev.letter}.${dev.number}`); } return semver.valid(parts.join("")); } /** Reverse normalizations applied by poetry2semver */ function semver2poetry(version) { if (!version) return null; const s = semver.parse(version); if (!s) return null; const spellings = { a: "alpha", b: "beta", c: "rc", dev: "alpha" }; s.prerelease = s.prerelease.map((letter) => spellings[letter] ?? letter); return s.format(); } /** * Translate a poetry-style version range to npm format * * This function works like cargo2npm, but it doesn't * add a '^', because poetry treats versions without operators as * exact versions. */ function poetry2npm(input, throwOnUnsupported = false) { const transformed = input.split(",").map((str) => str.trim()).filter(notEmpty).join(" ").split(RANGE_COMPARATOR_PATTERN).map((chunk) => poetry2semver(chunk, false) ?? chunk).join("").replace(/===/, "="); if (throwOnUnsupported) { if (transformed.split(regEx(/\s+/)).some((part) => part.startsWith("!="))) throw new Error("Unsupported by Poetry versioning implementation"); } return transformed; } /** * Translate an npm-style version range to poetry format * * NOTE: This function is largely copied from cargo versioning code. * Poetry uses commas (like in cargo) instead of spaces (like in npm) * for AND operation. */ function npm2poetry(range) { const res = range.split(RANGE_COMPARATOR_PATTERN).map((chunk) => semver2poetry(chunk) ?? chunk).join("").split(" ").map((str) => str.trim()).filter(notEmpty); const operators = [ "^", "~", "=", ">", "<", "<=", ">=" ]; for (let i = 0; i < res.length - 1; i += 1) if (operators.includes(res[i])) { const newValue = `${res[i]} ${res[i + 1]}`; res.splice(i, 2, newValue); } return res.join(", ").replace(/\s*,?\s*\|\|\s*,?\s*/g, " || "); } //#endregion export { npm2poetry, poetry2npm, poetry2semver, semver2poetry }; //# sourceMappingURL=transform.js.map