Private/Logic/RuntimeKernel/Definitions/Manifested.Versioning.ps1
|
function ConvertTo-ManifestedComparableVersion { [CmdletBinding()] param( [string]$VersionText ) if ([string]::IsNullOrWhiteSpace($VersionText)) { return $null } $match = [regex]::Match($VersionText, 'v?(\d+\.\d+\.\d+)') if (-not $match.Success) { return $null } return [version]$match.Groups[1].Value } function ConvertTo-ManifestedSemanticVersionText { [CmdletBinding()] param( [string]$VersionText ) if ([string]::IsNullOrWhiteSpace($VersionText)) { return $null } $match = [regex]::Match($VersionText, 'v?(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.\-]+)?)') if (-not $match.Success) { return $null } return $match.Groups[1].Value } function ConvertTo-ManifestedSemanticVersionObject { [CmdletBinding()] param( [string]$VersionText ) $normalizedVersion = ConvertTo-ManifestedSemanticVersionText -VersionText $VersionText if ([string]::IsNullOrWhiteSpace($normalizedVersion)) { return $null } $match = [regex]::Match($normalizedVersion, '(\d+\.\d+\.\d+)') if (-not $match.Success) { return $null } return [version]$match.Groups[1].Value } function Resolve-ManifestedCommandDefinitionReference { [CmdletBinding()] param( [string]$CommandName, [pscustomobject]$Definition ) if ($Definition) { return $Definition } if ([string]::IsNullOrWhiteSpace($CommandName)) { throw 'A command definition reference requires CommandName or Definition.' } $resolvedDefinition = Get-ManifestedCommandDefinition -CommandName $CommandName if (-not $resolvedDefinition) { throw "Could not resolve a packaged command definition for '$CommandName'." } return $resolvedDefinition } function Expand-ManifestedDefinitionTemplate { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$Template, [string]$Version, [string]$TagName, [string]$Flavor ) return ($Template. Replace('{version}', $(if ($null -ne $Version) { [string]$Version } else { '' })). Replace('{tagName}', $(if ($null -ne $TagName) { [string]$TagName } else { '' })). Replace('{flavor}', $(if ($null -ne $Flavor) { [string]$Flavor } else { '' }))) } function Get-ManifestedHostArchitectureKey { [CmdletBinding()] param() if ([System.Environment]::OSVersion.Platform -ne [System.PlatformID]::Win32NT) { return $null } $archHints = @($env:PROCESSOR_ARCHITECTURE, $env:PROCESSOR_ARCHITEW6432) -join ';' if ($archHints -match 'ARM64') { return 'arm64' } if ([Environment]::Is64BitOperatingSystem) { return 'x64' } return $null } function Get-ManifestedDefinitionPortableFactsBlock { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [pscustomobject]$Definition ) foreach ($blockName in @('portableRuntime', 'pythonEmbeddableRuntime')) { $factsBlock = Get-ManifestedDefinitionBlock -Definition $Definition -SectionName 'facts' -BlockName $blockName if ($factsBlock) { return $factsBlock } } return $null } function Get-ManifestedDefinitionRuntimeVersionRule { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [pscustomobject]$Definition ) $factsBlock = Get-ManifestedDefinitionPortableFactsBlock -Definition $Definition if (-not $factsBlock) { return $null } if ($factsBlock.PSObject.Properties.Match('versionRule').Count -gt 0 -and $factsBlock.versionRule) { return $factsBlock.versionRule } if ($factsBlock.PSObject.Properties.Match('versionProbe').Count -gt 0 -and $factsBlock.versionProbe) { return $factsBlock.versionProbe } return $null } function Get-ManifestedDefinitionReleaseVersionRule { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [pscustomobject]$Definition ) foreach ($blockName in @('githubRelease', 'nodeDist', 'vsCodeUpdate', 'pythonEmbed', 'directDownload')) { $supplyBlock = Get-ManifestedDefinitionBlock -Definition $Definition -SectionName 'supply' -BlockName $blockName if (-not $supplyBlock) { continue } if ($supplyBlock.PSObject.Properties.Match('releaseVersionRule').Count -gt 0 -and $supplyBlock.releaseVersionRule) { return $supplyBlock.releaseVersionRule } } return (Get-ManifestedDefinitionRuntimeVersionRule -Definition $Definition) } function Get-ManifestedDefinitionVersionPolicy { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [pscustomobject]$Definition ) $factsBlock = Get-ManifestedDefinitionPortableFactsBlock -Definition $Definition if (-not $factsBlock) { return $null } if ($factsBlock.PSObject.Properties.Match('versionPolicy').Count -gt 0 -and $factsBlock.versionPolicy) { return $factsBlock.versionPolicy } return $null } function ConvertTo-ManifestedVersionTextFromRule { [CmdletBinding()] param( [string]$VersionText, [pscustomobject]$Rule ) if ([string]::IsNullOrWhiteSpace($VersionText)) { return $null } if (-not $Rule) { return (ConvertTo-ManifestedSemanticVersionText -VersionText $VersionText) } $pattern = if ($Rule.PSObject.Properties.Match('regex').Count -gt 0 -and -not [string]::IsNullOrWhiteSpace($Rule.regex)) { [string]$Rule.regex } else { 'v?(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.\-]+)?)' } $match = [regex]::Match($VersionText, $pattern) if (-not $match.Success) { return $null } $normalizedVersion = if ($match.Groups.Count -gt 1) { $match.Groups[1].Value } else { $match.Value } if ($Rule.PSObject.Properties.Match('normalizeRegex').Count -gt 0 -and -not [string]::IsNullOrWhiteSpace($Rule.normalizeRegex)) { $replacement = if ($Rule.PSObject.Properties.Match('normalizeReplacement').Count -gt 0) { [string]$Rule.normalizeReplacement } else { '$1' } $normalizedVersion = ($normalizedVersion -replace [string]$Rule.normalizeRegex, $replacement) } if ($Rule.PSObject.Properties.Match('prefix').Count -gt 0 -and -not [string]::IsNullOrWhiteSpace($Rule.prefix) -and -not $normalizedVersion.StartsWith([string]$Rule.prefix, [System.StringComparison]::OrdinalIgnoreCase)) { $normalizedVersion = ([string]$Rule.prefix + $normalizedVersion) } return $normalizedVersion } function ConvertTo-ManifestedVersionObjectFromRule { [CmdletBinding()] param( [string]$VersionText, [pscustomobject]$Rule ) $normalizedVersion = ConvertTo-ManifestedVersionTextFromRule -VersionText $VersionText -Rule $Rule if ([string]::IsNullOrWhiteSpace($normalizedVersion)) { return $null } $match = [regex]::Match($normalizedVersion, '(\d+(?:\.\d+){1,3})') if (-not $match.Success) { return $null } return [version]$match.Groups[1].Value } function Get-ManifestedDefinitionFlavor { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [pscustomobject]$Definition ) foreach ($blockName in @('portableRuntime', 'pythonEmbeddableRuntime', 'machinePrerequisite', 'npmCli')) { $factsBlock = Get-ManifestedDefinitionBlock -Definition $Definition -SectionName 'facts' -BlockName $blockName if (-not $factsBlock) { continue } if ($factsBlock.PSObject.Properties.Match('hostFlavorMap').Count -gt 0 -and $factsBlock.hostFlavorMap) { $archKey = Get-ManifestedHostArchitectureKey if ([string]::IsNullOrWhiteSpace($archKey)) { return $null } if ($factsBlock.hostFlavorMap.PSObject.Properties.Match($archKey).Count -gt 0) { return $factsBlock.hostFlavorMap.$archKey } } } return $null } function Get-ManifestedCommandFlavor { [CmdletBinding()] param( [string]$CommandName, [pscustomobject]$Definition ) $Definition = Resolve-ManifestedCommandDefinitionReference -CommandName $CommandName -Definition $Definition return (Get-ManifestedDefinitionFlavor -Definition $Definition) } function Get-ManifestedVersionSpec { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [pscustomobject]$Definition ) return [pscustomobject]@{ RuntimeVersionRule = Get-ManifestedDefinitionRuntimeVersionRule -Definition $Definition ReleaseVersionRule = Get-ManifestedDefinitionReleaseVersionRule -Definition $Definition VersionPolicy = Get-ManifestedDefinitionVersionPolicy -Definition $Definition } } function Test-ManifestedManagedVersion { [CmdletBinding()] [OutputType([bool])] param( [Parameter(Mandatory = $true)] [version]$Version, $VersionPolicy, $Rule ) if (-not $VersionPolicy) { return $true } if ($VersionPolicy.PSObject.Properties.Match('managedMinimumVersion').Count -gt 0 -and -not [string]::IsNullOrWhiteSpace($VersionPolicy.managedMinimumVersion)) { $minimumVersion = ConvertTo-ManifestedVersionObjectFromRule -VersionText ([string]$VersionPolicy.managedMinimumVersion) -Rule $Rule if ($minimumVersion -and ($Version -lt $minimumVersion)) { return $false } } if ($VersionPolicy.PSObject.Properties.Match('managedVersionFamily').Count -gt 0 -and -not [string]::IsNullOrWhiteSpace($VersionPolicy.managedVersionFamily)) { $currentFamily = '{0}.{1}' -f $Version.Major, $Version.Minor if ($currentFamily -ne [string]$VersionPolicy.managedVersionFamily) { return $false } } return $true } function Test-ManifestedExternalVersion { [CmdletBinding()] [OutputType([bool])] param( [Parameter(Mandatory = $true)] [version]$Version, $VersionPolicy, $Rule ) if (-not $VersionPolicy) { return $true } if ($VersionPolicy.PSObject.Properties.Match('externalMinimumVersion').Count -gt 0 -and -not [string]::IsNullOrWhiteSpace($VersionPolicy.externalMinimumVersion)) { $minimumVersion = ConvertTo-ManifestedVersionObjectFromRule -VersionText ([string]$VersionPolicy.externalMinimumVersion) -Rule $Rule if ($minimumVersion -and ($Version -lt $minimumVersion)) { return $false } } return $true } function Get-ManifestedFlavorMappedValue { [CmdletBinding()] param( $Map, [Parameter(Mandatory = $true)] [string]$Flavor ) if ($null -eq $Map) { return $null } if ($Map.PSObject.Properties.Match($Flavor).Count -gt 0) { return [string]$Map.$Flavor } return $null } |