Skip to content

Commit 887e7c1

Browse files
committed
Parse references at end of changelog as separate part of a changelog.
1 parent 3f98e8d commit 887e7c1

File tree

1 file changed

+91
-10
lines changed

1 file changed

+91
-10
lines changed

src/app/Fake.Core.ReleaseNotes/Changelog.fs

Lines changed: 91 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,16 @@ module Changelog =
108108
| Security s -> sprintf "Security: %s" s.CleanedText
109109
| Custom (h, s) -> sprintf "%s: %s" h s.CleanedText
110110

111+
member x.ChangeText() =
112+
match x with
113+
| Added (changeText)
114+
| Changed (changeText)
115+
| Deprecated (changeText)
116+
| Removed (changeText)
117+
| Fixed (changeText)
118+
| Security (changeText)
119+
| Custom (_, changeText) -> changeText
120+
111121
/// Create a new change type changelog entry
112122
static member New(header: string, line: string) : Change =
113123
let text =
@@ -267,6 +277,32 @@ module Changelog =
267277

268278
assemblyVersion, nugetVersion
269279

280+
/// <summary>
281+
/// A version or "Unreleased"
282+
/// </summary>
283+
type ReferenceVersion =
284+
| SemVerRef of SemVerInfo
285+
| UnreleasedRef
286+
287+
override x.ToString() =
288+
match x with
289+
| SemVerRef (semVerInfo) -> semVerInfo.ToString()
290+
| UnreleasedRef -> "Unreleased"
291+
292+
/// <summary>
293+
/// A reference from a version to a repository URL (e.g. a tag or a compare link)
294+
/// </summary>
295+
/// <code>
296+
/// [Unreleased]: https://github.com/user/MyCoolNewLib.git/compare/v0.1.0...HEAD
297+
/// [0.1.0]: https://github.com/user/MyCoolNewLib.git/releases/tag/v0.1.0
298+
/// </code>
299+
type Reference =
300+
{ SemVer: ReferenceVersion
301+
RepoUrl: Uri }
302+
303+
override x.ToString() =
304+
sprintf "[%s]: %s" (x.SemVer.ToString()) (x.RepoUrl.ToString())
305+
270306
/// <summary>
271307
/// Holds data for a changelog file, which include changelog entries an other metadata
272308
/// </summary>
@@ -283,17 +319,21 @@ module Changelog =
283319

284320
/// The change log entries
285321
Entries: ChangelogEntry list
322+
323+
/// The references to repository URLs
324+
References: Reference list
286325
}
287326

288327
/// the latest change log entry
289328
member x.LatestEntry = x.Entries |> Seq.head
290329

291330
/// Create a new changelog record from given data
292-
static member New(header, description, unreleased, entries) =
331+
static member New(header, description, unreleased, entries, references) =
293332
{ Header = header
294333
Description = description
295334
Unreleased = unreleased
296-
Entries = entries }
335+
Entries = entries
336+
References = references }
297337

298338
/// Promote an unreleased changelog entry to a released one
299339
member x.PromoteUnreleased(assemblyVersion: string, nugetVersion: string) : Changelog =
@@ -311,7 +351,7 @@ module Changelog =
311351
)
312352

313353
let unreleased' = Some { Description = None; Changes = [] }
314-
Changelog.New(x.Header, x.Description, unreleased', newEntry :: x.Entries)
354+
Changelog.New(x.Header, x.Description, unreleased', newEntry :: x.Entries, x.References)
315355

316356
/// Promote an unreleased changelog entry to a released one using version number
317357
member x.PromoteUnreleased(version: string) : Changelog =
@@ -346,7 +386,10 @@ module Changelog =
346386
| "" -> "Changelog"
347387
| h -> h
348388

349-
(sprintf "# %s\n\n%s\n\n%s" header description entries)
389+
let references =
390+
x.References |> List.map (fun reference -> reference.ToString()) |> joinLines
391+
392+
(sprintf "# %s\n\n%s\n\n%s\n\n%s" header description entries references)
350393
|> fixMultipleNewlines
351394
|> String.trim
352395

@@ -358,8 +401,9 @@ module Changelog =
358401
/// <param name="description">the descriptive text for changelog</param>
359402
/// <param name="unreleased">the unreleased list of changelog entries</param>
360403
/// <param name="entries">the list of changelog entries</param>
361-
let createWithCustomHeader header description unreleased entries =
362-
Changelog.New(header, description, unreleased, entries)
404+
/// <param name="references">the list of references</param>
405+
let createWithCustomHeader header description unreleased entries references =
406+
Changelog.New(header, description, unreleased, entries, references)
363407

364408
/// <summary>
365409
/// Create a changelog with given data
@@ -368,16 +412,17 @@ module Changelog =
368412
/// <param name="description">the descriptive text for changelog </param>
369413
/// <param name="unreleased">the unreleased list of changelog entries</param>
370414
/// <param name="entries">the list of changelog entries</param>
371-
let create description unreleased entries =
372-
createWithCustomHeader "Changelog" description unreleased entries
415+
/// <param name="references">the list of references</param>
416+
let create description unreleased entries references =
417+
createWithCustomHeader "Changelog" description unreleased entries references
373418

374419
/// <summary>
375420
/// Create a changelog with given entries and default values for other data including
376421
/// header and description.
377422
/// </summary>
378423
///
379424
/// <param name="entries">the list of changelog entries</param>
380-
let fromEntries entries = create None None entries
425+
let fromEntries entries = create None None entries []
381426

382427
let internal isMainHeader line : bool = "# " <* line
383428
let internal isVersionHeader line : bool = "## " <* line
@@ -538,7 +583,43 @@ module Changelog =
538583
| h :: _ -> h
539584
| _ -> "Changelog"
540585

541-
Changelog.New(header, description, unreleased, entries)
586+
// Move references from last changelog entry into references.
587+
let entriesWithoutReferences, references =
588+
let referenceRegex =
589+
$"""^\[(({nugetRegex.ToString()})|Unreleased)\]: +(http[s]://.+)$"""
590+
|> String.getRegEx
591+
592+
match entries with
593+
| [] -> [], []
594+
| entries ->
595+
let front, lastChange = entries |> List.splitAt (List.length entries - 1)
596+
let last = List.head lastChange
597+
598+
let refChanges, trueChanges =
599+
last.Changes
600+
|> List.partition (fun (change: Change) ->
601+
referenceRegex.Match(change.ChangeText().CleanedText).Success)
602+
603+
let references =
604+
refChanges
605+
|> List.map (fun change ->
606+
let referenceMatch = referenceRegex.Match(change.ChangeText().CleanedText)
607+
let version = referenceMatch.Groups[1].Value
608+
let uri = referenceMatch.Groups[6].Value
609+
610+
{ SemVer =
611+
if version = "Unreleased" then
612+
UnreleasedRef
613+
else
614+
SemVerRef(SemVer.parse version)
615+
RepoUrl = Uri(uri) })
616+
617+
let newLastEntry =
618+
ChangelogEntry.New(last.AssemblyVersion, last.NuGetVersion, trueChanges)
619+
620+
front @ [ newLastEntry ], references
621+
622+
Changelog.New(header, description, unreleased, entriesWithoutReferences, references)
542623

543624
/// <summary>
544625
/// Parses a Changelog text file and returns the latest changelog.

0 commit comments

Comments
 (0)