231 lines
7.9 KiB
PowerShell
231 lines
7.9 KiB
PowerShell
function Get-SemverHistory {
|
|
[CmdletBinding()]
|
|
param (
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$Path = (Get-Location).Path
|
|
)
|
|
|
|
if ((Split-Path -Path $Path -Leaf) -eq 'sem.ver') {
|
|
# We have a semver file already
|
|
} else {
|
|
if (-not (Get-Item -Path $Path).PSIsContainer) {
|
|
throw "The Path argument should be a folder or a sem.ver specific file"
|
|
}
|
|
|
|
$Path = Join-Path -Path $Path -ChildPath "sem.ver"
|
|
$Path = (Get-ChildItem -Path $Path -Recurse | Select-Object -First 1).FullName
|
|
}
|
|
|
|
if (-not (Test-Path -Path $Path)) {
|
|
throw "Could not find the requested path [$Path]"
|
|
}
|
|
|
|
$semverLog = git log -c -- $Path
|
|
|
|
$commits = @()
|
|
$commit = $null
|
|
$inSemverLines = $false
|
|
foreach ($line in $semverLog) {
|
|
if ([string]::IsNullOrWhiteSpace($line)) {
|
|
continue
|
|
}
|
|
# This breaks if the comment starts with the word 'commit' on the left margin
|
|
if ($line.StartsWith("commit") -and [string]::IsNullOrWhiteSpace($Commit.SemverValue)) {
|
|
if ($null -ne $commit) {
|
|
$commits += $commit
|
|
}
|
|
$commit = @{
|
|
Hash = ($line -split 'commit ')[1].Trim()
|
|
Author = ""
|
|
Date = ""
|
|
SemverValue = ""
|
|
SemverContents = @()
|
|
Comment = @()
|
|
}
|
|
$inSemverLines = $false
|
|
} elseif ($line.StartsWith("Author:")) {
|
|
$commit.Author = ($line -split 'Author:')[1].Trim()
|
|
} elseif ($line.StartsWith("Date:")) {
|
|
$commit.Date = ($line -split 'Date:')[1].Trim()
|
|
} else {
|
|
if ($line.StartsWith("diff --git")) {
|
|
# We don't care about [diff --git a/sem.ver b/sem.ver] type lines
|
|
continue
|
|
} elseif ($line.StartsWith("index") -and ($line -split ' ').Count -eq 3) {
|
|
# we don't care about [index 7c4d2b4..e1de4ac 100644] type lines
|
|
continue
|
|
} elseif ($line.StartsWith("---") -or $line.StartsWith("+++")) {
|
|
# we don't care about the diff filenames
|
|
continue
|
|
} elseif ($line.StartsWith("@@") -and $line.EndsWith("@@")) {
|
|
$inSemverLines = $true
|
|
continue
|
|
} elseif ($inSemverLines) {
|
|
if ($line.Trim().StartsWith("-") -or $line.StartsWith("\")) {
|
|
# ignore remove lines
|
|
continue
|
|
} elseif ($line.Trim().StartsWith("+")) {
|
|
# skip the first two characters
|
|
$line = $line.Substring(2)
|
|
}
|
|
|
|
$commit.SemverContents += $line
|
|
} else {
|
|
$commit.Comment += $line.Trim()
|
|
}
|
|
}
|
|
}
|
|
# Save the last one too!
|
|
if ($null -ne $commit) {
|
|
$commits += $commit
|
|
}
|
|
|
|
foreach ($commit in $commits) {
|
|
# Yes, it's a hack. It's cheaper than retrieving the file _at_ the hash tho
|
|
$jsonString = "$($commit.SemverContents -join '')".Trim()
|
|
$jsonString = $jsonString.Replace(' ', '').Replace("`t", "")
|
|
if ([string]::IsNullOrWhiteSpace($jsonString)) {
|
|
continue
|
|
}
|
|
if (($jsonString.IndexOf("Version") -eq -1) -or ($jsonString.StartsWith('{"Major"'))) {
|
|
$jsonString = "`"Version`": {$jsonString"
|
|
}
|
|
if (-not $jsonString.StartsWith("{")) {
|
|
$jsonString = "{$jsonString"
|
|
}
|
|
if ($jsonString.StartsWith("{{")) {
|
|
$jsonString = $jsonString.Substring(1)
|
|
$jsonString = "{`"Version`":$jsonString"
|
|
}
|
|
if (-not $jsonString.EndsWith("}")) {
|
|
$jsonString = "$jsonString}"
|
|
}
|
|
if (-not $jsonString.EndsWith("}}")) {
|
|
$jsonString = "$jsonString}"
|
|
}
|
|
$jsonString = $jsonString.Replace(' {{', '{')
|
|
$json = ConvertFrom-Json $jsonString
|
|
$commit.SemverValue = "$($json.Version.Major).$($json.Version.Minor).$($json.Version.Patch)"
|
|
$commit.SemverContents = $null
|
|
}
|
|
|
|
return $commits
|
|
}
|
|
|
|
function Get-GitHistory {
|
|
[CmdletBinding()]
|
|
[OutputType([object[]])]
|
|
param (
|
|
[Parameter(Mandatory = $true, ParameterSetName = 'ByHash')]
|
|
[ValidateNotNullOrEmpty()]
|
|
[Alias('From')]
|
|
[string]$HashStart,
|
|
|
|
[Parameter(Mandatory = $true, ParameterSetName = 'ByHash')]
|
|
[ValidateNotNullOrEmpty()]
|
|
[Alias('To')]
|
|
[string]$HashEnd,
|
|
|
|
[Parameter(Mandatory = $true, ParameterSetName = 'ByObject')]
|
|
[Alias('FromEntry')]
|
|
[object]$StartEntry,
|
|
|
|
[Parameter(Mandatory = $true, ParameterSetName = 'ByObject')]
|
|
[Alias('ToEntry')]
|
|
[object]$EndEntry
|
|
)
|
|
|
|
$logLead = Get-LogLeadName
|
|
|
|
if ($PSCmdlet.ParameterSetName -eq 'ByHash') {
|
|
if ($HashStart -eq $HashEnd) {
|
|
Write-Error "$logLead : You must supply two different hashes. These hashes were the same."
|
|
return
|
|
}
|
|
|
|
$dateStart = Invoke-CallOperatorWithPathAndParameters git @('log', '--no-walk', '--format="%ai"', $HashStart)
|
|
$dateEnd = Invoke-CallOperatorWithPathAndParameters git @('log', '--no-walk', '--format="%ai"', $HashEnd)
|
|
|
|
# Put them in the right order
|
|
if ($dateStart -lt $dateEnd) {
|
|
$HashStart, $HashEnd = $HashEnd, $HashStart
|
|
}
|
|
} else {
|
|
if ($StartEntry.Date -lt $EndEntry.Date) {
|
|
$StartEntry, $EndEntry = $EndEntry, $StartEntry
|
|
}
|
|
|
|
$HashEnd = $EndEntry.Hash
|
|
$HashStart = $StartEntry.Hash
|
|
}
|
|
|
|
$lines = Invoke-CallOperatorWithPathAndParameters git @('log', "$HashEnd...$HashStart", '--format="Author: %aN%nDate: %ai%n%B%n-="', '--notes')
|
|
|
|
$results = @()
|
|
$result = $null
|
|
$skipAdd = $false
|
|
foreach ($line in $lines) {
|
|
if ($line.StartsWith("Author: ")) {
|
|
if ($null -ne $result) {
|
|
$results += $result
|
|
$skipAdd = $false
|
|
}
|
|
$result = @{
|
|
Author = $line.Substring(8)
|
|
Date = $null
|
|
Comments = @()
|
|
JiraTickets = @()
|
|
}
|
|
} elseif ($line.Trim() -eq '-=') {
|
|
if ($skipAdd -eq $false) {
|
|
$results += $result
|
|
}
|
|
$skipAdd = $false
|
|
$result = $null
|
|
} elseif ($line.StartsWith("Date: ")) {
|
|
$result.Date = [DateTime]($line.Substring(6))
|
|
} else {
|
|
$result.Comments += $line.Trim()
|
|
if ($line.StartsWith('Merge')) {
|
|
$skipAdd = $true
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach ($result in $results) {
|
|
$result.JiraTickets = (Select-String '[A-Z]+-[0-9]+' -InputObject $result.Comments -AllMatches -CaseSensitive).Matches.Value
|
|
}
|
|
|
|
return $results
|
|
}
|
|
|
|
function Get-RepoHistoryBySemver {
|
|
[CmdletBinding()]
|
|
param (
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$Path = (Get-Location).Path
|
|
)
|
|
|
|
$results = @()
|
|
|
|
Write-Progress -Activity "Getting history for semver" -PercentComplete 1
|
|
$semverHistory = Get-SemverHistory -Path $Path
|
|
|
|
for ($i = 0; $i -lt ($semverHistory.Count - 1); $i++) {
|
|
$from = $semverHistory[$i]
|
|
$to = $semverHistory[$i + 1]
|
|
Write-Progress -Activity "Getting history by semver" -PercentComplete ((100 * $i) / ($semverHistory.Count - 1)) -Status "Checking for data between $($from.Hash) and $($to.Hash)"
|
|
$commitHistory = Get-GitHistory -StartEntry $from -EndEntry $to
|
|
|
|
$results += @{
|
|
Version = $from.SemverValue
|
|
JiraTickets = ($commitHistory.JiraTickets | Sort-Object -Unique)
|
|
CommitHistory = $commitHistory
|
|
CommitCount = $commitHistory.Count
|
|
SemverData = $from
|
|
}
|
|
}
|
|
Write-Progress -Completed -Activity "Getting history by semver"
|
|
|
|
return $results
|
|
} |