From 7c0f8d8408f077f1e3fc2f9d9fe372996dda3191 Mon Sep 17 00:00:00 2001 From: mika kuns Date: Thu, 23 Apr 2026 14:21:25 +0200 Subject: [PATCH] feat(releases): add VersionComparer --- src/ClaudeDo.Releases/VersionComparer.cs | 18 +++++++++++ .../VersionComparerTests.cs | 30 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 src/ClaudeDo.Releases/VersionComparer.cs create mode 100644 tests/ClaudeDo.Releases.Tests/VersionComparerTests.cs diff --git a/src/ClaudeDo.Releases/VersionComparer.cs b/src/ClaudeDo.Releases/VersionComparer.cs new file mode 100644 index 0000000..e38d1fc --- /dev/null +++ b/src/ClaudeDo.Releases/VersionComparer.cs @@ -0,0 +1,18 @@ +namespace ClaudeDo.Releases; + +public readonly record struct VersionCompareResult(bool IsNewer, bool Unparseable); + +public static class VersionComparer +{ + public static VersionCompareResult Compare(string latest, string current) + { + var latestTrimmed = (latest ?? "").TrimStart('v', 'V'); + var currentTrimmed = (current ?? "").TrimStart('v', 'V'); + + var unparseable = !Version.TryParse(latestTrimmed, out var lv) + | !Version.TryParse(currentTrimmed, out var cv); + + if (unparseable) return new VersionCompareResult(false, true); + return new VersionCompareResult(lv > cv, false); + } +} diff --git a/tests/ClaudeDo.Releases.Tests/VersionComparerTests.cs b/tests/ClaudeDo.Releases.Tests/VersionComparerTests.cs new file mode 100644 index 0000000..5aba89f --- /dev/null +++ b/tests/ClaudeDo.Releases.Tests/VersionComparerTests.cs @@ -0,0 +1,30 @@ +namespace ClaudeDo.Releases.Tests; + +public class VersionComparerTests +{ + [Theory] + [InlineData("0.2.0", "0.1.0", true, false)] + [InlineData("0.2.0", "0.2.0", false, false)] + [InlineData("0.1.0", "0.2.0", false, false)] + [InlineData("v0.2.0", "0.1.0", true, false)] + [InlineData("0.2.0", "v0.1.0", true, false)] + [InlineData("1.0.0.0", "0.99.99.99", true, false)] + public void Compare_ParseableVersions(string latest, string current, bool expectedNewer, bool expectedUnparseable) + { + var result = VersionComparer.Compare(latest, current); + Assert.Equal(expectedNewer, result.IsNewer); + Assert.Equal(expectedUnparseable, result.Unparseable); + } + + [Theory] + [InlineData("0.2.0-beta", "0.1.0")] + [InlineData("0.2.0", "0.1.0-alpha")] + [InlineData("garbage", "0.1.0")] + [InlineData("", "0.1.0")] + public void Compare_UnparseableReturnsNotNewer(string latest, string current) + { + var result = VersionComparer.Compare(latest, current); + Assert.False(result.IsNewer); + Assert.True(result.Unparseable); + } +}