Winget-cli: winget should install an app if there is an exact match (eg 'git')

Created on 22 May 2020  路  38Comments  路  Source: microsoft/winget-cli

Brief description of your issue

C:\Program Files $ winget install Git
Multiple apps found matching input criteria. Please refine the input.
Name                                    Id                                       Version      Matched
---------------------------------------------------------------------------------------------------------
Git                                     Git.Git                                  2.26.2
Logitech Harmony Remote                 Logitech.Harmony                         1.0.1.308
GitHub Desktop                          GitHub.GitHubDesktop                     2.5.0
GitHub CLI                              GitHub.cli                               0.8.0
Atom                                    GitHub.Atom                              1.45.0
AdobeDigitalEditions                    Adobe.AdobeDigitalEditions               4.5.11
MicrosoftGitCredentialManagerforWindows Microsoft.GitCredentialManagerforWindows 1.20.0
Git Large File Storage                  GitHub.GitLFS                            2.11.0
Git Extensions                          GitExtensionsTeam.GitExtensions          3.3.1
MaxTo                                   DigitalCreations.MaxTo                   2.0.1
Gitter IM                               Gitlab.Gitter.IM                         4.1.0
GitKraken                               Axosoft.GitKraken                        7.0.0
TortoiseGit                             TortoiseGit.TortoiseGit                  2.10.0.2
AppInstallerFileBuilder                 Microsoft.AppInstallerFileBuilder        1.2020.211.0 Tag: GitHub
Sublime Merge                           SublimeHQ.SublimeMerge                   1119         Tag: git

Steps to reproduce

winget install Git

Expected behavior

git installs, as the name is an exact match (case insensitive).

Actual behavior

The error above.

Environment

Windows Package Manager v0.1.41331 Preview
Copyright (c) Microsoft Corporation. All rights reserved.

Windows: Windows.Desktop v10.0.19628.1
Package: Microsoft.DesktopAppInstaller v1.0.41331.0

Links:
  Privacy Statement: https://aka.ms/winget-privacy
  License agreement: https://aka.ms/winget-license
  3rd Party Notices: https://aka.ms/winget-3rdPartyNotice
  Homepage:          https://aka.ms/winget
Issue-Bug

Most helpful comment

"Fall into the pit of success"

Search = case insensitive, non-exact match
Install = case insensitive, exact match.

These should be no brainer commands:
winget install Git
winget install git
winget install discord
winget install Discord

If I type install, exact match should be inferred. If I wanted a search, I would invoke a search.

All 38 comments

I'm having this exact issue with "Powershell" and/or "Microsoft.Powershell", and I have no idea how to actually get the one I want.

I've hit the same issue trying to install Discord. IMHO each package should have a mandatory, unique and case insensitive moniker (or just apply those characteristics to the ID). Basically, the same user experience as brew.sh

@CalvinAllen you can use the -e or --exact switch followed by the package name with correct capitalization and perhaps quote marks if it contains a space

@kipters Thanks, that did the trick!

I suggest trying -? on the commands. Based on that output, this seems to be expected behavior. Without the -e that kipters mentioned, you are asking it to query for that name.

@CalvinAllen you can use the -e or --exact switch followed by the package name with correct capitalization and perhaps quote marks if it contains a space

So we should give user a hint when such things happen. Here is a mock hint.
image

@CalvinAllen you can use the -e or --exact switch followed by the package name with correct capitalization and perhaps quote marks if it contains a space

So we should give user a hint when such things happen. Here is a mock hint.

image

This is exactly what happened to me when I discovered the issue

image

This is exactly what happened to me when I discovered the issue

However, it can be difficult for a newbie to find a such a option.
That's why I added a hint in the mock screenshot, to make this option more discoverable:

Use -e or --exact option if you want a exact match install.

I support it!

Im adding onto this because there is tons of pacakges that have Git in the name but i cant possibly install git even with the exact id Git.Git because Git.GitLFS exists.

Hints aren't as good as what @kipsters suggested:

IMHO each package should have a mandatory, unique and case insensitive moniker (or just apply those characteristics to the ID).

winget install git should install git. Not tell you to that to type winget install git.git or whatever other obscure command.

There's a reason why most popular package managers have short package names.

"Fall into the pit of success"

Search = case insensitive, non-exact match
Install = case insensitive, exact match.

These should be no brainer commands:
winget install Git
winget install git
winget install discord
winget install Discord

If I type install, exact match should be inferred. If I wanted a search, I would invoke a search.

I ran into this today as well, and it was very confusing. 馃憤 to changing something here.

I think it is fine that when you say "install git" it says "which git". However, it should show a message similar to what kipters mentioned, or provide a sequence number against the filtered result and ask us to enter a number.

I'm having this exact issue with "Powershell" and/or "Microsoft.Powershell", and I have no idea how to actually get the one I want.

We're working with the PowerShell team to address some of this with adjustments to the manifests. For now winget install Microsoft.PowerShell -e works (it is case sensitive).

The Id is intended to be the key to disambiguating between packages. It is currently case sensitive. It also doesn't exclude other Id values that are a superset eg. "Git.Git" and "Git.GitLFS" both match for winget install git.git.

I am also thinking the help dialog may benefit from providing an example. I'll build a short spec.

At the moment, when installing apps with multiple search results, the following nomenclature is working perfectly:

winget install --name <appName> -e

Note that the _appName_ is Case Sensitive !

@SubhamK108 that would work even without the --name

@neville-nazerane Yes indeed, it's working absolutely fine even without the --name. I didn't test that before.

