namespace StellaOps.Feedser.Merge.Comparers; using System.Diagnostics.CodeAnalysis; using Semver; /// /// Provides helpers to interpret introduced/fixed/lastAffected SemVer ranges and compare versions. /// public static class SemanticVersionRangeResolver { public static bool TryParse(string? value, [NotNullWhen(true)] out SemVersion? result) => SemVersion.TryParse(value, SemVersionStyles.Any, out result); public static SemVersion Parse(string value) => SemVersion.Parse(value, SemVersionStyles.Any); /// /// Resolves the effective start and end versions using introduced/fixed/lastAffected semantics. /// public static (SemVersion? introduced, SemVersion? exclusiveUpperBound, SemVersion? inclusiveUpperBound) ResolveWindows( string? introduced, string? fixedVersion, string? lastAffected) { var introducedVersion = TryParse(introduced, out var parsedIntroduced) ? parsedIntroduced : null; var fixedVersionParsed = TryParse(fixedVersion, out var parsedFixed) ? parsedFixed : null; var lastAffectedVersion = TryParse(lastAffected, out var parsedLast) ? parsedLast : null; SemVersion? exclusiveUpper = null; SemVersion? inclusiveUpper = null; if (fixedVersionParsed is not null) { exclusiveUpper = fixedVersionParsed; } else if (lastAffectedVersion is not null) { inclusiveUpper = lastAffectedVersion; exclusiveUpper = NextPatch(lastAffectedVersion); } return (introducedVersion, exclusiveUpper, inclusiveUpper); } public static int Compare(string? left, string? right) { var leftParsed = TryParse(left, out var leftSemver); var rightParsed = TryParse(right, out var rightSemver); if (leftParsed && rightParsed) { return SemVersion.CompareSortOrder(leftSemver, rightSemver); } if (leftParsed) { return 1; } if (rightParsed) { return -1; } return string.Compare(left, right, StringComparison.Ordinal); } private static SemVersion NextPatch(SemVersion version) { return new SemVersion(version.Major, version.Minor, version.Patch + 1); } }