From 331c922043a5817ff9abb3a3e0141646944264da Mon Sep 17 00:00:00 2001 From: Sandro Figo Date: Sun, 22 Jan 2023 22:16:08 +0100 Subject: [PATCH 1/4] Fix ChangelogTasks to remove empty lines before parsing (#1097) --- source/Nuke.Common/ChangeLog/ChangeLogTasks.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/Nuke.Common/ChangeLog/ChangeLogTasks.cs b/source/Nuke.Common/ChangeLog/ChangeLogTasks.cs index 74f1ea69c..136ff5169 100644 --- a/source/Nuke.Common/ChangeLog/ChangeLogTasks.cs +++ b/source/Nuke.Common/ChangeLog/ChangeLogTasks.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.IO; using System.Linq; using JetBrains.Annotations; using NuGet.Versioning; @@ -46,7 +47,7 @@ public static string GetNuGetReleaseNotes(string changelogFile, GitRepository re [Pure] public static IReadOnlyList ReadReleaseNotes(string changelogFile) { - var lines = TextTasks.ReadAllLines(changelogFile).ToList(); + var lines = File.ReadAllLines(changelogFile).Where(x => !x.IsNullOrWhiteSpace()).ToList(); var releaseSections = GetReleaseSections(lines).ToList(); Assert.True(releaseSections.Any(), "Changelog should have at least one release note section"); From 6506f3081926e89232e1811b77f5c984a7bf17b5 Mon Sep 17 00:00:00 2001 From: Morten Larsen Date: Sun, 22 Jan 2023 22:32:10 +0100 Subject: [PATCH 2/4] Fix ToolSettings to manually copy ProcessCustomLogger to new instances (#1080) --- source/Nuke.Common.Tests/SettingsTest.cs | 4 ++++ source/Nuke.Tooling/SettingsEntity.NewInstance.cs | 3 +++ source/Nuke.Tooling/ToolSettings.cs | 1 + 3 files changed, 8 insertions(+) diff --git a/source/Nuke.Common.Tests/SettingsTest.cs b/source/Nuke.Common.Tests/SettingsTest.cs index c278329ce..0fd5ced5e 100644 --- a/source/Nuke.Common.Tests/SettingsTest.cs +++ b/source/Nuke.Common.Tests/SettingsTest.cs @@ -30,18 +30,22 @@ private static void Assert(Configure configurator, string arguments) [Fact] public void TestCommon() { + var logEntry = default((OutputType Type, string String)); var settings = new DotNetRunSettings() .SetProcessToolPath("/path/to/dotnet") .SetProcessEnvironmentVariable("key", "value") .SetProcessExecutionTimeout(TimeSpan.FromMilliseconds(1_000)) .SetProcessArgumentConfigurator(_ => _ .Add("/switch")) + .SetProcessCustomLogger((type, str) => logEntry = (type, str)) .EnableProcessLogInvocation(); + settings.ProcessCustomLogger.Invoke(OutputType.Err, "text"); settings.ProcessToolPath.Should().Be("/path/to/dotnet"); settings.ProcessEnvironmentVariables.Should().ContainSingle(x => x.Key == "key" && x.Value == "value"); settings.ProcessExecutionTimeout.Should().Be(1_000); settings.ProcessArgumentConfigurator.Invoke(new Arguments()).RenderForOutput().Should().Be("/switch"); + logEntry.Should().Be((OutputType.Err, "text")); } [Fact] diff --git a/source/Nuke.Tooling/SettingsEntity.NewInstance.cs b/source/Nuke.Tooling/SettingsEntity.NewInstance.cs index 22b33298f..435288b28 100644 --- a/source/Nuke.Tooling/SettingsEntity.NewInstance.cs +++ b/source/Nuke.Tooling/SettingsEntity.NewInstance.cs @@ -25,7 +25,10 @@ public static T NewInstance(this T settingsEntity) var newInstance = (T) binaryFormatter.Deserialize(memoryStream); if (newInstance is ToolSettings toolSettings) + { toolSettings.ProcessArgumentConfigurator = ((ToolSettings) (object) settingsEntity).ProcessArgumentConfigurator; + toolSettings.ProcessCustomLogger = ((ToolSettings) (object) settingsEntity).ProcessCustomLogger; + } return newInstance; } diff --git a/source/Nuke.Tooling/ToolSettings.cs b/source/Nuke.Tooling/ToolSettings.cs index 744be582e..798531b34 100644 --- a/source/Nuke.Tooling/ToolSettings.cs +++ b/source/Nuke.Tooling/ToolSettings.cs @@ -33,6 +33,7 @@ protected ToolSettings() public bool? ProcessLogOutput { get; internal set; } public bool? ProcessLogInvocation { get; internal set; } + [field: NonSerialized] public virtual Action ProcessCustomLogger { get; internal set; } [NonSerialized] From e43af311648e2be2ad9448fd674b7c6ece83508e Mon Sep 17 00:00:00 2001 From: Sandro Figo Date: Sat, 7 Jan 2023 12:30:33 +0100 Subject: [PATCH 3/4] Make GetReleaseSections() and ReleaseSection internal for testing --- source/Nuke.Common/ChangeLog/ChangeLogTasks.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/Nuke.Common/ChangeLog/ChangeLogTasks.cs b/source/Nuke.Common/ChangeLog/ChangeLogTasks.cs index 136ff5169..2bfb91a4f 100644 --- a/source/Nuke.Common/ChangeLog/ChangeLogTasks.cs +++ b/source/Nuke.Common/ChangeLog/ChangeLogTasks.cs @@ -176,7 +176,7 @@ public static IEnumerable ExtractChangelogSectionNotes(string changelogF .Take(section.EndIndex - section.StartIndex); } - private static IEnumerable GetReleaseSections(List content) + internal static IEnumerable GetReleaseSections(List content) { static bool IsReleaseHead(string str) => str.StartsWith("## "); @@ -245,7 +245,7 @@ private static void UpdateVersionSummary(string tag, List content, [CanB } [DebuggerDisplay("{" + nameof(Caption) + "} [{" + nameof(StartIndex) + "}-{" + nameof(EndIndex) + "}]")] - private class ReleaseSection + internal class ReleaseSection { public string Caption; public int StartIndex; From 7bc7fd66b7a5d9d6f34cba219a964e7af9dc6bcc Mon Sep 17 00:00:00 2001 From: Sandro Figo Date: Fri, 6 Jan 2023 22:58:57 +0100 Subject: [PATCH 4/4] Add unit tests for changelog tasks --- .../changelog_reference_1.0.0_variant_1.md | 49 +++++++ .../changelog_reference_1.0.0_variant_2.md | 19 +++ ...log_reference_1.0.0_variant_2.verified.txt | 25 ++++ .../changelog_reference_1.0.0_variant_3.md | 53 +++++++ ...log_reference_1.0.0_variant_3.verified.txt | 65 +++++++++ .../changelog_reference_1.0.0_variant_4.md | 7 + ...log_reference_1.0.0_variant_4.verified.txt | 14 ++ .../changelog_reference_1.0.0_variant_5.md | 10 ++ ...1.0.0_variant_5_section_0.2.3.verified.txt | 4 + .../changelog_reference_invalid_variant_1.md | 2 + .../changelog_reference_invalid_variant_2.md | 13 ++ .../Nuke.Common.Tests/ChangelogTasksTest.cs | 134 ++++++++++++++++++ 12 files changed, 395 insertions(+) create mode 100644 source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_1.md create mode 100644 source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_2.md create mode 100644 source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_2.verified.txt create mode 100644 source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_3.md create mode 100644 source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_3.verified.txt create mode 100644 source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_4.md create mode 100644 source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_4.verified.txt create mode 100644 source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_5.md create mode 100644 source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_5_section_0.2.3.verified.txt create mode 100644 source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_invalid_variant_1.md create mode 100644 source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_invalid_variant_2.md create mode 100644 source/Nuke.Common.Tests/ChangelogTasksTest.cs diff --git a/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_1.md b/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_1.md new file mode 100644 index 000000000..cd4d0eea9 --- /dev/null +++ b/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_1.md @@ -0,0 +1,49 @@ +Some text at the top of the changelog file. + +# Changelog + +This format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). + +## [Unreleased] + +### Added + +- Added something + +### Fixed + +- Fixed something + +## [1.4.0] - 2023-01-05 + +### Added + +- First item +- Second item + +### Changed + +- Fixed something +- Fixed something else + +## [1.0.0] - 2023-01-03 + +### Removed + +- Removed something + +## [0.2.0] - 2023-01-02 + +### Added + +- Some text that spans + multiple lines +- A text on a single line + +## [0.1.0] - 2023-01-01 + +### Added + +- Added something + +Some text at the end of the changelog file. \ No newline at end of file diff --git a/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_2.md b/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_2.md new file mode 100644 index 000000000..078876296 --- /dev/null +++ b/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_2.md @@ -0,0 +1,19 @@ +# Changelog + +This format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). + +## [Unreleased] + +### Added + +- Some text that spans + multiple lines + +- A text on a single line + + +## [1.0.0] - 2023-01-01 + +### Fixed + +- Fixed something \ No newline at end of file diff --git a/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_2.verified.txt b/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_2.verified.txt new file mode 100644 index 000000000..838cd1b39 --- /dev/null +++ b/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_2.verified.txt @@ -0,0 +1,25 @@ +[ + { + IsEmpty: false, + Unreleased: true, + Notes: [ + ### Added, + - Some text that spans, + multiple lines, + - A text on a single line + ], + StartIndex: 2, + EndIndex: 6 + }, + { + IsEmpty: false, + Unreleased: false, + Version: 1.0.0, + Notes: [ + ### Fixed, + - Fixed something + ], + StartIndex: 7, + EndIndex: 9 + } +] \ No newline at end of file diff --git a/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_3.md b/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_3.md new file mode 100644 index 000000000..496c7d5c4 --- /dev/null +++ b/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_3.md @@ -0,0 +1,53 @@ +Some text at the top of the changelog file. + +# Changelog + +This format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). + +## [Unreleased] + +### Added + +- Added something + + ### Fixed + +- Fixed something + +## [1.4.0] - 2023-01-05 + +### Added + + + + +- First item + +- Second item + +### Changed + +- Fixed something +- Fixed something else + +## [1.0.0] - 2023-01-03 + +### Removed + + - Removed something + +## [0.2.0] - 2023-01-02 + +### Added + +- Some text that spans + multiple lines +- A text on a single line + +## [0.1.0] - 2023-01-01 + +### Added + +- Added something + + Some text at the end of the changelog file. \ No newline at end of file diff --git a/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_3.verified.txt b/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_3.verified.txt new file mode 100644 index 000000000..3adcc4356 --- /dev/null +++ b/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_3.verified.txt @@ -0,0 +1,65 @@ +[ + { + IsEmpty: false, + Unreleased: true, + Notes: [ + ### Added, + - Added something, + ### Fixed, + - Fixed something + ], + StartIndex: 3, + EndIndex: 7 + }, + { + IsEmpty: false, + Unreleased: false, + Version: 1.4.0, + Notes: [ + ### Added , + - First item, + - Second item, + ### Changed, + - Fixed something, + - Fixed something else + ], + StartIndex: 8, + EndIndex: 14 + }, + { + IsEmpty: false, + Unreleased: false, + Version: 1.0.0, + Notes: [ + ### Removed, + - Removed something + ], + StartIndex: 15, + EndIndex: 17 + }, + { + IsEmpty: false, + Unreleased: false, + Version: 0.2.0, + Notes: [ + ### Added, + - Some text that spans, + multiple lines, + - A text on a single line + ], + StartIndex: 18, + EndIndex: 22 + }, + { + IsEmpty: false, + Unreleased: false, + Version: 0.1.0, + Notes: [ + ### Added, + - Added something, + Some text at the end of the changelog file. + ], + StartIndex: 23, + EndIndex: 26 + } +] \ No newline at end of file diff --git a/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_4.md b/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_4.md new file mode 100644 index 000000000..ea8781327 --- /dev/null +++ b/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_4.md @@ -0,0 +1,7 @@ +# Changelog +This format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [Unreleased] +### Added +- Some text that spans + multiple lines +- A text on a single line \ No newline at end of file diff --git a/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_4.verified.txt b/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_4.verified.txt new file mode 100644 index 000000000..1dc9874b9 --- /dev/null +++ b/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_4.verified.txt @@ -0,0 +1,14 @@ +[ + { + IsEmpty: false, + Unreleased: true, + Notes: [ + ### Added, + - Some text that spans, + multiple lines, + - A text on a single line + ], + StartIndex: 2, + EndIndex: 6 + } +] \ No newline at end of file diff --git a/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_5.md b/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_5.md new file mode 100644 index 000000000..501bce708 --- /dev/null +++ b/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_5.md @@ -0,0 +1,10 @@ +# Changelog +This format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [Unreleased] +### Added +- Some text that spans + multiple lines +- A text on a single line +## [0.2.3] - 2023-01-02 +### Fixed +- Fixed something \ No newline at end of file diff --git a/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_5_section_0.2.3.verified.txt b/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_5_section_0.2.3.verified.txt new file mode 100644 index 000000000..565c36793 --- /dev/null +++ b/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_1.0.0_variant_5_section_0.2.3.verified.txt @@ -0,0 +1,4 @@ +[ + ### Fixed, + - Fixed something +] \ No newline at end of file diff --git a/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_invalid_variant_1.md b/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_invalid_variant_1.md new file mode 100644 index 000000000..2fcff6fc2 --- /dev/null +++ b/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_invalid_variant_1.md @@ -0,0 +1,2 @@ +# Changelog +A change log that does not comply with the format from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). \ No newline at end of file diff --git a/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_invalid_variant_2.md b/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_invalid_variant_2.md new file mode 100644 index 000000000..a4b321c62 --- /dev/null +++ b/source/Nuke.Common.Tests/ChangelogReferenceFiles/changelog_reference_invalid_variant_2.md @@ -0,0 +1,13 @@ +# Changelog +A change log that does not comply with the format from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [Unreleased] +### Added +- Some text that spans + multiple lines +- A text on a single line +## [Unreleased] +### Added +- Second unreleased section +## [0.2.3] - 2023-01-02 +### Fixed +- Fixed something \ No newline at end of file diff --git a/source/Nuke.Common.Tests/ChangelogTasksTest.cs b/source/Nuke.Common.Tests/ChangelogTasksTest.cs new file mode 100644 index 000000000..66cbcedbe --- /dev/null +++ b/source/Nuke.Common.Tests/ChangelogTasksTest.cs @@ -0,0 +1,134 @@ +// Copyright 2023 Maintainers of NUKE. +// Distributed under the MIT License. +// https://github.com/nuke-build/nuke/blob/master/LICENSE + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using FluentAssertions; +using JetBrains.Annotations; +using Nuke.Common.ChangeLog; +using Nuke.Common.IO; +using VerifyXunit; +using Xunit; + +namespace Nuke.Common.Tests +{ + [UsesVerify] + public class ChangelogTasksTest + { + private static AbsolutePath RootDirectory => Constants.TryGetRootDirectoryFrom(EnvironmentInfo.WorkingDirectory).NotNull(); + + private static AbsolutePath PathToChangelogReferenceFiles => RootDirectory / "source" / "Nuke.Common.Tests" / "ChangelogReferenceFiles"; + + [Theory] + [MemberData(nameof(AllChangelogReference_1_0_0_Files))] + public void ReadReleaseNotes_ChangelogReferenceFile_ThrowsNoExceptions(AbsolutePath file) + { + Action act = () => ChangelogTasks.ReadReleaseNotes(file); + + act.Should().NotThrow(); + } + + [Theory] + [MemberData(nameof(AllChangelogReference_1_0_0_Files))] + public void ReadReleaseNotes_ChangelogReferenceFile_ReturnsAnyReleaseNotes(AbsolutePath file) + { + var releaseNotes = ChangelogTasks.ReadReleaseNotes(file); + + releaseNotes.Should().NotBeEmpty(); + } + + [Theory] + [MemberData(nameof(AllChangelogReference_1_0_0_Files))] + public void ReadChangelog_ChangelogReferenceFile_ThrowsNoExceptions(AbsolutePath file) + { + Action act = () => ChangelogTasks.ReadChangelog(file); + + act.Should().NotThrow(); + } + + [Theory] + [MemberData(nameof(AllChangelogReference_1_0_0_Files))] + public void ExtractChangelogSectionNotes_ChangelogReferenceFile_ThrowsNoExceptions(AbsolutePath file) + { + Action act = () => ChangelogTasks.ExtractChangelogSectionNotes(file); + + act.Should().NotThrow(); + } + + [Theory] + [InlineData("changelog_reference_1.0.0_variant_2.md")] + [InlineData("changelog_reference_1.0.0_variant_3.md")] + [InlineData("changelog_reference_1.0.0_variant_4.md")] + public Task ReadReleaseNotes_ChangelogReferenceFile_HasParsedCorrectly(string fileName) + { + var changeLogFilePath = PathToChangelogReferenceFiles / fileName; + + var releaseNotes = ChangelogTasks.ReadReleaseNotes(changeLogFilePath); + + return Verifier.Verify(releaseNotes).UseDirectory(PathToChangelogReferenceFiles).UseFileName(changeLogFilePath.NameWithoutExtension); + } + + [Fact] + public void GetReleaseSections_ChangelogReferenceFileWithoutReleaseHead_ReturnsEmpty() + { + var changeLogFilePath = PathToChangelogReferenceFiles / "changelog_reference_invalid_variant_1.md"; + var lines = changeLogFilePath.ReadAllLines().ToList(); + + ChangelogTasks.GetReleaseSections(lines).Should().BeEmpty(); + } + + [Theory] + [InlineData("changelog_reference_1.0.0_variant_5.md", "0.2.3")] + public Task ExtractChangelogSectionNotes_WithTag_ReturnsSectionThatMatchesProvidedTag(string fileName, string tag) + { + var changeLogFilePath = PathToChangelogReferenceFiles / fileName; + var sectionNotes = ChangelogTasks.ExtractChangelogSectionNotes(changeLogFilePath, tag); + + return Verifier.Verify(sectionNotes).UseDirectory(PathToChangelogReferenceFiles) + .UseFileName($"{changeLogFilePath.NameWithoutExtension}_section_{tag}"); + } + + [Theory] + [InlineData("changelog_reference_1.0.0_variant_5.md", "0.0.0")] + [InlineData("changelog_reference_1.0.0_variant_5.md", "9.9.9")] + public void ExtractChangelogSection_WithNonExistingTag_ThrowsInformativeException(string fileName, string tag) + { + var changeLogFilePath = PathToChangelogReferenceFiles / fileName; + + Action act = () => ChangelogTasks.ExtractChangelogSectionNotes(changeLogFilePath, tag); + + act.Should().Throw().Where(ex => ex.Message == $"Could not find release section for '{tag}'."); + } + + [Theory] + [InlineData("changelog_reference_invalid_variant_2.md")] + public void ReadChangelog_ChangelogFileThatHasMultipleUnreleasedSection_ThrowsInformativeException(string fileName) + { + var changeLogFilePath = PathToChangelogReferenceFiles / fileName; + + Action act = () => ChangelogTasks.ReadChangelog(changeLogFilePath); + + act.Should().Throw().Where(ex => ex.Message == "Changelog should have only one draft section"); + } + + [Theory] + [InlineData("changelog_reference_invalid_variant_1.md")] + public void ReadChangelog_EmptyChangelogFile_ThrowsInformativeException(string fileName) + { + var changeLogFilePath = PathToChangelogReferenceFiles / fileName; + + Action act = () => ChangelogTasks.ReadChangelog(changeLogFilePath); + + act.Should().Throw().Where(ex => ex.Message == "Changelog should have at least one release note section"); + } + + [UsedImplicitly] + public static IEnumerable AllChangelogReference_1_0_0_Files + { + get => PathToChangelogReferenceFiles.GlobFiles("changelog_reference_1.0.0*.md").Select(file => new object[] { file }); + } + } +}