PowerShell / PSResourceGet

PSResourceGet is the package manager for PowerShell
https://www.powershellgallery.com/packages/Microsoft.PowerShell.PSResourceGet
MIT License
489 stars 94 forks source link

PSResourceInfo object does not properly sort versions #459

Open ThomasNieto opened 3 years ago

ThomasNieto commented 3 years ago

Prerequisites

Steps to reproduce

I should be able to sort resources by their version but this does not work as expected. This does not work due to PowerShellGet 3.0.11-beta splitting up semantic versioning into two different properties Version [System.Version] and PrereleaseLabel [String] on the PSResourceInfo type.

PowerShellGet 3.0.11-beta already takes a dependency on Nuget.Versioning.dll which contains [NuGet.Versioning.NuGetVersion] type that can handle traditional [Version] as well as [SemanticVersion].

Related issue https://github.com/PowerShell/PowerShell/issues/2983, https://github.com/PowerShell/PowerShellGet/issues/83

cc: @jaykul

Expected behavior

Should be able to properly sort resources by version.

Actual behavior

Sorting does not take into account semantic versioning.

Error details

No response

Environment data

PS C:\> Get-Module -Name PowerShellGet

ModuleType Version    PreRelease Name                                ExportedCommands
---------- -------    ---------- ----                                ----------------
Binary     3.0.11     beta       PowerShellGet                       {Find-PSResource, Get-InstalledPSResource, Get-PS…

PS C:\> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.2.0-preview.8
PSEdition                      Core
GitCommitId                    7.2.0-preview.8
OS                             Microsoft Windows 10.0.19043
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Visuals

No response

StevenBucher98 commented 3 years ago

Thanks @ThomasNieto! We will make this change soon, we will try to get this in for the next release as well.

StevenBucher98 commented 2 years ago

Hi @ThomasNieto, we are looking at implementing this but are slightly confused by your ask. What is the scenario you would like to see? Is there a particular workflow that you are looking for? and would this be possible with some PowerShell existing commands?

ThomasNieto commented 2 years ago

@StevenBucher98 As a user I want to be able to sort PSResourceInfo objects by their version. In this example below you can see that prerelease (semver) is not being taken into account when sorting by version. The end user should not need know and workaround (write their own semver sorter) to get this working. The type/property should handle this by use case by default. Please let me know if you need further information.

Actual behavior

$stable = Find-PSResource PSReadline -Version 2.1.0
$prerelease = Find-PSResource PSReadline -Version 2.1.0-beta1

PS C:\> $stable, $prerelease | Sort-Object Version

Name       Version Prerelease Description
----       ------- ---------- -----------
PSReadLine 2.1.0.0            Great command line editing in the PowerShell console host
PSReadLine 2.1.0.0 beta1      Great command line editing in the PowerShell console host

PS C:\> $stable, $prerelease | Sort-Object Version -Descending

Name       Version Prerelease Description
----       ------- ---------- -----------
PSReadLine 2.1.0.0            Great command line editing in the PowerShell console host
PSReadLine 2.1.0.0 beta1      Great command line editing in the PowerShell console host

Expected behavior

$stable = Find-PSResource PSReadline -Version 2.1.0
$prerelease = Find-PSResource PSReadline -Version 2.1.0-beta1

PS C:\> $stable, $prerelease | Sort-Object Version

Name       Version Prerelease Description
----       ------- ---------- -----------
PSReadLine 2.1.0.0 beta1      Great command line editing in the PowerShell console host
PSReadLine 2.1.0.0            Great command line editing in the PowerShell console host

PS C:\> $stable, $prerelease | Sort-Object Version -Descending

Name       Version Prerelease Description
----       ------- ---------- -----------
PSReadLine 2.1.0.0            Great command line editing in the PowerShell console host
PSReadLine 2.1.0.0 beta1      Great command line editing in the PowerShell console host

A potential solution is to change Version property from System.Version to NugetVersion type.

$stable = [NuGet.Versioning.NuGetVersion]'2.1.0'
$prerelease = [NuGet.Versioning.NuGetVersion]'2.1.0-beta1'

PS C:\> $stable, $prerelease | Sort-Object

Version         : 2.1.0.0
IsLegacyVersion : False
Revision        : 0
IsSemVer2       : False
OriginalVersion : 2.1.0-beta1
Major           : 2
Minor           : 1
Patch           : 0
ReleaseLabels   : {beta1}
Release         : beta1
IsPrerelease    : True
HasMetadata     : False
Metadata        :

Version         : 2.1.0.0
IsLegacyVersion : False
Revision        : 0
IsSemVer2       : False
OriginalVersion : 2.1.0
Major           : 2
Minor           : 1
Patch           : 0
ReleaseLabels   : {}
Release         :
IsPrerelease    : False
HasMetadata     : False
Metadata        :

PS C:\> $stable, $prerelease | Sort-Object -Descending

Version         : 2.1.0.0
IsLegacyVersion : False
Revision        : 0
IsSemVer2       : False
OriginalVersion : 2.1.0
Major           : 2
Minor           : 1
Patch           : 0
ReleaseLabels   : {}
Release         :
IsPrerelease    : False
HasMetadata     : False
Metadata        :

Version         : 2.1.0.0
IsLegacyVersion : False
Revision        : 0
IsSemVer2       : False
OriginalVersion : 2.1.0-beta1
Major           : 2
Minor           : 1
Patch           : 0
ReleaseLabels   : {beta1}
Release         : beta1
IsPrerelease    : True
HasMetadata     : False
Metadata        :
StevenBucher98 commented 2 years ago

Thanks for the detailed description @ThomasNieto, is this sorting critical to any of your workflows? We really appreciate how detailed you were with this issue report, and we better understand the scenario now.

Jaykul commented 2 years ago

tl;dr: These objects should have a SemanticVersion property so we can sort by that.

To make | Sort Version work the way it's described, you would have to change the Version property.

But let's try to think about this a different way. Imagine that you actually followed SemVer with this module...

Instead of this: image

You would have published:

Name          Version  Prerelease
----          -------  ----------
PowerShellGet 3.0.0.0  beta12    
PowerShellGet 3.0.0.0  beta11    
PowerShellGet 3.0.0.0  beta10    

So, if we had those three packages in a $Modules array and we wanted to invert the sort order so the newest is last, how would we do that? Currently, we can't unless we create a new property to sort by:

Update-TypeData -MemberName SemanticVersion -MemberType ScriptProperty -Value {
  [System.Management.Automation.SemanticVersion]($this.Version, $this.PrereleaseLabel -join "-")
} -TypeName Microsoft.PowerShell.PowerShellGet.UtilClasses.PSResourceInfo 

So that we can do this:

$Modules | Sort SemanticVersion