winget-cli
winget-cli copied to clipboard
SearchForSingle versus SearchForMany leads to confusing results sometimes
As a user, I find the difference between
SearchSourceForMany
andSearchSourceForSingle
quite confusing. Take a look at this for example -PS C:\WINDOWS\system32> winget search resourcehacker Name Id Version --------------------------------------------------- Resource Hacker AngusJohnson.ResourceHacker 5.1.8 PS C:\WINDOWS\system32> winget show resourcehacker No package found matching input criteria.
Search clearly returned a single result, so why wouldn't show also find that single result? Is this actually a bug in
SearchSourceForSingle
?_Originally posted by @Trenly in https://github.com/microsoft/winget-cli/pull/2847#discussion_r1068944891
SearchForMany searches more fields with
substring
search, SearchForSingle on the other hand, searches only PackageName, Id, Moniker, PackageFamilyName and ProductCode withCaseInsensitive
search, which is more strict and less likely to return multiple results.
Originally posted by @yao-msft in https://github.com/microsoft/winget-cli/pull/2847#discussion_r1068954278
Feature Request
There are times when SearchForMany will return a single package. When it does, it can make moving from a command like winget search resourcehacker
(which returns a single result and uses SearchForMany) to a command like winget install resourcehacker
(which returns no results and uses SearchForSingle) very frustrating for users.
Implemetation
My first thought is to start with a search for many. If search for many returns only one result, use that result. If search for many returns multiple results, then fallback to search for single. One downside to this is that if there is only 1 package returned from search for many, it has a higher likelihood of not being the package the user intended due to the additional fields being considered in search.
Second thought is to add a setting for a default query. Neutral/Unset would be the current behavior - some commands use search for single, others use search for many; Strict could be always using search for single; Broad could be always using search for many
Third thought would be to instead have an argument that could be added to make the search for single a bit less restrictive, perhaps using a substring search instead of a case insensitive search while still ignoring the additional fields considered by a search for many
One downside to this is that if there is only 1 package returned from search for many, it has a higher likelihood of not being the package the user intended due to the additional fields being considered in search.
Yes. This is one of the main reasons we are strict for SearchForSingle. SearchForSingle means "we are quite certain this is the package" because installation will follow and it is an operation that is considered to change machine state.
We actually made this decision after many complaints about unintentional installation when winget first preview released. We don't want user to search for "foo" then somehow "foobar" gets installed even if "foobar" may be the only package returned in the repo. The actual package "foo" may not be added to the repo yet. Substring search is low confidence for finding a package intended. I would argue against using any substring search for SearchForSingle, and against trying SearchForMany for winget install.
On the other hand, using CaseInsensitive search has its advantages too. It will easily differentiate Microsoft.Team vs. Microsoft.Teams.Preview. This is also a decision made during first preview release after we received many complaints about "too many packages" in winget install without using --exact.
I can appreciate those sentiments. It certainly is a fine balance. I agree that "foobar" wouldn't want to be installed if it was the only one unless that was truly the user intent. On the other hand, there are many times where it is user intent to install foo bar, which can also be frustrating.
I also agree that using the broad search for something like teams
would return too many results and be confusing. But, looking at the actual search results returned, a majority of them are because of the tags. But, your example teams is also a great example of how search for single can also be a little too enthusiastic (for some people). There are certainly some users who would like to see that there are various versions of Teams
in the repo.
I suppose the request here is for more configurability, and to have a "middle ground" that isn't as strict as the current search for single but also isn't as broad as the search for many
Going in a completely different direction.. What if instead of modifying the search behavior to match expectations, we add some messaging to set the expectations?
For example, add a loose match arg to install, and if we find no results show a message like "this arg may find more results, but it is more likely to provide false matches." And then in search if we find a single result, add a message like "this is a loose match search, the same query may produce no search results on commands that require more exact matching."
Going in a completely different direction.. What if instead of modifying the search behavior to match expectations, we add some messaging to set the expectations?
For example, add a loose match arg to install, and if we find no results show a message like "this arg may find more results, but it is more likely to provide false matches." And then in search if we find a single result, add a message like "this is a loose match search, the same query may produce no search results on commands that require more exact matching."
I think that's what I was trying to get at, just didn't know how to phrase it
I've been thinking a bit more broadly about WinGet having a pair of UX (User Experience) modes. The current mode would be the default behavior. More precise / strict requirements for users. The new mode would be more "interactive" (not to be confused with interactive install). It would have more prompts and could reduce the typing. It's similar to what we've been working on with:
- https://github.com/microsoft/winget-cli/issues/1830
Hi i'm coming from the mentioned topic.
I second the idea of a "loose search" argument, but it would also be cool if it could actually be used, eg. to uninstall multiple packages (maybe with a wildcard?):
PS C:\> winget list python
Name Id Version Available Source
------------------------------------------------------------------------------------------
Python 3.7.7 (32-bit) Python.Python.3.7 3.7.7 3.7.9 winget
Python Launcher {0E6EEAC9-4913-4C2F-B7D2-761B27C35D7C} 3.11.7966.0
Python 3.10.8 (64-bit) Python.Python.3.7 > 3.7.9 winget
Python 3.11.0 (64-bit) Python.Python.3.7 > 3.7.9 winget
Python 3.7.9 (64-bit) Python.Python.3.7 3.7.9 winget
PS C:\> winget uninstall python
No installed package found matching input criteria.
PS C:\> winget uninstall python*
No installed package found matching input criteria.
(here for example i'm trying to obliterate all traces of python from my system)
Would it be possible to add a switch to show the actual filters used internally by the search routine? Like PSWindowsUpdate's -ShowPreSearchCriteria
:
PS C:\> Get-WindowsUpdate -WindowsUpdate -UpdateType Driver -IsInstalled -ShowPreSearchCriteria -Verbose
PreSearchCriteria: IsInstalled = 0 and Type = 'Driver' and IsHidden = 0
VERBOSE: MG-PC: Connecting to Windows Update server.Please wait...
VERBOSE: Found[1] Updates in pre search criteria
VERBOSE: Found[1] Updates in post search criteria
Also, a clarification about the order of filters (eg. --id
coming first, --version
later) would be helpful. For example the aforementioned PSWindowsUpdate
package makes the distinction between what it calls Pre
and Post
search criteria very clear:
- https://gist.github.com/aetonsi/233461c7d9f336e24acfdbf2a7b32a59#file-man_get-windowsupdate-L15
- https://gist.github.com/aetonsi/233461c7d9f336e24acfdbf2a7b32a59#file-man_get-windowsupdate-L514
In any case, more messaging would be useful
thanks