diff --git a/PhpManager/private/Constants.ps1 b/PhpManager/private/Constants.ps1 index e534520..d37edd9 100644 --- a/PhpManager/private/Constants.ps1 +++ b/PhpManager/private/Constants.ps1 @@ -25,7 +25,7 @@ New-Variable -Option Constant -Scope Script -Name 'UNSTABLEPHP_RELEASECANDIDATE_ # PHP non-stable identifiers regex New-Variable -Option Constant -Scope Script -Name 'UNSTABLEPHP_RX' -Value "$UNSTABLEPHP_ALPHA|$UNSTABLEPHP_BETA|$UNSTABLEPHP_RELEASECANDIDATE_LC|$UNSTABLEPHP_RELEASECANDIDATE_UC" -New-Variable -Option Constant -Scope Script -Name 'RX_ZIPARCHIVE' -Value "php-(?\d+\.\d+\.\d+)(?:(?$UNSTABLEPHP_RX)(?[1-9]\d*))?(?-nts)?-Win32-(?:VC|vc|vs)(?\d{1,2})-(?x86|x64)\.zip" +New-Variable -Option Constant -Scope Script -Name 'RX_ZIPARCHIVE' -Value "php-(?\d+\.\d+\.\d+)(?:(?$UNSTABLEPHP_RX)(?[1-9]\d*))?(?:-(?\d+))?(?-nts)?-Win32-(?:VC|vc|vs)(?\d{1,2})-(?x86|x64)\.zip" New-Variable -Option Constant -Scope Script -Name 'RX_ZIPARCHIVE_SNAPSHOT' -Value "(?:master|(?:php-(?\d+\.\d+)))/r[0-9a-f]{7,}/php-(?:master|\d+\.\d+)-(?nts|ts)-windows-(?:VC|vc|vs)(?\d{1,2})-(?x86|x64)-r[0-9a-f]{7,}\.zip" New-Variable -Option Constant -Scope Script -Name 'RX_ZIPARCHIVE_SNAPSHOT_SHIVAMMATHUR' -Value "php-(?:master|\d+\.\d+)-(?nts|ts)-windows-(?:VC|vc|vs)(?\d{1,2})-(?x86|x64).zip" diff --git a/PhpManager/private/Get-PhpVersionFromUrl.ps1 b/PhpManager/private/Get-PhpVersionFromUrl.ps1 index 945f46b..13fd2a5 100644 --- a/PhpManager/private/Get-PhpVersionFromUrl.ps1 +++ b/PhpManager/private/Get-PhpVersionFromUrl.ps1 @@ -40,6 +40,7 @@ $data.Version = $groups['version'].Value $data.UnstabilityLevel = $groups['unstabilityLevel'].Value $data.UnstabilityVersion = $groups['unstabilityVersion'].Value + $data.Build = $groups['build'].Value $data.ThreadSafe = $groups['threadSafe'].Value -ne '-nts' $data.VCVersion = $groups['vcVersion'].Value $data.Architecture = $groups['architecture'].Value @@ -57,6 +58,7 @@ } $data.UnstabilityLevel = $Script:UNSTABLEPHP_SNAPSHOT $data.UnstabilityVersion = $null + $data.Build = 0 $data.ThreadSafe = $groups['threadSafe'].Value -ne 'nts' $data.VCVersion = $groups['vcVersion'].Value $data.Architecture = $groups['architecture'].Value diff --git a/PhpManager/private/PhpVersion.ps1 b/PhpManager/private/PhpVersion.ps1 index 1880229..a6f1695 100644 --- a/PhpManager/private/PhpVersion.ps1 +++ b/PhpManager/private/PhpVersion.ps1 @@ -30,6 +30,10 @@ #> [Nullable[int]] $UnstabilityVersion <# + The Windows build number of a release (eg 1 for php-8.5.12-1-...zip), 0 if not specified, $null if unknown (eg for installed versions) + #> + [Nullable[int]] $Build + <# A string used to display the details of the version #> [ValidateNotNull()] @@ -62,6 +66,7 @@ - Version: required - UnstabilityLevel: optional - UnstabilityVersion: optional + - Build: optional - Architecture: required - ThreadSafe: required - VCVersion: required @@ -81,6 +86,13 @@ } elseif ($this.UnstabilityLevel -ne $Script:UNSTABLEPHP_SNAPSHOT) { $this.UnstabilityLevel = $null } + if ($data.ContainsKey('Build') -and $null -ne $data.Build) { + if ($data.Build -eq '') { + $this.Build = 0 + } else { + $this.Build = [int] $data.Build + } + } $this.Version = $data.Version if ($data.Version -eq 'master') { $this.MajorMinorVersion = 'master' @@ -121,7 +133,11 @@ $this.Architecture = $data.Architecture $this.ThreadSafe = $data.ThreadSafe $this.VCVersion = $data.VCVersion - $dn = 'PHP ' + $this.FullVersion + ' ' + $this.Architecture + $dn = 'PHP ' + $this.FullVersion + if ($this.Build -gt 0) { + $dn += '-' + $this.Build + } + $dn += ' ' + $this.Architecture if ($this.Architecture -eq $Script:ARCHITECTURE_32BITS) { $dn += ' (32-bit)' } elseif ($this.Architecture -eq $Script:ARCHITECTURE_64BITS) { @@ -144,6 +160,9 @@ $cmp = -1 } elseif ($this.ComparableVersion -gt $that.ComparableVersion) { $cmp = 1 + } elseif ($null -ne $this.Build -and $null -ne $that.Build -and $this.Build -ne $that.Build) { + # The build number is unknown for installed versions: compare it only between downloadable ones + $cmp = if ($this.Build -lt $that.Build) { -1 } else { 1 } } else { if ($this.Architecture -gt $that.Architecture) { $cmp = -1 diff --git a/PhpManager/public/Install-Php.ps1 b/PhpManager/public/Install-Php.ps1 index 9be74c1..10a09d8 100644 --- a/PhpManager/public/Install-Php.ps1 +++ b/PhpManager/public/Install-Php.ps1 @@ -135,7 +135,7 @@ foreach ($compatibleVersion in $compatibleVersions) { if ($null -eq $versionToInstall) { $versionToInstall = $compatibleVersion - } elseif ($compatibleVersions -gt $versionToInstall) { + } elseif ($compatibleVersion -gt $versionToInstall) { $versionToInstall = $compatibleVersion } } diff --git a/test/tests/Get-PhpVersionFromUrl.Tests.ps1 b/test/tests/Get-PhpVersionFromUrl.Tests.ps1 new file mode 100644 index 0000000..71b6f32 --- /dev/null +++ b/test/tests/Get-PhpVersionFromUrl.Tests.ps1 @@ -0,0 +1,42 @@ +Describe 'Get-PhpVersionFromUrl' { + It 'parses a release without build number' { + $v = Get-PhpVersionFromUrl -Url 'https://downloads.php.net/~windows/releases/php-8.5.12-nts-Win32-vs17-x64.zip' -ReleaseState Release + $v.FullVersion | Should -BeExactly '8.5.12' + $v.Build | Should -Be 0 + $v.ThreadSafe | Should -BeFalse + $v.VCVersion | Should -Be 17 + $v.Architecture | Should -BeExactly 'x64' + $v.DisplayName | Should -BeExactly 'PHP 8.5.12 x64 (64-bit) Non-Thread-Safe' + } + It 'parses a release with build number' { + $v = Get-PhpVersionFromUrl -Url 'https://downloads.php.net/~windows/releases/php-8.5.12-1-Win32-vs17-x86.zip' -ReleaseState Release + $v.FullVersion | Should -BeExactly '8.5.12' + $v.Build | Should -Be 1 + $v.ThreadSafe | Should -BeTrue + $v.Architecture | Should -BeExactly 'x86' + $v.DisplayName | Should -BeExactly 'PHP 8.5.12-1 x86 (32-bit) Thread-Safe' + } + It 'parses a release candidate with build number' { + $v = Get-PhpVersionFromUrl -Url 'php-8.6.0RC4-2-nts-Win32-vs18-x64.zip' -ReleaseState QA + $v.FullVersion | Should -BeExactly '8.6.0RC4' + $v.Build | Should -Be 2 + } + It 'prefers higher build numbers of the same version' { + $v0 = Get-PhpVersionFromUrl -Url 'php-8.5.12-nts-Win32-vs17-x64.zip' -ReleaseState Release + $v1 = Get-PhpVersionFromUrl -Url 'php-8.5.12-1-nts-Win32-vs17-x64.zip' -ReleaseState Release + $v2 = Get-PhpVersionFromUrl -Url 'php-8.5.12-2-nts-Win32-vs17-x64.zip' -ReleaseState Release + $next = Get-PhpVersionFromUrl -Url 'php-8.5.13-nts-Win32-vs17-x64.zip' -ReleaseState Release + $v1.CompareTo($v0) | Should -BeGreaterThan 0 + $v2.CompareTo($v1) | Should -BeGreaterThan 0 + $v0.CompareTo($v1) | Should -BeLessThan 0 + $next.CompareTo($v2) | Should -BeGreaterThan 0 + ($v0 -lt $v1) | Should -BeTrue + } + It 'ignores the build number when it is unknown' { + $v1 = Get-PhpVersionFromUrl -Url 'php-8.5.12-1-nts-Win32-vs17-x64.zip' -ReleaseState Release + $unknown = & (Get-Module PhpManager) { [PhpVersion]::new(@{Version = '8.5.12'; Architecture = 'x64'; ThreadSafe = $false; VCVersion = 17}) } + $unknown.Build | Should -BeNullOrEmpty + $v1.CompareTo($unknown) | Should -Be 0 + $unknown.CompareTo($v1) | Should -Be 0 + } +}