versionCore.ts 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import { ChildProcess } from 'node:child_process';
  2. import { readStdout, waitForCommand } from './commands';
  3. import { Language } from './localization';
  4. export type Version = `${number}.${number}.${number}`;
  5. export type VersionWithoutPatch = `${number}.${number}`;
  6. export type ResolvedVersion = {
  7. full: Version;
  8. withoutPatch: VersionWithoutPatch;
  9. detected?: Version;
  10. };
  11. export function isValidVersion(
  12. version: string
  13. ): version is Version | VersionWithoutPatch {
  14. return !!version.match(/^\d+\.\d+(\.\d+)?$/);
  15. }
  16. export function assertIsValidVersion(
  17. language: Language,
  18. tool: string,
  19. version: string
  20. ): asserts version is Version | VersionWithoutPatch {
  21. if (!isValidVersion(version)) {
  22. throw new Error(
  23. language.errors.invalidVersion
  24. .replace('$version', version)
  25. .replace('$tool', tool)
  26. );
  27. }
  28. }
  29. export function compareVersions(a: Version, b: Version): number {
  30. return a.localeCompare(b, undefined, { numeric: true });
  31. }
  32. export function getVersionWithoutPatch(
  33. version: Version | VersionWithoutPatch
  34. ): VersionWithoutPatch {
  35. return version.match(/^(\d+\.\d+)/)?.[1] as VersionWithoutPatch;
  36. }
  37. export function getVersionAndVersionWithoutPatch(
  38. version: Version | VersionWithoutPatch,
  39. patchMap: Record<VersionWithoutPatch, Version> = {}
  40. ): [Version, VersionWithoutPatch] {
  41. const segments = version.split('.').length;
  42. if (segments === 3) {
  43. return [version as Version, getVersionWithoutPatch(version)];
  44. }
  45. return [
  46. patchMap[version as VersionWithoutPatch] ?? `${version}.0`,
  47. version as VersionWithoutPatch,
  48. ];
  49. }
  50. export async function getVersionFromStdout(
  51. child: ChildProcess
  52. ): Promise<Version> {
  53. const [stdout] = await Promise.all([
  54. readStdout(child),
  55. waitForCommand(child),
  56. ]);
  57. return stdout.join('').match(/(\d+\.\d+\.\d+)/)?.[1] as Version;
  58. }