diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index bb1a746..8dd0274 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -2,8 +2,8 @@ "version": 1, "isRoot": true, "tools": { - "fantomas-tool": { - "version": "4.6.0-beta-001", + "fantomas": { + "version": "6.3.0-alpha-003", "commands": [ "fantomas" ] diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..6d9c86f --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +root = true + +[*.{fs,fsi,fsx}] +end_of_line = lf +fsharp_keep_max_number_of_blank_lines = 1 +fsharp_multi_line_lambda_closing_newline = true +fsharp_alternative_long_member_definitions = true +fsharp_align_function_signature_to_indentation = true +fsharp_experimental_keep_indent_in_branch = true +fsharp_bar_before_discriminated_union_declaration = true +fsharp_multiline_bracket_style = aligned + +# Expecto looks a bit nicer with stroustrup +[test/**/*.fs] +fsharp_multiline_bracket_style = stroustrup diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..e3ca87a --- /dev/null +++ b/.gitattributes @@ -0,0 +1,7 @@ +# Automatically normalize line endings +* text=auto + +# Always use lf for F# files +*.fs text eol=lf +*.fsx text eol=lf +*.fsi text eol=lf \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..10e38e9 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,14 @@ +version: 2 +updates: + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + + - package-ecosystem: "nuget" + directory: "/" + schedule: + interval: "daily" + ignore: + - dependency-name: "FSharp.Core" diff --git a/.github/workflows/buildAndTest.yml b/.github/workflows/buildAndTest.yml index 7da9f06..0e2970b 100644 --- a/.github/workflows/buildAndTest.yml +++ b/.github/workflows/buildAndTest.yml @@ -12,6 +12,10 @@ jobs: - uses: actions/checkout@v2 - name: Setup .NET Core uses: actions/setup-dotnet@v4 + - name: Tool restore + run: dotnet tool restore + - name: Format Check + run: dotnet fantomas . --check || echo "The code was not formatted, run `dotnet fantomas .` to format all code." - name: Restore run: dotnet restore - name: Run Build diff --git a/Directory.Build.props b/Directory.Build.props index 86a0b40..8cc5816 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -6,6 +6,11 @@ version;changelog;keepachangelog true ionide.png + $(NoWarn);3186,0042 + $(NoWarn);NU1902 + $(WarnOn);1182 + $(WarnOn);3390 + true diff --git a/src/Ionide.KeepAChangelog.Tasks/Library.fs b/src/Ionide.KeepAChangelog.Tasks/Library.fs index 63f9382..e78d61a 100644 --- a/src/Ionide.KeepAChangelog.Tasks/Library.fs +++ b/src/Ionide.KeepAChangelog.Tasks/Library.fs @@ -24,8 +24,10 @@ module Util = item.SetMetadata("Removed", data.Removed) item.SetMetadata("Fixed", data.Fixed) item.SetMetadata("Security", data.Security) - for (KeyValue(heading, lines)) in data.Custom do + + for KeyValue(heading, lines) in data.Custom do item.SetMetadata(heading, lines) + item type ParseChangelogs() = @@ -41,7 +43,7 @@ type ParseChangelogs() = member val CurrentReleaseChangelog: ITaskItem = null with get, set [] - member val AllReleasedChangelogs: ITaskItem [] = null with get, set + member val AllReleasedChangelogs: ITaskItem array = null with get, set [] member val LatestReleaseNotes: string = null with get, set @@ -58,9 +60,8 @@ type ParseChangelogs() = changelogs.Unreleased |> Option.iter (fun unreleased -> this.UnreleasedChangelog <- - TaskItem() - |> Util.mapChangelogData unreleased - |> Util.mapUnreleasedInfo) + TaskItem() |> Util.mapChangelogData unreleased |> Util.mapUnreleasedInfo + ) let sortedReleases = // have to use LINQ here because List.sortBy* require IComparable, which @@ -72,7 +73,10 @@ type ParseChangelogs() = |> Seq.map (fun (version, date, data) -> TaskItem() |> Util.mapReleaseInfo version date - |> fun d -> match data with Some data -> Util.mapChangelogData data d | None -> d + |> fun d -> + match data with + | Some data -> Util.mapChangelogData data d + | None -> d ) |> Seq.toArray @@ -81,14 +85,12 @@ type ParseChangelogs() = sortedReleases |> Seq.tryHead - |> Option.iter (fun (version, date, data) -> - data - |> Option.iter (fun data -> - this.LatestReleaseNotes <- data.ToMarkdown()) - ) + |> Option.iter (fun (_version, _date, data) -> + data |> Option.iter (fun data -> this.LatestReleaseNotes <- data.ToMarkdown()) + ) true - | Error (formatted, msg) -> + | Error(formatted, msg) -> this.Log.LogError( $"Error parsing Changelog at {file.FullName}. The error occurred at {msg.Position}.{System.Environment.NewLine}{formatted}" diff --git a/src/Ionide.KeepAChangelog/Library.fs b/src/Ionide.KeepAChangelog/Library.fs index 420ae9c..2e9678a 100644 --- a/src/Ionide.KeepAChangelog/Library.fs +++ b/src/Ionide.KeepAChangelog/Library.fs @@ -9,23 +9,26 @@ module Domain = Added: string Changed: string Deprecated: string - Removed: string + Removed: string Fixed: string Security: string Custom: Map } + static member Default = - { Added = String.Empty - Changed = String.Empty - Deprecated = String.Empty - Removed = String.Empty - Fixed = String.Empty - Security = String.Empty - Custom = Map.empty } - - member this.ToMarkdown () = + { + Added = String.Empty + Changed = String.Empty + Deprecated = String.Empty + Removed = String.Empty + Fixed = String.Empty + Security = String.Empty + Custom = Map.empty + } + + member this.ToMarkdown() = let section name (body: string) = - $"### {name}%s{Environment.NewLine}%s{Environment.NewLine}%s{body}" + $"### {name}%s{Environment.NewLine}%s{Environment.NewLine}%s{body}" String.concat Environment.NewLine @@ -41,18 +44,16 @@ module Domain = ] type Changelogs = - { Unreleased: ChangelogData option - Releases: (SemanticVersion * DateTime * ChangelogData option) list } + { + Unreleased: ChangelogData option + Releases: (SemanticVersion * DateTime * ChangelogData option) list + } module Parser = - open Domain open FParsec - open FParsec.CharParsers - open FParsec.Primitives open System.IO - open System.Collections.Generic type Parser<'t> = Parser<'t, unit> @@ -98,19 +99,23 @@ module Parser = // but we also need to keep parsing next lines until // * we find a bullet, or // * we get an empty line - let firstLine = FParsec.CharParsers.restOfLine true + let firstLine = CharParsers.restOfLine true let followingLine = nextCharSatisfiesNot (fun c -> c = '\n' || c = '-' || c = '*') >>. spaces1 - >>. FParsec.CharParsers.restOfLine true + >>. CharParsers.restOfLine true let rest = opt (many1 (attempt followingLine)) - pipe2 firstLine rest (fun f rest -> - match rest with - | None -> f - | Some parts -> String.concat " " (f :: parts)) + pipe2 + firstLine + rest + (fun f rest -> + match rest with + | None -> f + | Some parts -> String.concat " " (f :: parts) + ) "line item" pipe2 bullet content (fun bullet text -> $"{bullet} {text}") @@ -118,26 +123,21 @@ module Parser = let pSectionBody sectionName : Parser = let nextHeader = (newline >>. regex @"[#]{1,3}\s\S" |>> ignore) let endOfSection = choice [ eof; nextHeader ] - manyTill anyChar (lookAhead endOfSection) - |>> System.String.Concat + + manyTill anyChar (lookAhead endOfSection) |>> System.String.Concat $"{sectionName} section body" - + let pCustomSection: Parser = let sectionName = - skipString "###" - >>. spaces1 - >>. restOfLine true // TODO: maybe not the whole line? - $"custom section header" - sectionName - .>> attempt (opt newline) - .>>. (pSectionBody sectionName) + skipString "###" >>. spaces1 >>. restOfLine true // TODO: maybe not the whole line? + "custom section header" + + sectionName .>> attempt (opt newline) .>>. (pSectionBody sectionName) .>> attempt (opt newline) let pSection sectionName : Parser = - ((skipString "###" - >>. spaces1 - >>. skipString sectionName) - $"{sectionName} section header") + ((skipString "###" >>. spaces1 >>. skipString sectionName) + $"{sectionName} section header") >>. many1 newline >>. pSectionBody sectionName .>> attempt (opt newline) @@ -149,35 +149,33 @@ module Parser = let pFixed = pSection "Fixed" let pSecurity = pSection "Security" let pOrEmptyList p = opt (attempt p) - let pSectionLessItems = - many1 pEntry - .>> attempt (opt newline) + let pSectionLessItems = many1 pEntry .>> attempt (opt newline) let pSections: Parser ChangelogData> = - choice [ - attempt (pAdded |>> fun x data -> { data with Added = x }) - attempt (pChanged |>> fun x data -> { data with Changed = x }) - attempt (pRemoved |>> fun x data -> { data with Removed = x }) - attempt (pDeprecated |>> fun x data -> { data with Deprecated = x }) - attempt (pFixed |>> fun x data -> { data with Fixed = x }) - attempt (pSecurity |>> fun x data -> { data with Security = x }) - attempt (many1 pCustomSection |>> fun x data -> { data with Custom = Map.ofList x }) - ] + choice + [ + attempt (pAdded |>> fun x data -> { data with Added = x }) + attempt (pChanged |>> fun x data -> { data with Changed = x }) + attempt (pRemoved |>> fun x data -> { data with Removed = x }) + attempt (pDeprecated |>> fun x data -> { data with Deprecated = x }) + attempt (pFixed |>> fun x data -> { data with Fixed = x }) + attempt (pSecurity |>> fun x data -> { data with Security = x }) + attempt (many1 pCustomSection |>> fun x data -> { data with Custom = Map.ofList x }) + ] let pData: Parser = - many1 pSections - |>> List.fold (fun x f -> f x) ChangelogData.Default + many1 pSections |>> List.fold (fun x f -> f x) ChangelogData.Default - let pNonStructuredData : Parser = + let pNonStructuredData: Parser = let nextHeader = (newline >>. regex @"[#]{1,2}\s\S" |>> ignore) let endOfSection = choice [ eof; nextHeader ] + (manyTill anyChar (lookAhead endOfSection) .>> attempt (opt newline)) |>> (fun _content -> ChangelogData.Default) "release body" let pHeader: Parser = - (skipString "# Changelog" >>. skipNewline - .>> skipTillStringOrEof "##") + (skipString "# Changelog" >>. skipNewline .>> skipTillStringOrEof "##") "Changelog header" let mdUrl inner = @@ -189,24 +187,25 @@ module Parser = let pUnreleased: Parser = let unreleased = skipString "Unreleased" - let name = attempt ( - skipString "##" - >>. spaces1 - >>. (mdUrl unreleased <|> unreleased) - .>> skipRestOfLine true - "Unreleased label" - ) - name >>. opt (many newline) >>. opt pData - "Unreleased version section" + let name = + attempt ( + skipString "##" >>. spaces1 >>. (mdUrl unreleased <|> unreleased) + .>> skipRestOfLine true + "Unreleased label" + ) + + name >>. opt (many newline) >>. opt pData "Unreleased version section" let validSemverChars = - [| for c in '0' .. '9' -> c - for c in 'A' .. 'Z' -> c - for c in 'a' .. 'z' -> c - yield '-' - yield '.' - yield '+' |] + [| + for c in '0' .. '9' -> c + for c in 'A' .. 'Z' -> c + for c in 'a' .. 'z' -> c + yield '-' + yield '.' + yield '+' + |] |> Set.ofArray let pSemver: Parser<_> = @@ -214,31 +213,22 @@ module Parser = |>> fun text -> SemVersion.SemanticVersion.Parse text let pDate: Parser<_> = - let pYear = - pint32 - |> attempt - + let pYear = pint32 |> attempt - let pMonth = - pint32 - |> attempt + let pMonth = pint32 |> attempt - let pDay = - pint32 - |> attempt + let pDay = pint32 |> attempt let ymdDashes = let dash = pchar '-' pipe5 pYear dash pMonth dash pDay (fun y _ m _ d -> System.DateTime(y, m, d)) - let dmyDots = let dot = pchar '.' pipe5 pDay dot pMonth dot pYear (fun d _ m _ y -> System.DateTime(y, m, d)) attempt dmyDots <|> ymdDashes - let pVersion = mdUrl pSemver <|> pSemver let pRelease: Parser = @@ -252,18 +242,22 @@ module Parser = let pChangeLogs: Parser = let unreleased = pUnreleased - |>> fun unreleased -> - match unreleased with - | None -> None - | Some u when u = ChangelogData.Default -> None - | Some unreleased -> Some unreleased + |>> fun unreleased -> + match unreleased with + | None -> None + | Some u when u = ChangelogData.Default -> None + | Some unreleased -> Some unreleased + pipe3 pHeader (attempt (opt unreleased)) (attempt (many pRelease)) (fun _header unreleased releases -> - { Unreleased = defaultArg unreleased None - Releases = releases }) + { + Unreleased = defaultArg unreleased None + Releases = releases + } + ) let parseChangeLog (file: FileInfo) = match @@ -272,6 +266,6 @@ module Parser = () file.FullName (System.Text.UTF8Encoding(encoderShouldEmitUTF8Identifier = false)) - with - | ParserResult.Success (result, _, pos) -> Result.Ok result - | ParserResult.Failure (msg, structuredError, pos) -> Result.Error(msg, structuredError) + with + | ParserResult.Success(result, _, _pos) -> Result.Ok result + | ParserResult.Failure(msg, structuredError, _pos) -> Result.Error(msg, structuredError) diff --git a/test/Ionide.KeepAChangelog.Test/Program.fs b/test/Ionide.KeepAChangelog.Test/Program.fs index 01b4e45..20e41b7 100644 --- a/test/Ionide.KeepAChangelog.Test/Program.fs +++ b/test/Ionide.KeepAChangelog.Test/Program.fs @@ -5,10 +5,11 @@ open SemVersion open Expecto open Ionide.KeepAChangelog.Domain -let normalizeNewline (v:string) = v.Replace("\r", "") +let normalizeNewline (v: string) = v.Replace("\r", "") let singleRelease = - normalizeNewline """## [1.0.0] - 2017-06-20 + normalizeNewline + """## [1.0.0] - 2017-06-20 ### Added - A @@ -20,15 +21,18 @@ let singleRelease = """ let singleReleaseExpected = - (SemanticVersion.Parse "1.0.0", DateTime(2017, 06, 20), Some { - ChangelogData.Default with - Added = "- A\n" - Changed = "- B\n" - Removed = "- C\n" - }) + (SemanticVersion.Parse "1.0.0", + DateTime(2017, 06, 20), + Some { + ChangelogData.Default with + Added = "- A\n" + Changed = "- B\n" + Removed = "- C\n" + }) let keepAChangelog = - normalizeNewline """# Changelog + normalizeNewline + """# 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/), @@ -54,22 +58,22 @@ 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\n- B\n- C\n\n" - } - ] - } +let keepAChangelogExpected: Changelogs = { + Unreleased = None + Releases = [ + singleReleaseExpected + SemanticVersion.Parse("0.3.0"), + DateTime(2015, 12, 03), + Some { + ChangelogData.Default with + Added = "- A\n- B\n- C\n\n" + } + ] +} let header = - normalizeNewline """# Changelog + normalizeNewline + """# 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/), @@ -78,7 +82,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 """ let emptyUnreleased = - normalizeNewline """## [Unreleased] + normalizeNewline + """## [Unreleased] """ @@ -87,7 +92,9 @@ let headerAndUnreleased = header + emptyUnreleased let headerAndUnreleasedAndRelease = header + emptyUnreleased + singleRelease let headerAndUnreleasedAndReleaseExpected = None, singleReleaseExpected -let sample1Release = normalizeNewline """## [0.3.1] - 8.1.2022 +let sample1Release = + normalizeNewline + """## [0.3.1] - 8.1.2022 ### Added @@ -96,9 +103,16 @@ let sample1Release = normalizeNewline """## [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\n\n" } + SemanticVersion.Parse "0.3.1", + DateTime(2022, 1, 8), + Some { + ChangelogData.Default with + Added = "- Add XmlDocs to the generated package\n\n" + } -let sample = normalizeNewline """# Changelog +let sample = + normalizeNewline + """# 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/), @@ -135,7 +149,10 @@ let sampleExpected: Changelogs = { Releases = [ SemanticVersion.Parse "0.3.1", DateTime(2022, 1, 8), - Some { ChangelogData.Default with Added = "* Add XmlDocs to the generated package\n" } + Some { + ChangelogData.Default with + Added = "* Add XmlDocs to the generated package\n" + } SemanticVersion.Parse "0.3.0", DateTime(2021, 11, 23), @@ -145,78 +162,80 @@ let sampleExpected: Changelogs = { normalizeNewline """* 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)\n" } - + Some { + ChangelogData.Default with + Added = "* Add support for `codeAction/resolve` (by @razzmatazz)\n" + } + SemanticVersion.Parse "0.1.1", DateTime(2021, 11, 15), - Some { ChangelogData.Default with Added = "* Initial implementation\n" } + Some { + ChangelogData.Default with + Added = "* Initial implementation\n" + } ] } open FParsec -open FParsec.Primitives 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 + match CharParsers.run p text with + | CharParsers.Success(r, _, _) -> Expect.equal r expected "Should have produced expected value" + | CharParsers.Failure(m, _, _) -> failwithf "%A" m } -let runSuccessNormalized label (p: Parser) text (expected:string) = +let runSuccessNormalized label (p: Parser) text (expected: string) = test $"parsing {label}" { - match FParsec.CharParsers.run p text with - | FParsec.CharParsers.Success (r, _, _) -> + match CharParsers.run p text with + | CharParsers.Success(r, _, _) -> let normalizedR = r.Replace("\r", "") let normalizedExpected = expected.Replace("\r", "") Expect.equal normalizedR normalizedExpected "Should have produced expected value" - | FParsec.CharParsers.Failure (m, _, _) -> - failwithf "%A" m + | CharParsers.Failure(m, _, _) -> failwithf "%A" m } -let parsingExamples = 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 parsingExamples = + 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 changelogDataTest = test "Transform ChangelogData to Markdown" { - let changelogData = - { - Added = "* Added line 1\n* Added line 2\n" - Changed = "* Changed line 1\n* Changed line 2\n" - Deprecated = "* Deprecated line 1\n* Deprecated line 2\n" - Removed = "* Removed line 1\n* Removed line 2\n" - Fixed = "* Fixed line 1\n* Fixed line 2\n" - Security = "* Security line 1\n* Security line 2\n" - Custom = - [ - "CustomHeaderA", "* Custom line 1\n* Custom line 2\n" - "CustomHeaderB", "* Custom line 3\n* Custom line 4\n" - ] - |> Map.ofList - } + let changelogData = { + Added = "* Added line 1\n* Added line 2\n" + Changed = "* Changed line 1\n* Changed line 2\n" + Deprecated = "* Deprecated line 1\n* Deprecated line 2\n" + Removed = "* Removed line 1\n* Removed line 2\n" + Fixed = "* Fixed line 1\n* Fixed line 2\n" + Security = "* Security line 1\n* Security line 2\n" + Custom = + [ + "CustomHeaderA", "* Custom line 1\n* Custom line 2\n" + "CustomHeaderB", "* Custom line 3\n* Custom line 4\n" + ] + |> Map.ofList + } let expected = - normalizeNewline """### Added + normalizeNewline + """### Added * Added line 1 * Added line 2 @@ -258,9 +277,10 @@ let changelogDataTest = """ Expect.equal (normalizeNewline (changelogData.ToMarkdown())) expected "Should have produced expected value" -} + } -let FableSample = """# Changelog +let FableSample = + """# 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/), @@ -312,12 +332,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * PR #3608: Rewrite `time_span.py` allowing for better precision by using a number representation intead of native `timedelta`. (by @MangelMaxime) """ -let FableSampleExpected :Changelogs = { - Unreleased = Some { - ChangelogData.Default with - Fixed = - normalizeNewline - """#### Python +let FableSampleExpected: Changelogs = { + Unreleased = + Some { + ChangelogData.Default with + Fixed = + normalizeNewline + """#### Python * Fix #3617: Fix comparaison between list option when one is None * Fix #3615: Fix remove from dictionary with tuple as key @@ -326,19 +347,21 @@ let FableSampleExpected :Changelogs = { * Fix #3610: Cleanup Python regex handling * Fix #3628: System.DateTime.Substract not correctly transpiled """ - } + } Releases = [ SemanticVersion.Parse "4.6.0", DateTime(2023, 11, 27), Some { ChangelogData.Default with Changed = - normalizeNewline """#### All + normalizeNewline + """#### All * Updated .NET metadata to 8.0.100 (by @ncave) """ Added = - normalizeNewline """#### All + normalizeNewline + """#### All * Fix #3584: Unit type compiles to undeclared variable (by @ncave) @@ -351,7 +374,8 @@ let FableSampleExpected :Changelogs = { * Added `Guid.TryParse`, `Guid.ToByteArray` (by @ncave) """ Fixed = - normalizeNewline """#### Python + normalizeNewline + """#### Python * Fixed char to string type regression with binary operator (by @dbrattli) * Fix `DateTime(..., DateTimeKind.Local).ToString("O")` (by @MangelMaxime) @@ -363,7 +387,9 @@ let FableSampleExpected :Changelogs = { ] } -let SectionLessSample = normalizeNewlines """# Changelog +let SectionLessSample = + normalizeNewlines + """# Changelog ## 4.2.1 - 2023-09-29 @@ -382,26 +408,19 @@ let SectionLessSample = normalizeNewlines """# Changelog let SectionLessSampleExpected: Changelogs = { Unreleased = None Releases = [ - SemanticVersion.Parse "4.2.1", - DateTime(2023, 9, 29), - Some ChangelogData.Default - SemanticVersion.Parse "4.2.0", - DateTime(2023, 9, 29), - Some ChangelogData.Default - ] + SemanticVersion.Parse "4.2.1", DateTime(2023, 9, 29), Some ChangelogData.Default + SemanticVersion.Parse "4.2.0", DateTime(2023, 9, 29), Some ChangelogData.Default + ] } -let fableTests = testList "Fable" [ - runSuccess "Multiple languages" Parser.pChangeLogs FableSample FableSampleExpected - runSuccess "SectionLess items" Parser.pChangeLogs SectionLessSample SectionLessSampleExpected -] +let fableTests = + testList "Fable" [ + runSuccess "Multiple languages" Parser.pChangeLogs FableSample FableSampleExpected + runSuccess "SectionLess items" Parser.pChangeLogs SectionLessSample SectionLessSampleExpected + ] [] -let tests = testList "All" [ - parsingExamples - changelogDataTest - fableTests -] +let tests = testList "All" [ parsingExamples; changelogDataTest; fableTests ] [] let main argv =