From 5aa2e5d6e49a5fabb12f6764eea4fd9364f7cb8b Mon Sep 17 00:00:00 2001 From: Ionite Date: Wed, 27 Sep 2023 17:33:28 -0400 Subject: [PATCH] Improve changelog parse to include current version in prerelease --- .../ViewModels/Dialogs/UpdateViewModel.cs | 42 +++++++++++++++++-- .../Avalonia/UpdateViewModelTests.cs | 15 ++++++- 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs index 40018206..8710295a 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs @@ -1,6 +1,7 @@ using System; using System.Diagnostics; using System.IO; +using System.Linq; using System.Net.Http; using System.Text.RegularExpressions; using System.Threading.Tasks; @@ -53,6 +54,11 @@ public partial class UpdateViewModel : ContentDialogViewModelBase [ObservableProperty] private string? newVersionText; + [GeneratedRegex( + @"(##\s*(v[0-9]+\.[0-9]+\.[0-9]+)((?:\n|.)+?))(?=(##\s*v[0-9]+\.[0-9]+\.[0-9]+)|\z)" + )] + private static partial Regex RegexChangelog(); + public UpdateViewModel( ISettingsManager settingsManager, IHttpClientFactory httpClientFactory, @@ -76,11 +82,39 @@ public partial class UpdateViewModel : ContentDialogViewModelBase /// internal static string? FormatChangelog(string markdown, SemVersion currentVersion) { - var pattern = $@"(##[\s\S]+?)(?:## v{currentVersion.WithoutPrereleaseOrMetadata()})"; + var pattern = RegexChangelog(); + + var results = pattern + .Matches(markdown) + .Select( + m => + new + { + Block = m.Groups[1].Value.Trim(), + Version = m.Groups[2].Value.Trim(), + Content = m.Groups[3].Value.Trim() + } + ) + .ToList(); + + // Join all blocks until and excluding the current version + // If we're on a pre-release, include the current release + + var currentVersionBlock = results.FindIndex( + x => x.Version == $"v{currentVersion.WithoutPrereleaseOrMetadata()}" + ); + + if (currentVersionBlock == -1) + { + return null; + } - var match = Regex.Match(markdown, pattern); + var blocks = results + .Take(currentVersionBlock + (currentVersion.IsPrerelease ? 1 : 0)) + .Select(x => x.Block) + .ToList(); - return match.Success ? match.Groups[1].Value.TrimEnd() : null; + return string.Join(Environment.NewLine + Environment.NewLine, blocks); } public async Task Preload() @@ -99,7 +133,7 @@ public partial class UpdateViewModel : ContentDialogViewModelBase if (UpdateInfo.ChangelogUrl.EndsWith(".md", StringComparison.OrdinalIgnoreCase)) { ReleaseNotes = - FormatChangelog(changelog, UpdateInfo.Version) + FormatChangelog(changelog, Compat.AppVersion) ?? "## Unable to format release notes"; } } diff --git a/StabilityMatrix.Tests/Avalonia/UpdateViewModelTests.cs b/StabilityMatrix.Tests/Avalonia/UpdateViewModelTests.cs index 93a05de3..7c5bb4e0 100644 --- a/StabilityMatrix.Tests/Avalonia/UpdateViewModelTests.cs +++ b/StabilityMatrix.Tests/Avalonia/UpdateViewModelTests.cs @@ -50,6 +50,19 @@ public class UpdateViewModelTests """; Assert.AreEqual(expected, result); - Assert.AreEqual(expected, resultPre); + + // Pre-release should include the current release + const string expectedPre = """ + ## v2.4.6 + ### Added + - Stuff + ### Changed + - Things + + ## v2.4.5 + ### Fixed + - Fixed bug + """; + Assert.AreEqual(expectedPre, resultPre); } }