Skip to content

Commit b53eecc

Browse files
Fix version comparison logic for 'latest' upgrades in PSGalleryModule and Package scripts (#170)
## Root Cause PSDepend was failing to upgrade modules/packages when requesting `'latest'` if a newer minor version was available. For example, machines with version 2.8.0 would not upgrade to 2.10.0, reporting: ``` You have the latest version of [module-name], with installed version [2.8.0] and PSGallery version [2.10.0] ``` The issue was **string-based version comparison** instead of typed version comparison. When comparing as strings: - `"2.10.0" -le "2.8.0"` evaluates to `$true` (because "1" < "8" lexically) This caused the logic to incorrectly conclude that 2.10.0 was not newer than 2.8.0. ## Solution Both PSGalleryModule.ps1 and Package.ps1 now: 1. Attempt to parse versions as `[System.Management.Automation.SemanticVersion]` objects first 2. Fall back to `[System.Version]` if SemanticVersion parsing fails 3. Compare the **typed objects** instead of strings 4. Return `$false` if neither parsing method succeeds ## Testing Added regression tests to catch this scenario: - **PSGalleryModule.Type.Tests.ps1**: Verifies 2.8.0 → 2.10.0 upgrade with `latest` - **Package.Type.Tests.ps1**: Same scenario for Package dependencies Fixes #139 Fixes #153
1 parent 864e03d commit b53eecc

4 files changed

Lines changed: 64 additions & 9 deletions

File tree

PSDepend/PSDependScripts/PSGalleryModule.ps1

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -251,16 +251,22 @@ if($Existing) {
251251
}
252252

253253
$GalleryVersion = Find-Module @FindModuleParams | Measure-Object -Property Version -Maximum | Select-Object -ExpandProperty Maximum
254-
[System.Version]$parsedVersion = $null
255-
[System.Management.Automation.SemanticVersion]$parsedSemanticVersion = $null
256-
[System.Management.Automation.SemanticVersion]$parsedTempSemanticVersion = $null
254+
[System.Version]$parsedExistingVersion = $null
255+
[System.Version]$parsedGalleryVersion = $null
256+
[System.Management.Automation.SemanticVersion]$parsedExistingSemanticVersion = $null
257+
[System.Management.Automation.SemanticVersion]$parsedGallerySemanticVersion = $null
257258
$isGalleryVersionLessEquals = if (
258-
[System.Management.Automation.SemanticVersion]::TryParse($ExistingVersion, [ref]$parsedSemanticVersion) -and
259-
[System.Management.Automation.SemanticVersion]::TryParse($GalleryVersion, [ref]$parsedTempSemanticVersion)
259+
[System.Management.Automation.SemanticVersion]::TryParse([string]$ExistingVersion, [ref]$parsedExistingSemanticVersion) -and
260+
[System.Management.Automation.SemanticVersion]::TryParse([string]$GalleryVersion, [ref]$parsedGallerySemanticVersion)
260261
) {
261-
$GalleryVersion -le $parsedSemanticVersion
262-
} elseif ([System.Version]::TryParse($ExistingVersion, [ref]$parsedVersion)) {
263-
$GalleryVersion -le $parsedVersion
262+
$parsedGallerySemanticVersion -le $parsedExistingSemanticVersion
263+
} elseif (
264+
[System.Version]::TryParse([string]$ExistingVersion, [ref]$parsedExistingVersion) -and
265+
[System.Version]::TryParse([string]$GalleryVersion, [ref]$parsedGalleryVersion)
266+
) {
267+
$parsedGalleryVersion -le $parsedExistingVersion
268+
} else {
269+
$false
264270
}
265271

266272
# latest, and we have latest

PSDepend/PSDependScripts/Package.ps1

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,10 +184,29 @@ if($Existing)
184184
return $null
185185
}
186186

