mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-07-28 01:37:43 +00:00
239 lines
8.4 KiB
PowerShell
239 lines
8.4 KiB
PowerShell
#!/usr/bin/env pwsh
|
|
#requires -Version 7.0
|
|
|
|
[CmdletBinding()]
|
|
param(
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$NdependLicense = $env:NDEPEND_LICENSE
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
$ProgressPreference = 'SilentlyContinue'
|
|
|
|
# Configuration
|
|
# Determine NDepend installation path based on OS
|
|
if ($IsWindows -or $env:OS -like "Windows*") {
|
|
$NdependDll = "C:\ndepend\net10.0\NDepend.Console.MultiOS.dll"
|
|
} else {
|
|
$NdependDll = Join-Path $HOME "NDepend/net10.0/NDepend.Console.MultiOS.dll"
|
|
}
|
|
# Ensure ScriptDir is set correctly even if $PSScriptRoot is empty (e.g., dot-sourced)
|
|
$ScriptDir = if ($PSScriptRoot) { $PSScriptRoot } else { Split-Path -Parent $MyInvocation.MyCommand.Path }
|
|
$ProjectRoot = Split-Path -Parent $ScriptDir
|
|
$CoverageDir = Join-Path $ScriptDir "coverage"
|
|
$SarifDir = Join-Path $ProjectRoot ".sarif"
|
|
$SolutionFile = Join-Path $ProjectRoot "QuanTAlib.slnx"
|
|
$TestProject = Join-Path $ProjectRoot "lib/QuanTAlib.Tests.csproj"
|
|
$TestProject2 = Join-Path $ProjectRoot "quantower/Quantower.Tests.csproj"
|
|
$RunSettingsFile = Join-Path $ProjectRoot ".config/coverage.runsettings"
|
|
$NdependProject = Join-Path $ScriptDir "quantalib.ndproj"
|
|
|
|
# Validate prerequisites
|
|
if (-not (Test-Path $NdependDll)) {
|
|
Write-Error "NDepend console not found at: $NdependDll"
|
|
exit 1
|
|
}
|
|
|
|
if ([string]::IsNullOrWhiteSpace($NdependLicense)) {
|
|
Write-Warning "NDEPEND_LICENSE environment variable not set. License activation may fail."
|
|
}
|
|
|
|
if (-not (Test-Path $SolutionFile)) {
|
|
Write-Error "Solution file not found: $SolutionFile"
|
|
exit 1
|
|
}
|
|
|
|
# Helper function for section headers
|
|
function Write-Section {
|
|
param([string]$Message)
|
|
Write-Information "`n=== $Message ==="
|
|
}
|
|
|
|
# Track analysis failure
|
|
$AnalysisFailed = $false
|
|
|
|
try {
|
|
# Create .sarif directory
|
|
Write-Section "Creating .sarif directory for Roslyn analyzer output"
|
|
if (-not (Test-Path $SarifDir)) {
|
|
New-Item -ItemType Directory -Path $SarifDir -Force | Out-Null
|
|
}
|
|
Write-Information "SARIF directory: $SarifDir"
|
|
|
|
# Restore, clean, and build
|
|
Write-Section "Cleaning and building solution (generates SARIF files)"
|
|
|
|
Write-Information "Restoring packages..."
|
|
dotnet restore $SolutionFile -v q
|
|
if ($LASTEXITCODE -ne 0) { throw "Restore failed with exit code $LASTEXITCODE" }
|
|
|
|
Write-Information "Cleaning solution..."
|
|
dotnet clean $SolutionFile -v q
|
|
if ($LASTEXITCODE -ne 0) { throw "Clean failed with exit code $LASTEXITCODE" }
|
|
|
|
Write-Information "Removing old coverage data..."
|
|
if (Test-Path $CoverageDir) {
|
|
Remove-Item -Path $CoverageDir -Recurse -Force
|
|
}
|
|
|
|
Write-Information "Building solution..."
|
|
dotnet build $SolutionFile -c Debug --no-incremental
|
|
if ($LASTEXITCODE -ne 0) { throw "Build failed with exit code $LASTEXITCODE" }
|
|
|
|
# Run tests with coverage (QuanTAlib.Tests)
|
|
Write-Section "Running tests with coverage (QuanTAlib.Tests)"
|
|
dotnet test $TestProject `
|
|
-c Debug `
|
|
--no-build `
|
|
--collect:"XPlat Code Coverage" `
|
|
--settings $RunSettingsFile `
|
|
--results-directory:$CoverageDir
|
|
|
|
if ($LASTEXITCODE -ne 0) { throw "Tests failed for QuanTAlib.Tests with exit code $LASTEXITCODE" }
|
|
|
|
# Run tests with coverage (Quantower.Tests)
|
|
Write-Section "Running tests with coverage (Quantower.Tests)"
|
|
dotnet test $TestProject2 `
|
|
-c Debug `
|
|
--no-build `
|
|
--collect:"XPlat Code Coverage" `
|
|
--settings $RunSettingsFile `
|
|
--results-directory:$CoverageDir
|
|
|
|
if ($LASTEXITCODE -ne 0) { throw "Tests failed for Quantower.Tests with exit code $LASTEXITCODE" }
|
|
|
|
# Find coverage files
|
|
Write-Information "`nSearching for coverage files..."
|
|
$CoverageFiles = Get-ChildItem -Path $CoverageDir -Filter "coverage.opencover.xml" -Recurse -File |
|
|
Select-Object -ExpandProperty FullName
|
|
|
|
if (-not $CoverageFiles) {
|
|
Write-Warning "No coverage files found in $CoverageDir"
|
|
}
|
|
else {
|
|
$CoverageFiles | ForEach-Object {
|
|
Write-Information "Coverage file: $_"
|
|
}
|
|
}
|
|
|
|
# Run JetBrains InspectCode
|
|
Write-Section "Running JetBrains InspectCode"
|
|
$InspectCodeOutput = Join-Path $SarifDir "resharper.sarif.json"
|
|
$jbPath = Get-Command "jb" -ErrorAction SilentlyContinue
|
|
if ($jbPath) {
|
|
Write-Information "Running InspectCode analysis..."
|
|
jb inspectcode $SolutionFile --output=$InspectCodeOutput --format=Sarif --no-build
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Warning "InspectCode completed with exit code $LASTEXITCODE"
|
|
}
|
|
else {
|
|
Write-Information "InspectCode SARIF saved to: $InspectCodeOutput"
|
|
}
|
|
}
|
|
else {
|
|
Write-Warning "JetBrains CLI (jb) not found. Skipping InspectCode analysis."
|
|
Write-Information " Install with: dotnet tool install -g JetBrains.ReSharper.GlobalTools"
|
|
}
|
|
|
|
# List SARIF files
|
|
Write-Section "SARIF files generated"
|
|
$SarifFiles = Get-ChildItem -Path $SarifDir -Filter "*.json" -ErrorAction SilentlyContinue
|
|
if ($SarifFiles) {
|
|
$SarifFiles | ForEach-Object {
|
|
Write-Information " $($_.Name) ($([math]::Round($_.Length / 1KB, 2)) KB)"
|
|
}
|
|
}
|
|
else {
|
|
Write-Information "No SARIF files found"
|
|
}
|
|
|
|
# Activate NDepend license
|
|
Write-Section "Activating NDepend license"
|
|
if (-not [string]::IsNullOrWhiteSpace($NdependLicense)) {
|
|
dotnet $NdependDll --RegLic $NdependLicense
|
|
if ($LASTEXITCODE -ne 0) { Write-Warning "License activation returned exit code $LASTEXITCODE" }
|
|
}
|
|
else {
|
|
Write-Warning "Skipping license activation (no license provided)"
|
|
}
|
|
|
|
# Run NDepend analysis
|
|
Write-Section "Running NDepend analysis"
|
|
$NdependArgs = @($NdependProject)
|
|
if ($CoverageFiles) {
|
|
$NdependArgs += "/CoverageFiles"
|
|
foreach ($file in $CoverageFiles) {
|
|
$NdependArgs += $file
|
|
}
|
|
}
|
|
|
|
dotnet $NdependDll @NdependArgs
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Warning "NDepend analysis completed with exit code $LASTEXITCODE"
|
|
$AnalysisFailed = $true
|
|
}
|
|
|
|
}
|
|
catch {
|
|
Write-Error "Script failed: $_"
|
|
$AnalysisFailed = $true
|
|
}
|
|
finally {
|
|
# Always deactivate license
|
|
Write-Section "Deactivating NDepend license"
|
|
if (-not [string]::IsNullOrWhiteSpace($NdependLicense)) {
|
|
dotnet $NdependDll --UnregLic
|
|
if ($LASTEXITCODE -ne 0) { Write-Warning "License deactivation returned exit code $LASTEXITCODE" }
|
|
}
|
|
else {
|
|
Write-Information "Skipping license deactivation (no license provided)"
|
|
}
|
|
|
|
# Generate badges from NDepend trend data
|
|
Write-Section "Generating quality badges"
|
|
$NDBadgePath = Join-Path $ScriptDir "NDBadge.exe"
|
|
# Find the most recent trend data file
|
|
$TrendMetricsDir = Join-Path $ScriptDir "NDependOut\TrendMetrics"
|
|
$TrendXml = if (Test-Path $TrendMetricsDir) {
|
|
Get-ChildItem -Path $TrendMetricsDir -Filter "NDependTrendData*.xml" -File |
|
|
Sort-Object Name -Descending |
|
|
Select-Object -First 1 -ExpandProperty FullName
|
|
}
|
|
else { $null }
|
|
$BadgeDir = Join-Path $ScriptDir "badges"
|
|
|
|
if ((Test-Path $NDBadgePath) -and $TrendXml -and (Test-Path $TrendXml)) {
|
|
if (-not (Test-Path $BadgeDir)) {
|
|
New-Item -ItemType Directory -Path $BadgeDir -Force | Out-Null
|
|
}
|
|
|
|
$Badges = @(
|
|
@{ Metric = "# Lines of Code"; Output = "loc.svg" },
|
|
@{ Metric = "# Source Files"; Output = "files.svg" },
|
|
@{ Metric = "# Classes"; Output = "classes.svg" },
|
|
@{ Metric = "# Methods"; Output = "methods.svg" },
|
|
@{ Metric = "# Public Types"; Output = "public-api.svg" },
|
|
@{ Metric = "Percentage of Comments"; Output = "comments.svg" },
|
|
@{ Metric = "Average Cyclomatic Complexity for Methods"; Output = "complexity.svg" }
|
|
)
|
|
|
|
foreach ($badge in $Badges) {
|
|
$outputPath = Join-Path $BadgeDir $badge.Output
|
|
& $NDBadgePath --xml $TrendXml --metric $badge.Metric --output $outputPath 2>$null
|
|
if ($LASTEXITCODE -eq 0) {
|
|
Write-Information " Generated: $($badge.Output)"
|
|
}
|
|
}
|
|
Write-Information "Badges saved to: $BadgeDir"
|
|
}
|
|
else {
|
|
Write-Information "Skipping badge generation (NDBadge.exe or trend data not found)"
|
|
}
|
|
|
|
Write-Section "Done"
|
|
|
|
if ($AnalysisFailed) {
|
|
Write-Information "Note: Analysis completed with quality gate failures"
|
|
exit 1
|
|
}
|
|
} |