diff --git a/Versionize.Tests/Changelog/ChangelogBuilderTests.cs b/Versionize.Tests/Changelog/ChangelogBuilderTests.cs index be8282a..bdc71f9 100644 --- a/Versionize.Tests/Changelog/ChangelogBuilderTests.cs +++ b/Versionize.Tests/Changelog/ChangelogBuilderTests.cs @@ -71,10 +71,20 @@ public void ShouldGenerateAChangelogForFixFeatAndBreakingCommits() }, ChangelogOptions.Default); - var wasChangelogWritten = File.Exists(Path.Join(_testDirectory, "CHANGELOG.md")); - Assert.True(wasChangelogWritten); + var changelogContents = File.ReadAllText(changelog.FilePath); - // TODO: Assert changelog entries + var sb = new ChangelogStringBuilder(); + sb.Append(ChangelogOptions.Preamble); + sb.Append(""); + sb.Append("## 1.1.0 (1-1-1)", 2); + sb.Append("### Features", 2); + sb.Append("* a breaking change feature"); + sb.Append("* a feature", 2); + sb.Append("### Bug Fixes", 2); + sb.Append("* a fix", 2); + sb.Append("### Breaking Changes", 2); + sb.Append("* a breaking change feature", 2); + Assert.Equal(sb.Build(), changelogContents); } [Fact] @@ -373,6 +383,36 @@ public void ShouldIncludeAllCommitsInChangelogWhenGiven() changelogContents.ShouldContain("some foo bar"); } + [Fact] + public void GenerateMarkdownShouldGenerateMarkdownForFixFeatAndBreakingCommits() + { + var plainLinkBuilder = new PlainLinkBuilder(); + string markdown = ChangelogBuilder.GenerateMarkdown( + new Version(1, 1, 0), + new DateTimeOffset(), + plainLinkBuilder, + new List + { + ConventionalCommitParser.Parse(new TestCommit("a360d6a307909c6e571b29d4a329fd786c5d4543", "fix: a fix")), + ConventionalCommitParser.Parse(new TestCommit("b360d6a307909c6e571b29d4a329fd786c5d4543", "feat: a feature")), + ConventionalCommitParser.Parse( + new TestCommit("c360d6a307909c6e571b29d4a329fd786c5d4543", "feat: a breaking change feature\nBREAKING CHANGE: this will break everything")), + }, + ChangelogOptions.Default); + + var sb = new ChangelogStringBuilder(); + sb.Append(""); + sb.Append("## 1.1.0 (1-1-1)", 2); + sb.Append("### Features", 2); + sb.Append("* a breaking change feature"); + sb.Append("* a feature", 2); + sb.Append("### Bug Fixes", 2); + sb.Append("* a fix", 2); + sb.Append("### Breaking Changes", 2); + sb.Append("* a breaking change feature", 2); + Assert.Equal(sb.Build(), markdown); + } + public void Dispose() { Cleanup.DeleteDirectory(_testDirectory); diff --git a/Versionize.Tests/TestSupport/ChangelogStringBuilder.cs b/Versionize.Tests/TestSupport/ChangelogStringBuilder.cs new file mode 100644 index 0000000..ac0ba71 --- /dev/null +++ b/Versionize.Tests/TestSupport/ChangelogStringBuilder.cs @@ -0,0 +1,21 @@ +using System.Text; + +namespace Versionize.Tests.TestSupport +{ + public class ChangelogStringBuilder + { + private readonly StringBuilder _sb = new(); + + public ChangelogStringBuilder Append(string text, int lineBreaks = 1) + { + _sb.Append(text); + for (int i = 0; i < lineBreaks; i++) + { + _sb.Append('\n'); + } + return this; + } + + public string Build() => _sb.ToString(); + } +} diff --git a/Versionize.Tests/WorkingCopyTests.cs b/Versionize.Tests/WorkingCopyTests.cs index 3d0d93a..4b9b7fe 100644 --- a/Versionize.Tests/WorkingCopyTests.cs +++ b/Versionize.Tests/WorkingCopyTests.cs @@ -49,21 +49,23 @@ public void ShouldExitIfWorkingCopyDoesNotExist() } [Fact] - public void ShouldPreformADryRun() + public void ShouldPerformADryRun() { TempCsProject.Create(_testSetup.WorkingDirectory); File.WriteAllText(Path.Join(_testSetup.WorkingDirectory, "hello.txt"), "First commit"); - CommitAll(_testSetup.Repository); - - File.WriteAllText(Path.Join(_testSetup.WorkingDirectory, "hello.txt"), "Second commit"); - CommitAll(_testSetup.Repository); + CommitAll(_testSetup.Repository, "feat: first commit"); var workingCopy = WorkingCopy.Discover(_testSetup.WorkingDirectory); workingCopy.Versionize(new VersionizeOptions { DryRun = true, SkipDirty = true }); - _testPlatformAbstractions.Messages.Count.ShouldBe(4); + _testPlatformAbstractions.Messages.Count.ShouldBe(7); _testPlatformAbstractions.Messages[0].Message.ShouldBe("Discovered 1 versionable projects"); + _testPlatformAbstractions.Messages[3].Message.ShouldBe("\n---"); + _testPlatformAbstractions.Messages[4].Message.ShouldContain("* first commit"); + _testPlatformAbstractions.Messages[5].Message.ShouldBe("---\n"); + var wasChangelogWritten = File.Exists(Path.Join(_testSetup.WorkingDirectory, "CHANGELOG.md")); + Assert.False(wasChangelogWritten); } [Fact] diff --git a/Versionize/Changelog/ChangelogBuilder.cs b/Versionize/Changelog/ChangelogBuilder.cs index d1685ac..7f07af4 100644 --- a/Versionize/Changelog/ChangelogBuilder.cs +++ b/Versionize/Changelog/ChangelogBuilder.cs @@ -22,6 +22,38 @@ private ChangelogBuilder(string file) IChangelogLinkBuilder linkBuilder, IEnumerable commits, ChangelogOptions changelogOptions) + { + string markdown = GenerateMarkdown(version, versionTime, linkBuilder, commits, changelogOptions); + + if (File.Exists(FilePath)) + { + var contents = File.ReadAllText(FilePath); + + var firstReleaseHeadlineIdx = contents.IndexOf("= 0) + { + markdown = contents.Insert(firstReleaseHeadlineIdx, markdown); + } + else + { + markdown = contents + "\n\n" + markdown; + } + + File.WriteAllText(FilePath, markdown); + } + else + { + File.WriteAllText(FilePath, changelogOptions.Header + "\n" + markdown); + } + } + + public static string GenerateMarkdown( + Version version, + DateTimeOffset versionTime, + IChangelogLinkBuilder linkBuilder, + IEnumerable commits, + ChangelogOptions changelogOptions) { var versionTagLink = string.IsNullOrWhiteSpace(linkBuilder.BuildVersionTagLink(version)) ? version.ToString() @@ -68,27 +100,7 @@ private ChangelogBuilder(string file) } } - if (File.Exists(FilePath)) - { - var contents = File.ReadAllText(FilePath); - - var firstReleaseHeadlineIdx = contents.IndexOf("= 0) - { - markdown = contents.Insert(firstReleaseHeadlineIdx, markdown); - } - else - { - markdown = contents + "\n\n" + markdown; - } - - File.WriteAllText(FilePath, markdown); - } - else - { - File.WriteAllText(FilePath, changelogOptions.Header + "\n" + markdown); - } + return markdown; } public static string BuildBlock(string header, IChangelogLinkBuilder linkBuilder, IEnumerable commits) diff --git a/Versionize/ChangelogOptions.cs b/Versionize/ChangelogOptions.cs index 6d69186..cb2f63a 100644 --- a/Versionize/ChangelogOptions.cs +++ b/Versionize/ChangelogOptions.cs @@ -6,7 +6,7 @@ namespace Versionize // TODO: Consider creating a ChangelogConfigurationContract as a layer of abstraction. public record class ChangelogOptions { - private const string Preamble = "# Change Log\n\nAll notable changes to this project will be documented in this file. See [versionize](https://github.com/saintedlama/versionize) for commit guidelines.\n"; + public const string Preamble = "# Change Log\n\nAll notable changes to this project will be documented in this file. See [versionize](https://github.com/saintedlama/versionize) for commit guidelines.\n"; public static readonly ChangelogOptions Default = new ChangelogOptions { Header = Preamble, diff --git a/Versionize/WorkingCopy.cs b/Versionize/WorkingCopy.cs index d300b44..9d9bb36 100644 --- a/Versionize/WorkingCopy.cs +++ b/Versionize/WorkingCopy.cs @@ -111,10 +111,17 @@ public Version Versionize(VersionizeOptions options) Step($"bumping version from {projects.Version} to {nextVersion} in projects"); var changelog = ChangelogBuilder.CreateForPath(workingDirectory); + var changelogLinkBuilder = LinkBuilderFactory.CreateFor(repo); - if (!options.DryRun) + if (options.DryRun) + { + string markdown = ChangelogBuilder.GenerateMarkdown(nextVersion, versionTime, changelogLinkBuilder, conventionalCommits, options.Changelog); + Information("\n---"); + Information(markdown.TrimEnd('\n')); + Information("---\n"); + } + else { - var changelogLinkBuilder = LinkBuilderFactory.CreateFor(repo); changelog.Write(nextVersion, versionTime, changelogLinkBuilder, conventionalCommits, options.Changelog); }