187+
$SourceVersion = (& $GetSourceVersion)
188+
[System.Version]$parsedExistingVersion = $null
189+
[System.Version]$parsedSourceVersion = $null
190+
[System.Management.Automation.SemanticVersion]$parsedExistingSemanticVersion = $null
191+
[System.Management.Automation.SemanticVersion]$parsedSourceSemanticVersion = $null
192+
$isSourceVersionLessEquals = if (
193+
[System.Management.Automation.SemanticVersion]::TryParse([string]$ExistingVersion, [ref]$parsedExistingSemanticVersion) -and
194+
[System.Management.Automation.SemanticVersion]::TryParse([string]$SourceVersion, [ref]$parsedSourceSemanticVersion)
195+
) {
196+
$parsedSourceSemanticVersion -le $parsedExistingSemanticVersion
197+
} elseif (
198+
[System.Version]::TryParse([string]$ExistingVersion, [ref]$parsedExistingVersion) -and
199+
[System.Version]::TryParse([string]$SourceVersion, [ref]$parsedSourceVersion)
200+
) {
201+
$parsedSourceVersion -le $parsedExistingVersion
202+
} else {
203+
$false
204+
}
205+
187206
# latest, and we have latest
188207
if( $Version -and
189208
($Version -eq 'latest' -or $Version -like '') -and
190-
($SourceVersion = (& $GetSourceVersion)) -le $ExistingVersion
209+
$isSourceVersionLessEquals
191210
)
192211
{
193212
Write-Verbose "You have the latest version of [$Name], with installed version [$ExistingVersion] and package source version [$SourceVersion]"

Tests/PSGalleryModule.Type.Tests.ps1

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,21 @@ Describe 'PSGalleryModule script' {
119119
}
120120
}
121121

122+
Context 'Latest version comparison' {
123+
It 'Installs when installed version 2.8.0 is behind gallery version 2.10.0' {
124+
InModuleScope PSDepend {
125+
Mock Get-Module { [PSCustomObject]@{ Name = 'TestModule'; Version = [version]'2.8.0' } } -ParameterFilter { $ListAvailable }
126+
Mock Find-Module { [PSCustomObject]@{ Name = 'TestModule'; Version = [version]'2.10.0' } }
127+
}
128+
$dep = New-PSDependFixture -DependencyName 'TestModule' -Version 'latest'
129+
InModuleScope PSDepend -Parameters @{ Dep = $dep; ScriptPath = $script:ScriptPath } {
130+
& $ScriptPath -Dependency $Dep
131+
}
132+
133+
Should -Invoke -CommandName Install-Module -ModuleName PSDepend -Times 1
134+
}
135+
}
136+
122137
Context 'Target as path uses Save-Module instead of Install-Module' {
123138
It 'Calls Save-Module with the target path' {
124139
$savePath = (New-Item 'TestDrive:/save' -ItemType Directory -Force).FullName

Tests/Package.Type.Tests.ps1

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,19 @@ Describe 'Package script' {
6363
}
6464
} | Should -Throw -ExpectedMessage '*Nuget*Target*'
6565
}
66+
67+
It 'Installs when installed version 2.8.0 is behind source version 2.10.0 and latest is requested' {
68+
$targetDir = (New-Item 'TestDrive:/pkg3' -ItemType Directory -Force).FullName
69+
InModuleScope PSDepend {
70+
Mock Get-Package { [PSCustomObject]@{ Name = 'jquery'; Version = [version]'2.8.0' } }
71+
Mock Find-Package { [PSCustomObject]@{ Name = 'jquery'; Version = [version]'2.10.0' } }
72+
}
73+
74+
$dep = New-PSDependFixture -DependencyName 'jquery' -DependencyType 'Package' -Target $targetDir -Source 'nuget.org' -Version 'latest'
75+
InModuleScope PSDepend -Parameters @{ Dep = $dep; ScriptPath = $script:ScriptPath } {
76+
& $ScriptPath -Dependency $Dep
77+
}
78+
79+
Should -Invoke -CommandName Install-Package -ModuleName PSDepend -Times 1
80+
}
6681
}

0 commit comments

Comments
 (0)