Files
Common-VS2019/eng/validate.ps1
T

135 lines
5.2 KiB
PowerShell

[CmdletBinding()]
param(
[switch] $SkipRestore,
[switch] $SkipDownstream,
[switch] $CollectCoverage
)
$ErrorActionPreference = 'Stop'
$repositoryRoot = Split-Path -Parent $PSScriptRoot
$testResultsPath = Join-Path $repositoryRoot 'TestResults\Validation'
$dotnetHome = Join-Path (Split-Path -Parent $repositoryRoot) '.dotnet-cli-validation'
$nugetPackagesPath = if ($env:NUGET_PACKAGES) { $env:NUGET_PACKAGES } else { Join-Path $env:USERPROFILE '.nuget\packages' }
$env:DOTNET_CLI_HOME = $dotnetHome
$env:DOTNET_GENERATE_ASPNET_CERTIFICATE = 'false'
$env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE = '1'
$env:DOTNET_CLI_TELEMETRY_OPTOUT = '1'
$env:DOTNET_NOLOGO = '1'
$env:NUGET_PACKAGES = $nugetPackagesPath
function Invoke-External
{
param(
[Parameter(Mandatory)] [string] $FilePath,
[Parameter(Mandatory)] [string[]] $ArgumentList
)
& $FilePath @ArgumentList
if ($LASTEXITCODE -ne 0)
{
throw "Command failed with exit code ${LASTEXITCODE}: $FilePath $($ArgumentList -join ' ')"
}
}
function Test-LineEndings
{
$crlfExtensions = @('.cs', '.csproj', '.sln', '.props', '.targets', '.config', '.json', '.xml', '.md', '.txt', '.ps1', '.cmd', '.bat')
$lfExtensions = @('.svg', '.html', '.css', '.js', '.sh', '.yml', '.yaml')
$invalidFiles = [System.Collections.Generic.List[string]]::new()
$files = @(& git -C $repositoryRoot diff --name-only --diff-filter=ACMRT)
if ($LASTEXITCODE -ne 0) { throw 'Unable to enumerate modified repository files.' }
$files += @(& git -C $repositoryRoot diff --cached --name-only --diff-filter=ACMRT)
if ($LASTEXITCODE -ne 0) { throw 'Unable to enumerate staged repository files.' }
$files += @(& git -C $repositoryRoot ls-files --others --exclude-standard)
if ($LASTEXITCODE -ne 0) { throw 'Unable to enumerate untracked repository files.' }
$files = $files | Sort-Object -Unique
foreach ($relativePath in $files)
{
$extension = [System.IO.Path]::GetExtension($relativePath).ToLowerInvariant()
if (($extension -notin $crlfExtensions) -and ($extension -notin $lfExtensions)) { continue }
$fullPath = Join-Path $repositoryRoot $relativePath
if (-not (Test-Path -LiteralPath $fullPath -PathType Leaf)) { continue }
$bytes = [System.IO.File]::ReadAllBytes($fullPath)
for ($index = 0; $index -lt $bytes.Length; $index++)
{
if (($extension -in $crlfExtensions) -and ($bytes[$index] -eq 10) -and (($index -eq 0) -or ($bytes[$index - 1] -ne 13)))
{
$invalidFiles.Add($relativePath)
break
}
if (($extension -in $lfExtensions) -and ($bytes[$index] -eq 13))
{
$invalidFiles.Add($relativePath)
break
}
}
}
if ($invalidFiles.Count -gt 0)
{
throw "Files with incorrect line endings:`n$($invalidFiles -join "`n")"
}
}
function Test-CoverageReport
{
param([Parameter(Mandatory)] [string] $ResultsPath)
$report = Get-ChildItem -LiteralPath $ResultsPath -Filter 'coverage.cobertura.xml' -Recurse | Select-Object -First 1
if (($null -eq $report) -or ($report.Length -eq 0))
{
throw "A non-empty Cobertura coverage report was not found under $ResultsPath"
}
[xml] $coverage = Get-Content -LiteralPath $report.FullName -Raw
if ($coverage.DocumentElement.Name -ne 'coverage')
{
throw "The coverage report at $($report.FullName) is not valid Cobertura XML."
}
}
Push-Location $repositoryRoot
try
{
Write-Host 'Validating Common workspace...'
if (-not $SkipRestore)
{
Invoke-External dotnet @('restore', 'SaCommonVS.sln', '--disable-build-servers', '--verbosity', 'minimal')
}
Invoke-External dotnet @('build', 'SaCommonVS.sln', '--configuration', 'Debug', '--no-restore', '--disable-build-servers', '--verbosity', 'minimal', '--maxcpucount:1')
Invoke-External dotnet @('test', 'SacsCoreUnitTests\SacsCoreUnitTests.csproj', '--configuration', 'Debug', '--no-build', '--no-restore', '--filter', 'FullyQualifiedName~SaMsSpreadsheet_POI_Tester', '--results-directory', $testResultsPath, '--verbosity', 'minimal')
Invoke-External dotnet @('test', 'SacsCoreUnitTests\SacsCoreUnitTests.csproj', '--configuration', 'Debug', '--no-build', '--no-restore', '--results-directory', $testResultsPath, '--verbosity', 'minimal')
if ($CollectCoverage)
{
$coverageResultsPath = Join-Path $testResultsPath "Coverage\$([guid]::NewGuid())"
Invoke-External dotnet @('test', 'SacsCoreUnitTests\SacsCoreUnitTests.csproj', '--configuration', 'Debug', '--no-build', '--no-restore', '--collect', 'XPlat Code Coverage', '--results-directory', $coverageResultsPath, '--verbosity', 'minimal')
Test-CoverageReport $coverageResultsPath
}
Invoke-External dotnet @('list', 'SacsStandardProc\SacsStandardProc.csproj', 'package', '--vulnerable', '--include-transitive')
Invoke-External git @('diff', '--check')
Test-LineEndings
if (-not $SkipDownstream)
{
$businessMgrValidation = Join-Path $repositoryRoot '..\..\BusinessMgr\Workspace\eng\validate.ps1'
if (-not (Test-Path -LiteralPath $businessMgrValidation -PathType Leaf))
{
throw "BusinessMgr validation script was not found at $businessMgrValidation"
}
$businessMgrArguments = @{}
if ($CollectCoverage) { $businessMgrArguments.CollectCoverage = $true }
& $businessMgrValidation @businessMgrArguments
if (-not $?) { throw 'BusinessMgr validation failed.' }
}
Write-Host 'Common validation passed.' -ForegroundColor Green
}
finally
{
Pop-Location
}