public/Get-ChangelogData.ps1
function Get-ChangelogData { <# .SYNOPSIS Takes a changelog in Keep a Changelog 1.0.0 format and parses the data into a PowerShell object. .DESCRIPTION Takes a changelog in Keep a Changelog 1.0.0 format and parses the data into a PowerShell object. .INPUTS This cmdlet does not accept pipeline input. .OUTPUTS This cmdlet outputs a PSCustomObject containing the changelog data. .EXAMPLE Get-ChangelogData Returns an object containing Header, Unreleased, Released, Footer, and LastVersion properties. .LINK https://github.com/natescherer/ChangelogManagement #> [CmdletBinding()] param ( [parameter(Mandatory = $false)] [ValidateScript( { Test-Path -Path $_ })] # Path to the changelog; defaults to ".\CHANGELOG.md" [string]$Path = "CHANGELOG.md" ) $NL = [System.Environment]::NewLine if ((Get-Content -Path $Path -Raw) -like "*`r`n*") { $FileNewline = "`r`n" } else { $FileNewline = "`n" } $ChangeTypes = @("Added", "Changed", "Deprecated", "Removed", "Fixed", "Security") $ChangelogData = Get-Content -Path $Path -Raw $Output = [PSCustomObject]@{ "Header" = "" "Unreleased" = [PSCustomObject]@{ } "Released" = @() "Footer" = "" "LastVersion" = "" "ReleaseNotes" = "" } # Split changelog into $Sections and split header and footer into their own variables [System.Collections.ArrayList]$Sections = $ChangelogData -split "## \[" $Output.Header = $Sections[0] $Sections.Remove($Output.Header) if ($Sections[-1] -match ".*\[Unreleased\]:.*") { $Output.Footer = "[Unreleased]:" + ($Sections[-1] -split "\[Unreleased\]:")[1] $Sections[-1] = ($Sections[-1] -split "\[Unreleased\]:")[0] } # Restore the leading "## [" onto each section that was previously removed by split function, and trim extra # line breaks $i = 1 while ($i -le $Sections.Count) { $Sections[$i - 1] = "## [" + $Sections[$i - 1] $i++ } # If found, split the Unreleased section into $UnreleasedTemp, then remove it from $Sections if ($Sections[0] -match "## \[Unreleased\].*") { $UnreleasedTemp = $Sections[0] $Sections.Remove($UnreleasedTemp) } else { $UnreleasedTemp = $null } if ($UnreleasedTemp) { # Construct the $Output.Unreleased object foreach ($ChangeType in $ChangeTypes) { if ($UnreleasedTemp -notlike "*### $ChangeType*") { Set-Variable -Name "Unreleased$ChangeType" -Value $null } else { $Value = (($UnreleasedTemp -split "### $ChangeType$FileNewline")[1] -split "###")[0].TrimEnd($FileNewline) -split $FileNewline | ForEach-Object { $_.TrimStart("- ") } Set-Variable -Name "Unreleased$ChangeType" -Value $Value } } $Output.Unreleased = [PSCustomObject]@{ "RawData" = $UnreleasedTemp "Link" = (($Output.Footer -split "Unreleased\]: ")[1] -split $FileNewline)[0] "Data" = [PSCustomObject]@{ Added = $UnreleasedAdded Changed = $UnreleasedChanged Deprecated = $UnreleasedDeprecated Removed = $UnreleasedRemoved Fixed = $UnreleasedFixed Security = $UnreleasedSecurity } "ChangeCount" = $UnreleasedAdded.Count + $UnreleasedChanged.Count + $UnreleasedDeprecated.Count + $UnreleasedRemoved.Count + $UnreleasedFixed.Count + $UnreleasedSecurity.Count } } else { $Output.Unreleased = $null } # Construct the $Output.Released array foreach ($Release in $Sections) { foreach ($ChangeType in $ChangeTypes) { if ($Release -notlike "*### $ChangeType*") { Set-Variable -Name "Release$ChangeType" -Value $null } else { $Value = (($Release -split "### $ChangeType$FileNewline")[1] -split "###")[0].TrimEnd($FileNewline) -split $FileNewline | ForEach-Object { $_.TrimStart("- ") } Set-Variable -Name "Release$ChangeType" -Value $Value } } $LoopVersionNumber = $Release.Split("[")[1].Split("]")[0] $Output.Released += [PSCustomObject]@{ "RawData" = $Release "Date" = Get-Date ($Release -split "\] \- ")[1].Split($FileNewline)[0] "Version" = $LoopVersionNumber "Link" = (($Output.Footer -split "$LoopVersionNumber\]: ")[1] -split $FileNewline)[0] "Data" = [PSCustomObject]@{ Added = $ReleaseAdded Changed = $ReleaseChanged Deprecated = $ReleaseDeprecated Removed = $ReleaseRemoved Fixed = $ReleaseFixed Security = $ReleaseSecurity } "ChangeCount" = $ReleaseAdded.Count + $ReleaseChanged.Count + $ReleaseDeprecated.Count + $ReleaseRemoved.Count + $ReleaseFixed.Count + $ReleaseSecurity.Count } } # Set $Output.LastVersion to the version number of the latest release listed in the changelog, or null if there # have not been any releases yet if ($Output.Released[0].Version) { $Output.LastVersion = $Output.Released[0].Version } else { $Output.LastVersion = $null } if ($Output.Released[0]) { $Output.ReleaseNotes = ($Output.Released[0].RawData -replace "^## .*", "").Trim() } else { $Output.ReleaseNotes = $null } $Output } |