Public/Clear-DevVmCache.ps1

<#
.SYNOPSIS
Clears the DevVm cache.
 
.DESCRIPTION
Clears the local DevVm cache of downloaded index files and version lists.
The cache is stored in %LOCALAPPDATA%\DevVm\Cache with a 30-day validity period.
 
.PARAMETER All
Clear all cached files. If not specified, shows current cache information.
 
.EXAMPLE
Clear-DevVmCache -All
 
#>

function Clear-DevVmCache {
    [CmdletBinding(SupportsShouldProcess = $true)]
    param (
        [switch]$All
    )

    $cacheDir = Get-DevVmCacheDirectory

    if ($PSCmdlet.ShouldProcess($cacheDir, "Clear DevVm cache")) {
        if ($All) {
            $cacheFiles = @(Get-ChildItem -Path $cacheDir -File -ErrorAction SilentlyContinue)

            if ($cacheFiles.Count -gt 0) {
                Write-Output "Clearing DevVm cache..."
                Write-Output "Cache location: $cacheDir"
                Write-Output "Files to remove: $($cacheFiles.Count)"
                Write-Output ""

                $cacheFiles | ForEach-Object {
                    $age = (Get-Date) - $_.LastWriteTime
                    Write-Verbose "Removing: $($_.Name) (age: $([math]::Round($age.TotalDays, 1)) days)"
                    Remove-Item -Path $_.FullName -Force -ErrorAction SilentlyContinue
                }

                Write-Output "Cache cleared successfully."
            }
            else {
                Write-Output "Cache is empty."
            }
        }
        else {
            # Show cache info
            $cacheFiles = @(Get-ChildItem -Path $cacheDir -File -ErrorAction SilentlyContinue | Where-Object { $_.Extension -eq '.cache' })

            if ($cacheFiles.Count -gt 0) {
                Write-Output "DevVm Cache Information"
                Write-Output "========================"
                Write-Output "Location: $cacheDir"
                Write-Output "Files: $($cacheFiles.Count)"
                Write-Output "Total Size: $([math]::Round((($cacheFiles | Measure-Object -Property Length -Sum).Sum / 1KB), 2)) KB"
                Write-Output ""
                Write-Output "Cache Details:"
                Write-Output ""

                $cacheFiles | ForEach-Object {
                    $age = (Get-Date) - $_.LastWriteTime
                    $status = if ($age.TotalDays -lt 30) { "VALID" } else { "EXPIRED" }
                    $expiryDate = $_.LastWriteTime.AddDays(30)
                    $daysRemaining = [math]::Max(0, ($expiryDate - (Get-Date)).TotalDays)

                    # Try to read metadata for runtime info
                    $metadataFile = $_.FullName -replace '\.cache$', '.metadata'
                    $runtime = 'unknown'
                    if (Test-Path $metadataFile) {
                        try {
                            $metadata = Get-Content -Path $metadataFile -Raw | ConvertFrom-Json -ErrorAction SilentlyContinue
                            if ($metadata -and $metadata.Runtime) {
                                $runtime = $metadata.Runtime
                            }
                        }
                        catch {
                            Write-Verbose "Failed to read cache metadata from ${metadataFile}: $_"
                        }
                    }

                    Write-Output " Runtime: $runtime"
                    Write-Output " Status: [$status] - Age: $([math]::Round($age.TotalDays, 1)) days"
                    Write-Output " Expires: $($expiryDate.ToString('yyyy-MM-dd HH:mm:ss')) ($([math]::Round($daysRemaining, 1)) days remaining)"
                    Write-Output " Size: $([math]::Round($_.Length / 1KB, 2)) KB"
                    Write-Output ""
                }
            }
            else {
                Write-Output "Cache is empty."
            }
        }
    }
}