microsoft/hve-core

Public

mirrored fromhttps://github.com/microsoft/hve-coreAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
e69486a5f809ede45c63c0a31358c12912bd5168

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

scripts/linting/Invoke-PythonLint.ps1

135lines · modepreview

#!/usr/bin/env pwsh
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: MIT
#
# Invoke-PythonLint.ps1
#
# Purpose: Dynamically discovers and lints Python skills using ruff
# Author: HVE Core Team

#Requires -Version 7.0

[CmdletBinding()]
param(
    [Parameter(Mandatory = $false)]
    [string]$RepoRoot = (Get-Location).Path,

    [Parameter(Mandatory = $false)]
    [string]$OutputPath
)

$ErrorActionPreference = 'Stop'

#region Functions

function Invoke-PythonLint {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)]
        [string]$RepoRoot,

        [Parameter(Mandatory = $false)]
        [string]$OutputPath
    )

    Push-Location $RepoRoot
    try {
        # Find all directories with pyproject.toml
        $pythonSkills = Get-ChildItem -Path . -Filter 'pyproject.toml' -Recurse -Force -File |
            Where-Object { $_.FullName -notmatch 'node_modules' } |
            ForEach-Object { $_.Directory.FullName }

        if (-not $pythonSkills) {
            Write-Host 'No Python skills found (no pyproject.toml files detected)' -ForegroundColor Yellow
            return @{ success = $true; skillsChecked = 0; errors = @() }
        }

        Write-Host "Found $($pythonSkills.Count) Python skill(s):" -ForegroundColor Cyan
        $pythonSkills | ForEach-Object { Write-Host "  - $_" -ForegroundColor Gray }

        # Check if ruff is available (once, before loop)
        $ruffAvailable = Get-Command ruff -ErrorAction SilentlyContinue
        if (-not $ruffAvailable) {
            Write-Host '❌ ruff is not installed. Run "uv sync" in a skill directory or install with "uv pip install ruff".' -ForegroundColor Red
            return @{ success = $false; skillsChecked = 0; errors = @('ruff not installed') }
        }

        $results = @{
            success = $true
            skillsChecked = 0
            errors = @()
            details = @()
        }

        foreach ($skillPath in $pythonSkills) {
            Write-Host "`nRunning ruff in $skillPath..." -ForegroundColor Cyan
            
            Push-Location $skillPath
            try {
                $output = ruff check . 2>&1
                $exitCode = $LASTEXITCODE
                
                $result = @{
                    path = $skillPath
                    passed = ($exitCode -eq 0)
                    output = $output | Out-String
                }
                
                $results.details += $result
                $results.skillsChecked++
                
                if ($exitCode -ne 0) {
                    Write-Host "$output" -ForegroundColor Red
                    Write-Host '❌ Linting issues found' -ForegroundColor Red
                    $results.success = $false
                    $results.errors += $skillPath
                } else {
                    if ($output) {
                        Write-Host "$output"
                    }
                    Write-Host '✓ No linting issues' -ForegroundColor Green
                }
            } catch {
                Write-Host "Error running ruff: $_" -ForegroundColor Red
                $results.success = $false
                $results.errors += "$skillPath - error: $_"
            } finally {
                Pop-Location
            }
        }

        # Default to logs directory when no OutputPath specified
        if (-not $OutputPath) {
            $logsDir = Join-Path -Path $RepoRoot -ChildPath 'logs'
            if (-not (Test-Path $logsDir)) {
                New-Item -ItemType Directory -Path $logsDir -Force | Out-Null
            }
            $OutputPath = Join-Path -Path $logsDir -ChildPath 'python-lint-results.json'
        }
        $results | ConvertTo-Json -Depth 3 | Out-File $OutputPath -Encoding UTF8
        Write-Host "📊 Results written to: $OutputPath" -ForegroundColor Cyan

        return $results
    } finally {
        Pop-Location
    }
}

#endregion

#region Main Execution

# Don't run main logic if dot-sourced for testing
if ($MyInvocation.InvocationName -ne '.') {
    $result = Invoke-PythonLint -RepoRoot $RepoRoot -OutputPath $OutputPath
    
    if ($result.success) {
        Write-Host "`n✅ All Python skills passed linting" -ForegroundColor Green
        exit 0
    } else {
        Write-Host "`n❌ Linting completed with errors" -ForegroundColor Red
        exit 1
    }
}

#endregion