When I encountered this error I read the documentation and tried using --id and --version to specify the exact package I wanted. It did not work. The -e flag did not jump out to me in the documentation until I found this thread.

winget-confuse

@kmuncie How about trying...
winget install --name PowerShell -e

Yes, thank you, using -e worked as noted above.

However I think it's important to recognize the failure of the the id and version tags to sufficiently narrow the search in my example. As many have commented above this search and install flow needs some improvement as packages begin multiplying.

This issue is at the top of the backlog for the next iteration - https://github.com/microsoft/winget-cli/milestone/4, and the proposed solution has been documented - https://github.com/microsoft/winget-cli/blob/master/doc/specs/%23292%20-%20winget%20should%20install%20an%20app%20if%20there%20is%20an%20exact%20match.md

(Not actually on this team, just relaying information)

Winget will also try to install a package by its tag (!!!)

Installing nodejs is apparently ambiguous because the package CodeLite.CodeLite includes the NodeJS tag.

PS C:\Users\theLMGN> winget install nodejs
Multiple apps found matching input criteria. Please refine the input.
Name         Id                Version Matched
--------------------------------------------------
Node.js      OpenJS.Nodejs     14.4.0
CodeLite IDE CodeLite.CodeLite 14.0.0  Tag: NodeJS

When I encountered this error I read the documentation and tried using --id and --version to specify the exact package I wanted. It did not work. The -e flag did not jump out to me in the documentation until I found this thread.

winget-confuse

The above example should work. It is more than exact to work without having an -e or --e specified.

Not sure how to code this but for UX next to the simple proposal to add the info line by @KiruyaMomochi the approach is a good thing. Perhaps yellow text color.
Keep it simple. @denelon

I think it's become clear that the use of substring instead of literal matching is not suitable for install, uninstall and upgrade operations as the user knows what he wants. The current behaviour only really makes sense for the search subcomand where you want to search across various metadata fields and optionally refine your search with additional options (name, moniker, etc.).

The current spec only covers the install subcommand.

492 is out to make this better. The short of it is that it requires case insensitive equality on one of Id, Name, or Moniker for install (and show).

I was also thinking of ways to help the user more. My two thoughts so far are:

  1. In the search results, somehow highlight the package(s) that would have been found if search was replaced with install. I'm not sure how to do this in a clear/discoverable way right now though. Fortunately the change in #492 should already sort these rows to the top of the results, so that should help.
  2. If install foo doesn't find anything, do an expanded search to give suggestions. Importantly, do not act on these results, but instead give a 'did you mean one of these?' kind of output.

I don't feel that either of these are strictly required to resolve this issue, and they may not even be something anyone cares about. So looking for feedback on when/if these (or any other) suggestions would make sense to help in the workflow.

I think it is fine that when you say "install git" it says "which git".

I think it is not. Can't be that my script breaks because someone published something between writing it and running it. Plus, do I have to know they published Git and not git? Why? Also the moniker is actually git and what is that even for.

Why will your script break because someone published something in between? There is one command that tries finding a match, installs if it only finds one, and another command that installs the exactly provided id. The latter is clearly intended for your use case, why wouldn't you just use it instead?

@denelon the release is not clear. What exactly is taken into account for an exact match?

The name of the package? Git.Git
The app's moniker? git
Something else?

Why will your script break because someone published something in between?

I guess it matters how easy it is. Short of writing a script it is just quite unfortunate the way it is now I try to install something five times in a row in various way and still nothing happens. And there's at least four concept of identifiers of various kinds which I seriously don't care about and I just don't want Windows to become Linux where it is quite normal to ask for help and get a bible full of switches and not even a good luck reading all that (e.g. curl).

@felipecassiors , the value needs to be a case insensitive match to one of Id, Name, or Moniker by default. If you specify which field with an argument, you can make it even more specific.

winget install git

Will find anything with Id == 'git', Name == 'git', or Moniker == 'git' (where == is case insensitive). You can use the show command to play around with it as it uses the same semantics to find a package.

When writing a script, to guarantee that the target package will be chosen, always use the --id option. Such as:

winget install --id git.git

This will only find a package whose Id == 'git.git', and as the Id is case insensitively unique, there can only be either 0 or 1 of them.

Thanks @JohnMcPMS, this is very clear now.

Yeah, but this still doesn't work.

PS C:\Users\theLMGN> winget install --id GoLang.Go --version 1.14.6
Multiple apps found matching input criteria. Please refine the input.
Name Id                 Version
----------------------------------
Go   GoLang.Go          1.14.6
Go   Golang.Go-Unstable 1.15-beta1

EDIT: I had an older version of WinGet installed, updating it fixed this issue.

@theLMGN , I think that does show an issue with the winget-pkgs repo though. We shouldn't really have let those two packages have the same name, because winget install go won't work right now. Although the real issue is that we are behind where users want to be on support for channels.

I like those thoughts @JohnMcPMS. Real issue no 3 I would say simplify unneeded concepts: install only ever by id and allow ids without dots, remove the concept of moniker and use (display)name and tag only ever in search?

I think everybody is happy to get rid of git.git, Notepad++.Notepad++, GIMP.GIMP, 7zip.7zip etc etc or even ArtifexSoftware.GhostScript, Microsoft.VisualStudioCode, Microsoft.VisualStudio.Community in favor of just say ghostscript, vscode and vscommunity, respectively. That is already quite enough to type.

I agree with @ericwj @denelon could you and the team give some examples where this idea would raise inevitable conflicts with winget install or search?
Imho the name and the version should be matching enough. Thanks for giving us an idea why you implemented the moniker concept.

Was this page helpful?
0 / 5 - 0 ratings