diff --git a/README.md b/README.md index e316510..b4d0bbb 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ It might be helpful to see how this library can help you. Imagine you have a pr and a CHANGELOG.md file like this: ```md -# Changelog +# Changelog ## 1.0.0 - 2022-01-14 @@ -71,18 +71,25 @@ If your changelog has multiple versions, the latest one will be used. There's really only one property that matters for these targets, and that's `ChangelogFile`. This needs to point to the Changelog file you want to read, but it defaults to `CHANGELOG.md` in the root of a given project in case you want to adhere to defaults. +| Property | Type | Default Value | Description | +| - | - | - | - | +| ChangelogFile | string | CHANGELOG.md | Points to the changelog file to parse. Note that the default value is set to the _project_ root by default, so a repository-wide changelog would require this property be set to a different value, for example in a Directory.Build.props file | +| GenerateAssemblyBuildDateAttribute | boolean | true | If set, an assembly metadata attribute named "BuildDate" will be generated with the date (YYYY-MM-DD) of the parsed release. | +| GenerateVersionForUnreleasedChanges | boolean | true | If set, the assembly/package version and release notes will be set from Unreleased changes, if any are present. | + ## API When the task runs, it writes several output items and properties: |Name|Type|Description| |----|----|-----------| -| UnreleasedChangelog | UnreleasedChangelogData option | If present, there was an 'Unreleased' section in the Changelog. This structure will contain the sections present. | +| UnreleasedChangelog | ReleaseChangelogData option | If present, there was an 'Unreleased' section in the Changelog. This structure will contain the sections present, as well as an auto-incremented version number for this release. | +| UnreleasedReleaseNotes | string option | If present, contains the concatenated list of all Changelog sections for the Unreleased section of the Changelog. This is a convenience property so that you don't have to String.Join all the lines in the `ReleaseChangelogData` structure yourself! | | CurrentReleaseChangelog | ReleaseChangelogData option | If present, there was at least one released logged in the Changelog. This structure will contain the details of each one. | | AllReleasedChangelogs | ReleaseChangelogData list | Contains the ordered list of all released in the ChangelogFile, descending. | -| LatestReleaseNotes | string option | If present, contains the concatenated list of all Changelog sections for the latest release. This is a convenience property so that you don't have to String.Join all the lines in the `ReleaseChangelogData` yourself! | +| LatestReleaseNotes | string option | If present, contains the concatenated list of all Changelog sections for the latest release. This is a convenience property so that you don't have to String.Join all the lines in the `ReleaseChangelogData` structure yourself! | -### ChangelogData +### ReleaseChangelogData This TaskItem has metadata for each of the known sections of a Changelog: @@ -95,13 +102,6 @@ This TaskItem has metadata for each of the known sections of a Changelog: In each case, the value of the metadata is the newline-concatenated list of all of the Changelog Entries for that section. -### UnreleasedChangelogData - -This structure is a `ChangelogData` with an `Identity` of `"Unreleased"`. - -### ReleaseChangelogData - -This structure is the same as `ChangelogData`, but it contains two more items of metadata: - +In addition, * the `Identity` of the `TaskItem` is the Semantic Version of the release * the `Date` of the `TaskItem` is the `YYYY-MM-DD`-formatted date of the release \ No newline at end of file diff --git a/test/Ionide.KeepAChangelog.Test/Program.fs b/test/Ionide.KeepAChangelog.Test/Program.fs index 47cc4e5..c15c7f1 100644 --- a/test/Ionide.KeepAChangelog.Test/Program.fs +++ b/test/Ionide.KeepAChangelog.Test/Program.fs @@ -18,13 +18,14 @@ let singleRelease = """ -let singleReleaseExpected = - (SemanticVersion.Parse "1.0.0", DateTime(2017, 06, 20), Some { - ChangelogData.Default with - Added = ["- A"] - Changed = ["- B"] - Removed = ["- C"] - }) +let singleReleaseExpected = + (SemanticVersion.Parse "1.0.0", + DateTime(2017, 6, 20), + Some + { ChangelogData.Default with + Added = [ "- A" ] + Changed = [ "- B" ] + Removed = [ "- C" ] }) let keepAChangelog = """# Changelog @@ -53,14 +54,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 """ -let keepAChangelogExpected: Changelogs = - { - Unreleased = None - Releases = [ - singleReleaseExpected - SemanticVersion.Parse("0.3.0"), DateTime(2015, 12, 03), Some { ChangelogData.Default with Added = ["- A";"- B";"- C"]} - ] - } +let keepAChangelogExpected: Changelogs = + { Unreleased = None + Releases = + [ singleReleaseExpected + SemanticVersion.Parse("0.3.0"), + DateTime(2015, 12, 3), + Some { ChangelogData.Default with Added = [ "- A"; "- B"; "- C" ] } ] } let header = """# Changelog @@ -81,7 +81,8 @@ let headerAndUnreleased = header + emptyUnreleased let headerAndUnreleasedAndRelease = header + emptyUnreleased + singleRelease let headerAndUnreleasedAndReleaseExpected = None, singleReleaseExpected -let sample1Release = """## [0.3.1] - 8.1.2022 +let sample1Release = + """## [0.3.1] - 8.1.2022 ### Added @@ -89,10 +90,13 @@ let sample1Release = """## [0.3.1] - 8.1.2022 """ -let sample1ReleaseExpected = - SemanticVersion.Parse "0.3.1", DateTime(2022, 1, 8), Some { ChangelogData.Default with Added = ["- Add XmlDocs to the generated package"] } +let sample1ReleaseExpected = + SemanticVersion.Parse "0.3.1", + DateTime(2022, 1, 8), + Some { ChangelogData.Default with Added = [ "- Add XmlDocs to the generated package" ] } -let sample = """# Changelog +let sample = + """# Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), @@ -124,15 +128,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Initial implementation """ -let sampleExpected: Changelogs = { - Unreleased = None - Releases = [ - SemanticVersion.Parse "0.3.1", DateTime(2022, 1, 8), Some { ChangelogData.Default with Added = ["* Add XmlDocs to the generated package"] } - SemanticVersion.Parse "0.3.0", DateTime(2021, 11, 23), Some { ChangelogData.Default with Added = ["* Expose client `CodeAction` caps as CodeActionClientCapabilities. (by @razzmatazz)"; "* Map CodeAction.IsPreferred & CodeAction.Disabled props. (by @razzmatazz)"] } - SemanticVersion.Parse "0.2.0", DateTime(2021, 11, 17), Some { ChangelogData.Default with Added = ["* Add support for `codeAction/resolve` (by @razzmatazz)"] } - SemanticVersion.Parse "0.1.1", DateTime(2021, 11, 15), Some { ChangelogData.Default with Added = ["* Initial implementation"] } - ] -} +let sampleExpected: Changelogs = + { Unreleased = None + Releases = + [ SemanticVersion.Parse "0.3.1", + DateTime(2022, 1, 8), + Some { ChangelogData.Default with Added = [ "* Add XmlDocs to the generated package" ] } + SemanticVersion.Parse "0.3.0", + DateTime(2021, 11, 23), + Some + { ChangelogData.Default with + Added = + [ "* Expose client `CodeAction` caps as CodeActionClientCapabilities. (by @razzmatazz)" + "* Map CodeAction.IsPreferred & CodeAction.Disabled props. (by @razzmatazz)" ] } + SemanticVersion.Parse "0.2.0", + DateTime(2021, 11, 17), + Some { ChangelogData.Default with Added = [ "* Add support for `codeAction/resolve` (by @razzmatazz)" ] } + SemanticVersion.Parse "0.1.1", + DateTime(2021, 11, 15), + Some { ChangelogData.Default with Added = [ "* Initial implementation" ] } ] } open FParsec open FParsec.Primitives @@ -141,32 +155,31 @@ let runSuccess label p text expected = test $"parsing {label}" { match FParsec.CharParsers.run p text with - | FParsec.CharParsers.Success (r, _, _) -> - Expect.equal r expected "Should have produced expected value" - | FParsec.CharParsers.Failure (m, _, _) -> - failwithf "%A" m + | FParsec.CharParsers.Success (r, _, _) -> Expect.equal r expected "Should have produced expected value" + | FParsec.CharParsers.Failure (m, _, _) -> failwithf "%A" m } [] -let tests = testList "parsing examples" [ - runSuccess "line entry" Parser.pEntry "- A" "- A" - runSuccess "header" Parser.pHeader header () - runSuccess "unreleased" Parser.pUnreleased emptyUnreleased None - runSuccess "header and unreleased" (Parser.pHeader >>. Parser.pUnreleased) headerAndUnreleased None - runSuccess "release" Parser.pRelease singleRelease singleReleaseExpected - runSuccess "sample 1 release" Parser.pRelease sample1Release sample1ReleaseExpected - runSuccess - "header and unreleased and released" - (Parser.pHeader >>. Parser.pUnreleased - .>>. Parser.pRelease) - headerAndUnreleasedAndRelease - headerAndUnreleasedAndReleaseExpected - - runSuccess "keepachangelog" Parser.pChangeLogs keepAChangelog keepAChangelogExpected - - runSuccess "lsp changelog" Parser.pChangeLogs sample sampleExpected -] +let tests = + testList + "parsing examples" + [ runSuccess "line entry" Parser.pEntry "- A" "- A" + runSuccess "header" Parser.pHeader header () + runSuccess "unreleased" Parser.pUnreleased emptyUnreleased None + runSuccess "header and unreleased" (Parser.pHeader >>. Parser.pUnreleased) headerAndUnreleased None + runSuccess "release" Parser.pRelease singleRelease singleReleaseExpected + runSuccess "sample 1 release" Parser.pRelease sample1Release sample1ReleaseExpected + runSuccess + "header and unreleased and released" + (Parser.pHeader >>. Parser.pUnreleased + .>>. Parser.pRelease) + headerAndUnreleasedAndRelease + headerAndUnreleasedAndReleaseExpected + + runSuccess "keepachangelog" Parser.pChangeLogs keepAChangelog keepAChangelogExpected + + runSuccess "lsp changelog" Parser.pChangeLogs sample sampleExpected ] [] -let main argv = - runTestsWithCLIArgs Seq.empty argv tests \ No newline at end of file +let main argv = + runTestsWithCLIArgs Seq.empty argv tests