Modules/businessdev.ALbuild.Core/Public/Test-BcVersionInRange.ps1

function Test-BcVersionInRange {
    <#
    .SYNOPSIS
        Tests whether a version satisfies a NuGet-style version range.
 
    .DESCRIPTION
        Implements NuGet version-range semantics
        (https://learn.microsoft.com/nuget/concepts/package-versioning#version-ranges):
 
          1.0 minimum, inclusive ( x >= 1.0 )
          [1.0] exact ( x == 1.0 )
          [1.0,) minimum, inclusive ( x >= 1.0 )
          (1.0,) minimum, exclusive ( x > 1.0 )
          (,1.0] maximum, inclusive ( x <= 1.0 )
          (,1.0) maximum, exclusive ( x < 1.0 )
          [1.0,2.0] inclusive both ends
          [1.0,2.0) inclusive low, exclusive high
          (1.0,2.0) exclusive both ends
 
        A missing endpoint is treated as unbounded regardless of bracket style. Versions are
        normalised to four parts via ConvertTo-BcVersion.
 
    .PARAMETER Version
        The version to test.
 
    .PARAMETER Range
        The NuGet version range expression.
 
    .EXAMPLE
        Test-BcVersionInRange -Version '25.1.0.0' -Range '[25.0,26.0)'
        Returns $true
 
    .OUTPUTS
        System.Boolean
    #>

    [CmdletBinding()]
    [OutputType([bool])]
    param(
        [Parameter(Mandatory, Position = 0)]
        [string] $Version,

        [Parameter(Mandatory, Position = 1)]
        [string] $Range
    )

    $value = ConvertTo-BcVersion -InputObject $Version -Strict
    $expr  = $Range.Trim()

    if ([string]::IsNullOrWhiteSpace($expr)) {
        throw "Version range must not be empty."
    }

    # Bare version (no brackets/comma) => minimum inclusive.
    if ($expr -notmatch '[\[\]\(\),]') {
        $min = ConvertTo-BcVersion -InputObject $expr -Strict
        return $value -ge $min
    }

    $match = [regex]::Match($expr, '^([\[\(])\s*([^,\]\)]*)\s*(,?)\s*([^,\]\)]*)\s*([\]\)])$')
    if (-not $match.Success) {
        throw "Invalid version range '$Range'."
    }

    $lowerInclusive = $match.Groups[1].Value -eq '['
    $lowerRaw       = $match.Groups[2].Value.Trim()
    $hasComma       = $match.Groups[3].Value -eq ','
    $upperRaw       = $match.Groups[4].Value.Trim()
    $upperInclusive = $match.Groups[5].Value -eq ']'

    if (-not $hasComma) {
        # No comma: only the exact form [x] is valid.
        if ($lowerInclusive -and $upperInclusive -and -not [string]::IsNullOrWhiteSpace($lowerRaw)) {
            $exact = ConvertTo-BcVersion -InputObject $lowerRaw -Strict
            return $value -eq $exact
        }
        throw "Invalid version range '$Range'."
    }

    $result = $true

    if (-not [string]::IsNullOrWhiteSpace($lowerRaw)) {
        $min = ConvertTo-BcVersion -InputObject $lowerRaw -Strict
        $result = $result -and $(if ($lowerInclusive) { $value -ge $min } else { $value -gt $min })
    }

    if (-not [string]::IsNullOrWhiteSpace($upperRaw)) {
        $max = ConvertTo-BcVersion -InputObject $upperRaw -Strict
        $result = $result -and $(if ($upperInclusive) { $value -le $max } else { $value -lt $max })
    }

    return $result
}