diff --git a/StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs index d33cb273..d83426d4 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs @@ -57,7 +57,7 @@ public partial class UpdateViewModel : ContentDialogViewModelBase private string? newVersionText; [GeneratedRegex( - @"(##\s*(v[0-9]+\.[0-9]+\.[0-9]+)((?:\n|.)+?))(?=(##\s*v[0-9]+\.[0-9]+\.[0-9]+)|\z)" + @"(##\s*(v[0-9]+\.[0-9]+\.[0-9]+(?:-(?:[0-9A-Za-z-.]+))?)((?:\n|.)+?))(?=(##\s*v[0-9]+\.[0-9]+\.[0-9]+)|\z)" )] private static partial Regex RegexChangelog(); @@ -82,7 +82,14 @@ public partial class UpdateViewModel : ContentDialogViewModelBase /// /// Formats changelog markdown including up to the current version /// - internal static string? FormatChangelog(string markdown, SemVersion currentVersion) + /// Markdown to format + /// Versions equal or below this are excluded + /// Maximum channel level to include + internal static string? FormatChangelog( + string markdown, + SemVersion currentVersion, + UpdateChannel maxChannel = UpdateChannel.Stable + ) { var pattern = RegexChangelog(); @@ -93,28 +100,59 @@ public partial class UpdateViewModel : ContentDialogViewModelBase new { Block = m.Groups[1].Value.Trim(), - Version = m.Groups[2].Value.Trim(), + Version = SemVersion.TryParse( + m.Groups[2].Value.Trim(), + SemVersionStyles.AllowV, + out var version + ) + ? version + : null, Content = m.Groups[3].Value.Trim() } ) + .Where(x => x.Version is not null) .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()}" + x => x.Version == currentVersion.WithoutMetadata() ); + // Support for previous pre-release without changelogs + if (currentVersionBlock == -1) + { + currentVersionBlock = results.FindIndex( + x => x.Version == currentVersion.WithoutPrereleaseOrMetadata() + ); + + // Add 1 if found to include the current release + if (currentVersionBlock != -1) + { + currentVersionBlock++; + } + } + + // Still not found, just include all if (currentVersionBlock == -1) { - return null; + currentVersionBlock = results.Count; } + // Filter out pre-releases var blocks = results - .Take(currentVersionBlock + (currentVersion.IsPrerelease ? 1 : 0)) - .Select(x => x.Block) - .ToList(); + .Take(currentVersionBlock) + .Where( + x => + x.Version!.PrereleaseIdentifiers.Count == 0 + || x.Version.PrereleaseIdentifiers[0].Value switch + { + "pre" when maxChannel >= UpdateChannel.Preview => true, + "dev" when maxChannel >= UpdateChannel.Development => true, + _ => false + } + ) + .Select(x => x.Block); return string.Join(Environment.NewLine + Environment.NewLine, blocks); } diff --git a/StabilityMatrix.Tests/Avalonia/UpdateViewModelTests.cs b/StabilityMatrix.Tests/Avalonia/UpdateViewModelTests.cs index 7c5bb4e0..829e0b99 100644 --- a/StabilityMatrix.Tests/Avalonia/UpdateViewModelTests.cs +++ b/StabilityMatrix.Tests/Avalonia/UpdateViewModelTests.cs @@ -1,5 +1,6 @@ using Semver; using StabilityMatrix.Avalonia.ViewModels.Dialogs; +using StabilityMatrix.Core.Models.Update; namespace StabilityMatrix.Tests.Avalonia; @@ -65,4 +66,63 @@ public class UpdateViewModelTests """; Assert.AreEqual(expectedPre, resultPre); } + + [TestMethod] + public void FormatChangelogWithChannelTest() + { + // Arrange + const string markdown = """ + # Changelog + + All notable changes to Stability Matrix will be documented in this file. + + The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), + and this project adheres to [Semantic Versioning 2.0](https://semver.org/spec/v2.0.0.html). + + ## v2.4.6 + ### Added + - Stuff + ### Changed + - Things + + ## v2.4.6-pre.1 + ### Fixed + - Fixed bug + + ## v2.4.6-dev.1 + ### Fixed + - Fixed bug + + ## v2.4.5 + ### Changed + - Changed stuff + """; + + // Act + var result = UpdateViewModel.FormatChangelog( + markdown, + SemVersion.Parse("2.4.0"), + UpdateChannel.Preview + ); + + // Assert + const string expected = """ + ## v2.4.6 + ### Added + - Stuff + ### Changed + - Things + + ## v2.4.6-pre.1 + ### Fixed + - Fixed bug + + ## v2.4.5 + ### Changed + - Changed stuff + """; + + // Should include pre but not dev + Assert.AreEqual(expected, result); + } }