Skip to content

Instantly share code, notes, and snippets.

@mattleibow
Last active November 9, 2022 23:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattleibow/0cdd6636f8e4d3c249569fe356e9cc5f to your computer and use it in GitHub Desktop.
Save mattleibow/0cdd6636f8e4d3c249569fe356e9cc5f to your computer and use it in GitHub Desktop.
# Runn th2se 2 commands:
# 1. Generate FULL diff:
# git diff OLD_BRANCH NEW_BRANCH --output=complete.diff **\PublicAPI.*.txt
# 2. Generate REDUCE diff:
# .\eng\scripts\get-breaking-diff.ps1 -Source .\complete.diff -Out .\breaks.diff -Unique .\unique.diff
[CmdletBinding(PositionalBinding=$false)]
param ($Source, $Out, $Unique)
Set-StrictMode -version 2.0
$ErrorActionPreference = "Stop"
$content = Get-Content $Source
$breaking = @()
$lastItem = $null
for ($i = 0; $i -lt $content.Count; $i++) {
$item = $content[$i]
# remove -IntPtr +nint diffs
if ($item.Contains('IntPtr')) {
$foundNint = $false
foreach ($c in $content) {
if ($c.Substring(1) -eq $item.Substring(1).Replace('System.IntPtr', 'nint')) {
$foundNint = $c
break
}
}
if ($foundNint) {
Write-Host "Removed because nint/IntPtr"
Write-Host " $item"
Write-Host " $foundNint"
continue
}
}
# remove (object parameter) (object? parameter) diffs
if ($item.Contains('(object parameter)')) {
$foundNull = $false
foreach ($c in $content) {
if ("~" + $c.Substring(1) -eq $item.Substring(1).Replace('(object parameter)', '(object? parameter)')) {
$foundNull = $c
break
}
}
if ($foundNull) {
Write-Host "Removed because (object[?] parameter)"
Write-Host " $item"
Write-Host " $foundNull"
continue
}
}
# remove nullability diffs
$itemWithoutNull = $item.Substring(1).Replace('?', '_').Replace('!', '_')
if ($itemWithoutNull -ne $item.Substring(1)) {
$wasNullChange = $false
for ($j = 0; $j -lt $breaking.Count; $j++) {
$b = $breaking[$j]
# skip null or equal items
if (($null -eq $b) -or ($item -eq $b)) { continue }
$bWithoutNull = $b.Substring(1).Replace('?', '_').Replace('!', '_')
if ($bWithoutNull -eq $itemWithoutNull) {
$breaking[$j] = $null
$wasNullChange = $true
break
}
}
if ($wasNullChange) {
Write-Host "Removed because #nullability"
Write-Host " $item"
Write-Host " $b"
continue
}
}
# remove empty lines
if ($item -eq '-') { continue }
# remove non-important items
if (-not $item.StartsWith('-') -and -not $item.StartsWith('diff')) { continue }
# remove ending items
if ($item.StartsWith('---')) { continue }
# remove overrides as this is not breaking
if ($item.StartsWith('-~override') -or $item.StartsWith('-override')) { continue }
# remove last item if it was an empty group
if ($lastItem -and $lastItem.StartsWith('diff') -and $item.StartsWith('diff')) {
$breaking[$breaking.Length - 1] = $null
}
# remove ctor(X? x = null) when there is ctor(X?) AND ctor()
$potentialMatch = '(Microsoft.Maui.IPropertyMapper? mapper = null)'
$noNullMatch = '(Microsoft.Maui.IPropertyMapper? mapper)'
$noArgsMatch = '()'
if ($item.Contains($potentialMatch)) {
$foundNoNull = $false
$foundNoArgs = $false
foreach ($c in $content) {
if ((-not $foundNoNull) -and ($c.Substring(1) -eq $item.Substring(1).Replace($potentialMatch, $noNullMatch))) {
$foundNoNull = $c
} elseif ((-not $foundNoArgs) -and ($c.Substring(1) -eq $item.Substring(1).Replace($potentialMatch, $noArgsMatch))) {
$foundNoArgs = $c
}
if ($foundNoNull -and $foundNoArgs) {
break
}
}
if ($foundNoNull -and $foundNoArgs) {
Write-Host "Removed because default nulls"
Write-Host " $item"
Write-Host " $foundNoNull"
Write-Host " $foundNoArgs"
continue
}
}
# remove same as above, but different
$potentialMatch = '(Microsoft.Maui.IPropertyMapper! mapper, Microsoft.Maui.CommandMapper? commandMapper = null)'
$noNullMatch = '(Microsoft.Maui.IPropertyMapper? mapper, Microsoft.Maui.CommandMapper? commandMapper)'
$noArgsMatch = '(Microsoft.Maui.IPropertyMapper? mapper)'
if ($item.Contains($potentialMatch)) {
$foundNoNull = $false
$foundNoArgs = $false
foreach ($c in $content) {
if ((-not $foundNoNull) -and ($c.Substring(1) -eq $item.Substring(1).Replace($potentialMatch, $noNullMatch))) {
$foundNoNull = $c
} elseif ((-not $foundNoArgs) -and ($c.Substring(1) -eq $item.Substring(1).Replace($potentialMatch, $noArgsMatch))) {
$foundNoArgs = $c
}
if ($foundNoNull -and $foundNoArgs) {
break
}
}
if ($foundNoNull -and $foundNoArgs) {
Write-Host "Removed because default nulls 2.0"
Write-Host " $item"
Write-Host " $foundNoNull"
Write-Host " $foundNoArgs"
continue
}
}
# remove same as above, but different
$potentialMatch = '(Microsoft.Maui.IPropertyMapper? mapper = null, Microsoft.Maui.CommandMapper? commandMapper = null)'
$noNullMatch = '(Microsoft.Maui.IPropertyMapper? mapper, Microsoft.Maui.CommandMapper? commandMapper)'
$noArgsMatch = '()'
if ($item.Contains($potentialMatch)) {
$foundNoNull = $false
$foundNoArgs = $false
foreach ($c in $content) {
if ((-not $foundNoNull) -and ($c.Substring(1) -eq $item.Substring(1).Replace($potentialMatch, $noNullMatch))) {
$foundNoNull = $c
} elseif ((-not $foundNoArgs) -and ($c.Substring(1) -eq $item.Substring(1).Replace($potentialMatch, $noArgsMatch))) {
$foundNoArgs = $c
}
if ($foundNoNull -and $foundNoArgs) {
break
}
}
if ($foundNoNull -and $foundNoArgs) {
Write-Host "Removed because default nulls 3.0"
Write-Host " $item"
Write-Host " $foundNoNull"
Write-Host " $foundNoArgs"
continue
}
}
# remove ~Xxx when Xxx exists still
if ($item.StartsWith('-~')) {
$foundNullRemove = $null
foreach ($c in $content) {
if (($c.Substring(1) -eq $item.Substring(2)) -or
($c.Substring(1) -eq ($item.Substring(2) + '?')) -or
($c.Substring(1) -eq ($item.Substring(2) + '!'))) {
$foundNullRemove = $c
break
}
}
if ($foundNullRemove) {
Write-Host "Removed because nullability was enabled"
Write-Host " $item"
Write-Host " $foundNullRemove"
continue
}
}
$breaking += $item
$lastItem = $item
}
# remove last empty group
if ($lastItem -and $breaking[$breaking.Length - 1].StartsWith('diff')) {
$breaking[$breaking.Length - 1] = $null
}
$breaking |
Where-Object { $null -ne $_ } |
Set-Content $Out
$breaking |
Where-Object { ($null -ne $_) -and (-not $_.StartsWith('diff')) } |
Sort-Object -Unique |
Set-Content $Unique
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment