Sync eng/common directory with azure-sdk-tools for PR 13097 (#6849)
* Add New-ChangelogContent and Set-ChangeLogEntryContent functions with tests Co-authored-by: haolingdong-msft <87355844+haolingdong-msft@users.noreply.github.com> * Fix string interpolation pattern for consistency Co-authored-by: haolingdong-msft <87355844+haolingdong-msft@users.noreply.github.com> * Refactor regex into shared helper and add .Trim() for consistency Co-authored-by: weshaggard <9010698+weshaggard@users.noreply.github.com> * Rename New-ChangelogContent to Parse-ChangelogContent Co-authored-by: weshaggard <9010698+weshaggard@users.noreply.github.com> * Update Remove-EmptySections to use Get-SectionHeaderRegex helper Co-authored-by: weshaggard <9010698+weshaggard@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: haolingdong-msft <87355844+haolingdong-msft@users.noreply.github.com> Co-authored-by: weshaggard <9010698+weshaggard@users.noreply.github.com>
This commit is contained in:
parent
e70a8a79c2
commit
512b4e31d2
@ -8,6 +8,15 @@ $CHANGELOG_UNRELEASED_STATUS = "(Unreleased)"
|
||||
$CHANGELOG_DATE_FORMAT = "yyyy-MM-dd"
|
||||
$RecommendedSectionHeaders = @("Features Added", "Breaking Changes", "Bugs Fixed", "Other Changes")
|
||||
|
||||
# Helper function to build the section header regex pattern
|
||||
function Get-SectionHeaderRegex {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$InitialAtxHeader
|
||||
)
|
||||
return "^${InitialAtxHeader}${SECTION_HEADER_REGEX_SUFFIX}"
|
||||
}
|
||||
|
||||
# Returns a Collection of changeLogEntry object containing changelog info for all versions present in the gived CHANGELOG
|
||||
function Get-ChangeLogEntries {
|
||||
param (
|
||||
@ -49,7 +58,7 @@ function Get-ChangeLogEntriesFromContent {
|
||||
$initialAtxHeader = $matches["HeaderLevel"]
|
||||
}
|
||||
|
||||
$sectionHeaderRegex = "^${initialAtxHeader}${SECTION_HEADER_REGEX_SUFFIX}"
|
||||
$sectionHeaderRegex = Get-SectionHeaderRegex -InitialAtxHeader $initialAtxHeader
|
||||
$changeLogEntries | Add-Member -NotePropertyName "InitialAtxHeader" -NotePropertyValue $initialAtxHeader
|
||||
$releaseTitleAtxHeader = $initialAtxHeader + "#"
|
||||
$headerLines = @()
|
||||
@ -301,7 +310,7 @@ function Remove-EmptySections {
|
||||
$InitialAtxHeader = "#"
|
||||
)
|
||||
|
||||
$sectionHeaderRegex = "^${InitialAtxHeader}${SECTION_HEADER_REGEX_SUFFIX}"
|
||||
$sectionHeaderRegex = Get-SectionHeaderRegex -InitialAtxHeader $InitialAtxHeader
|
||||
$releaseContent = $ChangeLogEntry.ReleaseContent
|
||||
|
||||
if ($releaseContent.Count -gt 0)
|
||||
@ -460,3 +469,135 @@ function Confirm-ChangeLogForRelease {
|
||||
}
|
||||
return $ChangeLogStatus.IsValid
|
||||
}
|
||||
|
||||
function Parse-ChangelogContent {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Parses raw changelog text into structured content with sections.
|
||||
|
||||
.DESCRIPTION
|
||||
Takes raw changelog text and parses it into structured arrays containing
|
||||
ReleaseContent (all lines) and Sections (organized by section headers).
|
||||
This function only generates content structure without modifying any files.
|
||||
|
||||
.PARAMETER ChangelogText
|
||||
The new changelog text containing sections (e.g., "### Breaking Changes", "### Features Added").
|
||||
|
||||
.PARAMETER InitialAtxHeader
|
||||
The markdown header level used in the changelog (e.g., "#" for H1, "##" for H2).
|
||||
Defaults to "#".
|
||||
|
||||
.OUTPUTS
|
||||
PSCustomObject with ReleaseContent and Sections properties.
|
||||
|
||||
.EXAMPLE
|
||||
$content = Parse-ChangelogContent -ChangelogText $changelogText -InitialAtxHeader "#"
|
||||
$content.ReleaseContent # Array of all lines
|
||||
$content.Sections # Hashtable of section name to content lines
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[string]$ChangelogText,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[string]$InitialAtxHeader = "#"
|
||||
)
|
||||
|
||||
Write-Verbose "Parsing changelog text into structured content..."
|
||||
|
||||
# Parse the new changelog content into lines
|
||||
$changelogLines = $ChangelogText -split "`r?`n"
|
||||
|
||||
# Initialize content structure
|
||||
$releaseContent = @()
|
||||
$sections = @{}
|
||||
|
||||
# Add an empty line after the version header
|
||||
$releaseContent += ""
|
||||
|
||||
# Parse the changelog content
|
||||
# InitialAtxHeader represents the markdown header level (e.g., "#" for H1, "##" for H2)
|
||||
# Section headers are two levels deeper than the changelog title
|
||||
# (e.g., "### Breaking Changes" if InitialAtxHeader is "#")
|
||||
$currentSection = $null
|
||||
$sectionHeaderRegex = Get-SectionHeaderRegex -InitialAtxHeader $InitialAtxHeader
|
||||
|
||||
foreach ($line in $changelogLines) {
|
||||
if ($line.Trim() -match $sectionHeaderRegex) {
|
||||
$currentSection = $matches["sectionName"].Trim()
|
||||
$sections[$currentSection] = @()
|
||||
$releaseContent += $line
|
||||
Write-Verbose " Found section: $currentSection"
|
||||
}
|
||||
elseif ($currentSection) {
|
||||
$sections[$currentSection] += $line
|
||||
$releaseContent += $line
|
||||
}
|
||||
else {
|
||||
$releaseContent += $line
|
||||
}
|
||||
}
|
||||
|
||||
Write-Verbose " Parsed $($sections.Count) section(s)"
|
||||
|
||||
# Return structured content
|
||||
return [PSCustomObject]@{
|
||||
ReleaseContent = $releaseContent
|
||||
Sections = $sections
|
||||
}
|
||||
}
|
||||
|
||||
function Set-ChangeLogEntryContent {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Updates a changelog entry with new content.
|
||||
|
||||
.DESCRIPTION
|
||||
Takes a changelog entry object and new changelog text, parses the text into
|
||||
structured content, and updates the entry's ReleaseContent and Sections properties.
|
||||
|
||||
.PARAMETER ChangeLogEntry
|
||||
The changelog entry object to update (from Get-ChangeLogEntries).
|
||||
|
||||
.PARAMETER NewContent
|
||||
The new changelog text containing sections.
|
||||
|
||||
.PARAMETER InitialAtxHeader
|
||||
The markdown header level used in the changelog. Defaults to "#".
|
||||
|
||||
.OUTPUTS
|
||||
The updated changelog entry object.
|
||||
|
||||
.EXAMPLE
|
||||
$entries = Get-ChangeLogEntries -ChangeLogLocation $changelogPath
|
||||
$entry = $entries["1.0.0"]
|
||||
Set-ChangeLogEntryContent -ChangeLogEntry $entry -NewContent $newText -InitialAtxHeader $entries.InitialAtxHeader
|
||||
Set-ChangeLogContent -ChangeLogLocation $changelogPath -ChangeLogEntries $entries
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateNotNull()]
|
||||
[PSCustomObject]$ChangeLogEntry,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[string]$NewContent,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[string]$InitialAtxHeader = "#"
|
||||
)
|
||||
|
||||
# Parse the new content into structured format
|
||||
$parsedContent = Parse-ChangelogContent -ChangelogText $NewContent -InitialAtxHeader $InitialAtxHeader
|
||||
|
||||
# Update the entry with the parsed content
|
||||
$ChangeLogEntry.ReleaseContent = $parsedContent.ReleaseContent
|
||||
$ChangeLogEntry.Sections = $parsedContent.Sections
|
||||
|
||||
return $ChangeLogEntry
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user