import { isEmptyArray, isNonEmptyArray, isNonEmptyStringAndNotWhitespace, } from '@sindresorhus/is'; import { RegExpVersioningApi } from '../regex/index.ts'; import type { RegExpVersion } from '../regex/types.ts'; import type { VersioningApiConstructor } from '../types.ts'; export const id = 'nixpkgs'; export const displayName = 'Nixpkgs'; export const urls = ['[Nixpkgs repository](https://github.com/NixOS/nixpkgs)']; export const supportsRanges = false; export class NixPkgsVersioning extends RegExpVersioningApi { private static readonly versionRegex = '^(?(nixos|nixpkgs|release))-((?\\d{2})\\.(?\\d{2})|unstable)(-(?(small|aarch64|darwin)))?$'; constructor() { super(NixPkgsVersioning.versionRegex); } protected override _parse(version: string): RegExpVersion | null { const groups = this._config?.exec(version)?.groups; if (!groups) { return null; } const { prefix, major, minor, suffix } = groups; const release = []; if (major) { release.push(Number.parseInt(major, 10)); } if (minor) { release.push(Number.parseInt(minor, 10)); } const compatibility = isNonEmptyStringAndNotWhitespace(suffix) ? `${prefix}-${suffix}` : prefix; return { release, compatibility, }; } override isStable(version: string): boolean { const parsed = this._parse(version); return isNonEmptyArray(parsed?.release); } protected override _compare(version: string, other: string): number { const left = this._parse(version); const right = this._parse(other); // empty version is equal to 'unstable' if (isEmptyArray(left?.release) && isEmptyArray(right?.release)) { return 0; } if (isEmptyArray(left?.release)) { return 1; } if (isEmptyArray(right?.release)) { return -1; } return super._compare(version, other); } } export const api: VersioningApiConstructor = NixPkgsVersioning; export default api;