UNPKG

renovate

Version:

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

229 lines (228 loc) • 7.19 kB
//#region lib/modules/versioning/bazel-module/bzlmod-version.ts /** * @fileoverview Contains classes that represent a Bazel module version. */ /** * Represents a single value in a VersionPart. For example, the version string * `1.2.3` has three identifiers: `1`, `2`, `3`. */ var Identifier = class Identifier { /** * Returns the identifier as a string. */ asString; /** * If the identifier only contains digits, this is the numeric value. * Otherwise, it is `0`. */ asNumber; /** * Specifies whether the identifier only contains digits. */ isDigitsOnly; /** * Regular expression used to identify whether an identifier value only * contains digits. */ static digitsOnlyMatcher = /^[0-9]+$/; /** * @param value The value that is parsed for the Bazel module version parts. */ constructor(value) { if (value === "") throw new Error("Identifier value cannot be empty."); this.asString = value; if (Identifier.digitsOnlyMatcher.test(value)) { this.isDigitsOnly = true; this.asNumber = parseInt(value, 10); } else { this.isDigitsOnly = false; this.asNumber = 0; } } /** * Determines whether this identifier and another identifier are equal. */ equals(other) { return this.asString === other.asString; } /** * Determines whether this identifier comes before the other identifier. */ isLessThan(other) { if (this.isDigitsOnly !== other.isDigitsOnly) return this.isDigitsOnly; if (this.asNumber !== other.asNumber) return this.asNumber < other.asNumber; return this.asString < other.asString; } }; /** * A collection of {@link Identifier} values that represent a portion of a * Bazel module version. */ var VersionPart = class VersionPart extends Array { /** * Creates a {@link VersionPart} populated with the provided identifiers. */ static create(...items) { const idents = items.map((item) => { if (typeof item === "string") return new Identifier(item); return item; }); const vp = new VersionPart(); vp.push(...idents); return vp; } /** * The string representation of the version part. */ get asString() { return this.map((ident) => ident.asString).join("."); } /** * Specifies whether this contains any identifiers. */ get isEmpty() { return this.length === 0; } /** * Returns the equivalent of the a Semver major value. */ get major() { return this.length > 0 ? this[0].asNumber : 0; } /** * Returns the equivalent of the a Semver minor value. */ get minor() { return this.length > 1 ? this[1].asNumber : 0; } /** * Returns the equivalent of the a Semver patch value. */ get patch() { return this.length > 2 ? this[2].asNumber : 0; } /** * Determines whether this version part is equal to the other. */ equals(other) { if (this.length !== other.length) return false; for (let i = 0; i < this.length; i++) { const a = this[i]; const b = other[i]; if (!a.equals(b)) return false; } return true; } /** * Determines whether this version part comes before the other. */ isLessThan(other) { if (this.equals(other)) return false; if (this.length === 0 && other.length !== 0) return false; if (other.length === 0 && this.length !== 0) return true; const shortestLen = this.length < other.length ? this.length : other.length; for (let i = 0; i < shortestLen; i++) { const a = this[i]; const b = other[i]; if (!a.equals(b)) return a.isLessThan(b); } return this.length < other.length; } }; /** * Represents a version in the Bazel module system. The version format we support is * `RELEASE[-PRERELEASE][+BUILD]`, where `RELEASE`, `PRERELEASE`, and `BUILD` are * each a sequence of "identifiers" (defined as a non-empty sequence of ASCII alphanumerical * characters and hyphens) separated by dots. The `RELEASE` part may not contain hyphens. * * Otherwise, this format is identical to SemVer, especially in terms of the comparison algorithm * (https://semver.org/#spec-item-11). In other words, this format is intentionally looser than * SemVer; in particular: * * - the "release" part isn't limited to exactly 3 segments (major, minor, patch), but can be * fewer or more; * - each segment in the "release" part can be identifiers instead of just numbers (so letters * are also allowed -- although hyphens are not). * * Any valid SemVer version is a valid Bazel module version. Additionally, two SemVer versions * `a` and `b` compare `a < b` iff the same holds when they're compared as Bazel * module versions. * * The special "empty string" version can also be used, and compares higher than everything else. * It signifies that there is a NonRegistryOverride for a module. */ var BzlmodVersion = class BzlmodVersion { original; release; prerelease; build; /** * The regular expression that identifies a valid Bazel module version. */ static versionMatcher = /^(?<release>[a-zA-Z0-9.]+)(?:-(?<prerelease>[a-zA-Z0-9.-]+))?(?:\+(?<build>[a-zA-Z0-9.-]+))?$/; /** * @param version The string that is parsed for the Bazel module version * values. */ constructor(version) { this.original = version; if (version === "") { this.release = VersionPart.create(); this.prerelease = VersionPart.create(); this.build = VersionPart.create(); return; } const vparts = BzlmodVersion.versionMatcher.exec(version)?.groups; if (!vparts) throw new Error(`Invalid Bazel module version: ${version}`); const rparts = vparts.release.split("."); this.release = VersionPart.create(...rparts); const pparts = vparts.prerelease ? vparts.prerelease.split(".") : []; this.prerelease = VersionPart.create(...pparts); const bparts = vparts.build ? [vparts.build] : []; this.build = VersionPart.create(...bparts); } /** * Specifies whether this is a pre-release version. */ get isPrerelease() { return !this.prerelease.isEmpty; } /** * Determines whether this Bazel module version is equal to the other. * * @param other The other version for the comparison. * @param ignoreBuild? If specified, determines whether the build value is * evaluated as part of the equality check. This is useful when * determining precedence. */ equals(other, ignoreBuild) { if (ignoreBuild) return this.release.equals(other.release) && this.prerelease.equals(other.prerelease); return this.release.equals(other.release) && this.prerelease.equals(other.prerelease) && this.build.equals(other.build); } /** * Determines whether this Bazel module version comes before the other. */ isLessThan(other) { if (this.release.isLessThan(other.release)) return true; if (this.isPrerelease && !other.isPrerelease) return true; if (this.prerelease.isLessThan(other.prerelease)) return true; return false; } /** * Determines whether this Bazel module version comes after the other. */ isGreaterThan(other) { return BzlmodVersion.defaultCompare(this, other) === 1; } /** * Evaluates two Bazel module versions and returns a value specifying whether * a < b (-1), a == b (0), or a > b (1). */ static defaultCompare(a, b) { if (a.equals(b, true)) return 0; if (a.isLessThan(b)) return -1; return 1; } }; //#endregion export { BzlmodVersion }; //# sourceMappingURL=bzlmod-version.js.map