public/Get-WtwUpdateStatus.ps1
|
function Get-WtwUpdateStatus { <# .SYNOPSIS Report whether a newer wtw is published on the PowerShell Gallery. .DESCRIPTION Caches the Gallery answer in ~/.wtw/update-check.json so repeated calls cost nothing. An offline or unreachable Gallery is a normal outcome: the failed attempt is cached too, so a disconnected workstation does not retry on every command. This is the function the detached background refresh runs; the foreground notice never calls it, because it must not wait on a network request. See Write-WtwUpdateNotice. .EXAMPLE Get-WtwUpdateStatus -Force Refreshes the cache and returns the current/latest comparison. #> [CmdletBinding()] param( [TimeSpan] $CacheTtl = [TimeSpan]::FromHours(24), [ValidateRange(1, 30)] [int] $TimeoutSec = 5, [string] $CachePath = (Join-Path $HOME '.wtw/update-check.json'), [switch] $Force ) $manifestPath = Join-Path $script:WtwModuleRoot 'wtw.psd1' $currentVersion = $null try { $currentVersion = [version](Import-PowerShellDataFile -LiteralPath $manifestPath).ModuleVersion } catch { $currentVersion = $null } $cacheFile = [IO.Path]::GetFullPath($CachePath) $cache = Read-WtwJsonFile -Path $cacheFile $now = [DateTime]::UtcNow $checkedAt = ConvertTo-WtwUtcDate -Value (Get-WtwPropertyValue -Object $cache -Name 'CheckedAtUtc') $cacheIsFresh = -not $Force -and $null -ne $checkedAt -and ($now - $checkedAt) -lt $CacheTtl $latestText = [string](Get-WtwPropertyValue -Object $cache -Name 'LatestVersion' -DefaultValue '') $status = [string](Get-WtwPropertyValue -Object $cache -Name 'Status' -DefaultValue 'Unknown') $source = 'cache' if (-not $cacheIsFresh) { $source = 'gallery' $status = 'Unavailable' try { $uri = "https://www.powershellgallery.com/api/v2/FindPackagesById()?id='wtw'&%24filter=IsLatestVersion" $response = Invoke-WebRequest -Uri $uri -TimeoutSec $TimeoutSec -ErrorAction Stop $match = [regex]::Match( [string]$response.Content, '<d:Version>(?<version>[^<]+)</d:Version>', [Text.RegularExpressions.RegexOptions]::CultureInvariant ) if (-not $match.Success) { throw 'The PowerShell Gallery response did not contain a wtw version.' } $latestText = $match.Groups['version'].Value [version]$latestText | Out-Null $status = 'Available' } catch { # Offline is normal. The failed attempt is cached below so wtw does # not retry - or pause - on every command. } try { $cacheDirectory = Split-Path -Parent $cacheFile New-Item -ItemType Directory -Path $cacheDirectory -Force -ErrorAction Stop | Out-Null [ordered]@{ CheckedAtUtc = $now.ToString('O') LatestVersion = $latestText Status = $status } | ConvertTo-Json | Set-Content -LiteralPath $cacheFile -Encoding utf8 -ErrorAction Stop } catch { # Update checks must never prevent wtw from running. } $checkedAt = $now } $latestVersion = $null if (-not [version]::TryParse($latestText, [ref] $latestVersion)) { $latestVersion = $null } [pscustomobject]@{ CurrentVersion = $currentVersion LatestVersion = $latestVersion UpdateAvailable = $null -ne $latestVersion -and $null -ne $currentVersion -and $latestVersion -gt $currentVersion Status = $status CheckedAtUtc = $checkedAt Source = $source } } |