Open denelon opened 4 years ago
Same for the 'show' command. I don't want it to be sorted by the ID but the name.
Currently, is there any way to display all apps alphabetically at all?
I started an implementation of this feature in https://github.com/microsoft/winget-cli/pull/1205.
There is currently a sort order defined by the search itself (as mentioned in the OP). It is currently sorted by (applies to the winget
source; arbitrary REST sources can sort arbitrarily):
Quality here means whether the match was exact, a substring, etc. So this means that winget search git
puts "Git" first as it is the best match due to the case insensitive equality between the name and the search term. Always sorting the entire output by name blindly will lead to results with far less relevance being placed first. For instance, when I run this locally I am seeing a result that is accidentally related because "digital" happens to contain "git" (and tags are lower for sort criteria 2 than names):
FL Studio ImageLine.FLStudio 20.8.3.2304 Tag: digital audio workstation
This would actually be placed before "Git" in the results with name sorting only. I would imagine that the large majority of users searching for "git" are not looking for this at all though. These 4 also fall into the same bucket:
Duplicate Cleaner Pro DigitalVolcanoSoftware.DuplicateClea… 4.1.4
Duplicate Cleaner Free DigitalVolcanoSoftware.DuplicateClea… 4.1.2
APDigitalExams CollegeBoard.APDigitalExams 0.9.1
2021 Digital AP Exams CollegeBoard.2021DigitalAPExams 0.9.4.5
If users still want results to be sorted purely based on name, I would think it best to have a setting rather than change the default (or have a setting and change the default).
I copied the original body of the Issue from a comment, and I never got back around to clarifying. Thanks for jumping in @JohnMcPMS.
Yes, we do need to think about how sorting can impact results.
I think what we currently have is similar to "best-match". I think the ask is an ability to get an alphabetical sort. This may be handled via arguments and/or settings.
winget search terminal
yields interesting results as many packages have "terminal" as one of their "Tag"s.
winget list
is possibly a better candidate for sorting by default.
@JohnMcPMS I see, thanks for explaining! I wasn't aware that there was already some logic for sorting implemented. I fully agree that always sorting by name seems like a step back to what we currently have, at least for the output of winget search
. I guess this feature needs some more thinking then.
Maybe this feature also becomes somewhat obsolete once there are PowerShell cmdlets for winget as you could then just use the sorting available in PowerShell.
+1 for winget list
sorting by name. It's a lot more difficult to use without that.
+1 for
winget list
sorting by name. It's a lot more difficult to use without that.
I could definitely get behind list
with no search parameter sorting alpha by name. That would be fairly easy to achieve internal to the Source implementation so as to not accidentally affect anything else, although might require a bit of plumbing and I'm not exactly sure on whether the SQLite ICU extensions already give us an easy ORDER BY
.
So this is a hack and a half, but in PowerShell it approximates alpha sort by name:
$nameVar = winget list ; $namevar[4..($namevar.length)] | Sort-Object | Format-Table
You lose out on the headers this way.
This is my even uglier (in code) table-formatted version. There's probably a graceful way to do this, but I'm just trying to bang out something that works. I hard-coded the column widths because I felt that some egregiously long names (Microsoft Security Updates primarily) ruined the entire table.
$wingetListOutput = winget list | Where-Object {$_ -notlike "*$([char]0x0008)*" -and $_ -notlike "*----------*"}
$wingetListOutputCSV = $wingetListOutput -replace '[ ]{2,}',','
$wingetListOutputCSV | ConvertFrom-Csv | Sort-Object -Property Name | Format-Table -Property @{ e='Name'; width = 30 }, @{ e='Id'; width = 60 }, @{ e='Version'; width = 20 }, @{ e='Available'; width = 20 }, Source
I'm gonna slap this in an alias and call it a day. Again, it's a frankenscript and it would definitely be best if the functionality were incorporated in WT.
@ehawman-rosenberg I decided to use the lack of alphabetised listing as an opportunity to take a quick look at the PowerShell module called Crescendo (Github: https://github.com/PowerShell/Crescendo):
The PowerShell Crescendo module provides a way to more easily take advantage of the PowerShell pipeline by invoking the native executable, facilitating parameter handling, and converting text output into objects.
but.. I immediately hit the problem that I think you've got, which is the lack of data present in the 'Available' column/property means the table gets jumbled up like this:
I couldn't think of an immediate solution but found this amazing bit of code: https://github.com/iRon7/ConvertFrom-SourceTable/blob/master/ConvertFrom-SourceTable.ps1 which solves the problem (once you've wrapped it into a function
command which is missing).
Example:
$Data = winget list; $Data = $Data | Where-Object {$_ -notlike '*$([char]0x0008)*' }
$Converted = ConvertFrom-SourceTable -InputObject $Data[4..$($Data.Length-1)] -Header $Data[2]
and $Converted
is exactly the kind of array object you'd want. I've stuck the function into a personal PS module where I tend to shove anything that's useful so it's available by default.
Wrapping this up in Crescendo gives a new cmdlet "Invoke-WinGet":
The .json
for the Crescendo code incase anyone wants it, which includes an -Upgrade switch too:
{
"$schema": "https://aka.ms/PowerShell/Crescendo/Schemas/2021-11",
"Commands": [
{
"Verb": "Invoke",
"Noun": "WinGet",
"OriginalName": "winget",
"OriginalCommandElements": [
],
"Parameters": [
{
"Name": "List",
"OriginalName": "list",
"ParameterType": "switch",
"ParameterSetName": [
"list"
],
"Description": "list items",
"Mandatory": false
},
{
"Name": "Upgrade",
"OriginalName": "upgrade",
"ParameterType": "switch",
"ParameterSetName": [
"upgrade"
],
"Description": "list items for upgrade",
"Mandatory": false
}
],
"OutputHandlers": [
{
"ParameterSetName": "list",
"Handler": "param($Data)
$Data = $Data | Where-Object { $_ -match '^[a-zA-Z0-9-]' }
ConvertFrom-SourceTable -InputObject $Data[2..$($Data.Length-1)] -Header $Data[0] | Sort-Object Name
"
},
{
"ParameterSetName": "upgrade",
"Handler": "param($Data)
$Data = $Data | Where-Object { $_ -match '^[a-zA-Z0-9-]' }
ConvertFrom-SourceTable -InputObject $Data[2..$($Data.Length-1)] -Header $Data[0] | Sort-Object Name
"
}
]
}
]
}
and
Export-CrescendoModule -ConfigurationFile "C:\Test\winget.Crescendo.json" -ModuleName "C:\Test\WinGetWrapper.psm1"
Import-Module "C:\Test\WinGetWrapper.psd1"
I find it somewhat amusing that we're using PowerShell to solve this problem when Chocolatey is native PowerShell and does the same thing as WinGet, essentially 😅
EDIT: Tweaked the code returned from winget output so it filters out progress bar lines (which resulted in errors when passing to ConvertFrom-SourceTable
), and added -Upgrade
switch.
@robinmalik you might want to take a look at https://github.com/microsoft/winget-cli/tree/master/tools/PowerShell
I participated in a hackathon to build PowerShell cmdlets. We were considering Crescendo but ended up doing more manual work due to the impedance of our command names vs approved PowerShell Nouns and Verbs. There may be some useful code there, and we would welcome any improvements :)
I'm gonna slap this in an alias and call it a day.
Pardon the n00b question: how do you do that? (Set-Alias
, I know, but I'm struggling with the syntax)
Cheers.
@robinmalik hey there, was curious if you have made any progress on the addition of Crescendo? or if anyone else has been working on a similar solution.
@aycippo They're doing it officially now. In amongst the assets for the latest release there's the module zipped up: https://github.com/microsoft/winget-cli/releases/download/v1.4.10173/Microsoft.WinGet.Client-PSModule.zip
Having just had a very quick look at it, this works: Get-WinGetPackage | Sort Name
.
To filter by those with updates available you have to use the IsUpdateAvailable
property, and not Available
as is shown in the default view by a custom formatting rule:
Get-WinGetPackage | ? { $_.IsUpdateAvailable } | Sort Name
(I wasn't able to pipe to Format-List
to see all data for a single package object because it threw an error Format-List: Exception has been thrown by the target of an invocation.
but I was able to pipe it to Get-Member
to figure that out)
[Policy] Area-Output [Policy] Area-Sorting
@robinmalik do we have an issue covering your finding with the "PowerShell" label?
@denelon I personally haven't created an issue for that encountered error. I can do, if you'd like?
Yes, please. 😊
@denelon Happy to report that having installed the latest version from the PowerShell Gallery (congrats on getting it up there!) that the format-list
issue I saw in the above zipped copy no longer exists :)
I would like the ability to customize the sort order when multiple results are returned.
In addition to arguments like
winget search _foo_ -sort Name
, I would like settings to specify my default preferences.winget list -sort Version
In addition, I would like to have settings to handle results from multiple sources so they can be displayed in a coalesced manner vs. the default where we sort by source based on their order in
winget source list
.