Improve JSON linting on windows/VS (#61825)

This commit is contained in:
Alexey 2022-10-21 04:16:34 +03:00 committed by GitHub
parent 810cef750f
commit 6364bd6b1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 80 additions and 6 deletions

View File

@ -141,6 +141,11 @@
<Link>
<SubSystem>Windows</SubSystem>
</Link>
<CustomBuildStep Condition="'$(CDDA_POST_BUILD_JSON_LINT)' != ''">
<Command>C:\windows\system32\windowspowershell\v1.0\powershell.exe $(SolutionDir)\style-json.ps1 -FromMSBuild</Command>
<Message>Linting JSON</Message>
<Outputs>non-existent-file-to-always-trigger-custom-step.txt</Outputs>
</CustomBuildStep>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
<ClCompile>

View File

@ -1,7 +1,76 @@
Write-Output "JSON formatting script begins."
param (
[switch]$FromMSBuild = $false
)
# https://stackoverflow.com/a/11213394
function IsFileLocked( [string] $filePath ) {
Rename-Item $filePath $filePath -ErrorVariable errs -ErrorAction SilentlyContinue
return ( $errs.Count -ne 0 )
}
function ExitWithError( [string] $msg ) {
if ( $FromMSBuild ) {
Write-Output "jsonlint : lint warning cddalint01 : $msg";
} else {
Write-Output $msg
}
Exit 0 # Return 0 so build continues
}
# Track execution time, if script is called from Visual Studio and it goes over max then bail out early
$timer = [Diagnostics.Stopwatch]::StartNew()
$timer_max_seconds = 30
$scriptDir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
Set-Location -Path (Join-Path -Path $scriptDir -ChildPath "..")
$blacklist = Get-Content "json_blacklist" | Resolve-Path -Relative
$files = Get-ChildItem -Recurse -Include *.json "data" | Resolve-Path -Relative | ?{$blacklist -notcontains $_}
$files | ForEach-Object -Begin { $i = 0 } -Process { $i = $i+1 } { if( $i -eq 1 -or $i % 100 -eq 0 -or $i -eq $files.count ) { Write-Output "File $i of $($files.Count)" } } { Invoke-Expression ".\tools\format\json_formatter.exe $_" } -End $null
Write-Output "JSON formatting script ends."
Set-Location -Path ( Join-Path -Path $scriptDir -ChildPath ".." )
$formatter = Join-Path ( Resolve-Path . ) "tools\format\json_formatter.exe"
if ( -not( Test-Path -Path $formatter -PathType Leaf ) ) {
ExitWithError( "Linting JSON skipped: Formatter executable not found at '$formatter'." )
}
if ( IsFileLocked( $formatter ) ) {
ExitWithError( "Linting JSON skipped: Formatter executable file is locked, likely formatter project is building." )
}
# Probe for files changed in common "upstream" branches, only style those
$gitChanged = @( git diff --name-only '*.json' )
foreach ( $probe in @( 'master', 'origin/master', 'upstream/master', 'fork/master' ) ) {
$mergebase = Invoke-Expression "git merge-base $probe HEAD" 2>&1
if ( -not( $? ) ) {
continue # skip missing branches
}
$gitChanged = ( @( $gitChanged ) + @( git diff --name-only $mergebase '*.json' ) ) | Select-Object -Unique
if ( -not( $? ) ) {
ExitWithError( "Linting JSON skipped: git diff command failed." )
}
}
if( $gitChanged.count -eq 0 ) {
ExitWithError( "Linting JSON skipped: git reported no changes in *.json files." )
}
$gitChanged | ForEach-Object -Begin { $i = 0 } -Process { $i = $i+1 } {
if( $i -eq 1 -or $i % 100 -eq 0 -or $i -eq $gitChanged.count ) {
Write-Output "File $i of $( $gitChanged.Count )"
}
} {
if ( $FromMSBuild ) { # parse and re-print in a format Visual Studio uses for error log
if ( [math]::Floor( $timer.Elapsed.TotalSeconds ) -gt $timer_max_seconds ) {
ExitWithError( "Linting JSON aborted: Took more than $timer_max_seconds seconds, run the lint script manually or raise build lint limit." )
}
$input = Invoke-Expression "$formatter $_" | Out-String
$regex = new-object RegEx('(?mi)^(.*):(\d+):(\d+): ([^\n]+)$')
foreach ( $res in $regex.matches( $input ) ) {
$line = $res.Groups[2].Value;
$col = $res.Groups[3].Value;
$msg = $res.Groups[4].Value;
$file = Join-Path ( Resolve-Path . ) $_
Write-Output "$file($line,$col) : lint warning cddalint01 : $msg";
break
}
} else {
Invoke-Expression "$formatter $_"
}
} -End $null