Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 40 additions & 31 deletions doc/ReleaseNotes.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,40 @@
## New in v1.29

# New Feature: Source Priority

> [!NOTE]
> Experimental under `sourcePriority`; defaulted to disabled.

With this feature, one can assign a numerical priority to sources when added or later through the `source edit`
command. Sources with higher priority are sorted first in the list of sources, which results in them getting put first
in the results if other things are equal.

> [!TIP]
> Search result ordering in winget is currently based on these values in this order:
> 1. Match quality (how well a valid field matches the search request)
> 2. Match field (which field was matched against the search request)
> 3. Source order (was always relevant, but with priority you can more easily affect this)

Beyond the ability to slightly affect the result ordering, commands that primarily target available packages
(largely `install`) will now prefer to use a single result from a source with higher priority rather than prompting for
disambiguation from the user. Said another way, if multiple sources return results but only one of those sources has
the highest priority value (and it returned only one result) then that package will be used rather than giving a
"multiple packages were found" error. This has been applied to both winget CLI and PowerShell module commands.

### REST result match criteria update

Along with the source priority change, the results from REST sources (like `msstore`) now attempt to correctly set the
match criteria that factor into the result ordering. This will prevent them from being sorted to the top automatically.

## Bug Fixes

<!-- Nothing yet! -->
## New in v1.29

# New Feature: Filter List and Search command by install scope

This adds the ability to filter the list returned by the `winget list` and `winget search` commands by the install scope
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

list already accepted scope.

using the `--scope` parameter. Valid scope values are `user` and `machine`. If the parameter is not given, any install
scopes are permitted.

> [!TIP]
> You can combine parameters for the `--source` and `--scope` parameters when filtering.

# New Feature: Source Priority

> [!NOTE]
> Experimental under `sourcePriority`; defaulted to disabled.

With this feature, one can assign a numerical priority to sources when added or later through the `source edit`
command. Sources with higher priority are sorted first in the list of sources, which results in them getting put first
in the results if other things are equal.

> [!TIP]
> Search result ordering in winget is currently based on these values in this order:
> 1. Match quality (how well a valid field matches the search request)
> 2. Match field (which field was matched against the search request)
> 3. Source order (was always relevant, but with priority you can more easily affect this)

Beyond the ability to slightly affect the result ordering, commands that primarily target available packages
(largely `install`) will now prefer to use a single result from a source with higher priority rather than prompting for
disambiguation from the user. Said another way, if multiple sources return results but only one of those sources has
the highest priority value (and it returned only one result) then that package will be used rather than giving a
"multiple packages were found" error. This has been applied to both winget CLI and PowerShell module commands.

### REST result match criteria update

Along with the source priority change, the results from REST sources (like `msstore`) now attempt to correctly set the
match criteria that factor into the result ordering. This will prevent them from being sorted to the top automatically.

## Bug Fixes

> 1. Prior to this version, it was permitted to provide a `--source` filter for the `winget list` command, however the parameter was ignored. Now if a filter is provided packages will be check before being returned from the `winget list` command.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
> 1. Prior to this version, it was permitted to provide a `--source` filter for the `winget list` command, however the parameter was ignored. Now if a filter is provided packages will be check before being returned from the `winget list` command.
> 1. Prior to this version, it was permitted to provide a `--source` filter for the `winget list` command, however the parameter was used only to limit the sources to correlate with. Now, if a filter is provided, packages will be filtered before being output from the `winget list` command.

This is false; the parameter was used inconsistently from how it would seem most people expected (but very consistently with the rest of the command workflows).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When calling the Powershell API, it sure doesn't seem to filter by scope. My goal is to find all the user-scoped, winget-installed packages and reinstall them as machine-scoped if possible. Trying to script in Powershell...

1 change: 1 addition & 0 deletions src/AppInstallerCLICore/Commands/ListCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ namespace AppInstaller::CLI
case Execution::Args::Type::Name:
case Execution::Args::Type::Moniker:
case Execution::Args::Type::Source:
case Execution::Args::Type::InstallScope:
case Execution::Args::Type::Tag:
case Execution::Args::Type::Command:
context <<
Expand Down
6 changes: 4 additions & 2 deletions src/AppInstallerCLICore/Commands/SearchCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ namespace AppInstaller::CLI
Argument::ForType(Execution::Args::Type::Tag),
Argument::ForType(Execution::Args::Type::Command),
Argument::ForType(Execution::Args::Type::Source),
Argument{ Execution::Args::Type::InstallScope, Resource::String::InstalledScopeArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help },
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Argument{ Execution::Args::Type::InstallScope, Resource::String::InstalledScopeArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help },
Argument{ Execution::Args::Type::InstallScope, Resource::String::InstallScopeDescription, ArgumentType::Standard, Argument::Visibility::Help },

Additionally, just accepting the parameter is unlikely to have the desired effect on the downstream workflow. search in particular intentionally avoids accessing the manifest, which is currently the only way to know available scopes and thus filter the results.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point. I was really only concerned with pulling a list to make an script to do an automated "user" to "machine" reinstall. I'll pull the search changes :)

Argument::ForType(Execution::Args::Type::Count),
Argument::ForType(Execution::Args::Type::Exact),
Argument::ForType(Execution::Args::Type::CustomHeader),
Expand Down Expand Up @@ -59,6 +60,7 @@ namespace AppInstaller::CLI
case Execution::Args::Type::Tag:
case Execution::Args::Type::Command:
case Execution::Args::Type::Source:
case Execution::Args::Type::InstallScope:
context <<
Workflow::CompleteWithSingleSemanticsForValue(valueType);
break;
Expand Down Expand Up @@ -93,10 +95,10 @@ namespace AppInstaller::CLI
}
else
{
context <<
context <<
Workflow::EnsureMatchesFromSearchResult(OperationType::Search) <<
Workflow::ReportSearchResult;
}

}
}
Original file line number Diff line number Diff line change
@@ -1,133 +1,141 @@
Function Get-WinGetPackage{
<#
.SYNOPSIS
Gets installed packages on the local system. displays the packages installed on the system, as well as whether an update is available.
Additional options can be provided to filter the output, much like the search command.

.DESCRIPTION
By running this cmdlet with the required inputs, it will retrieve the packages installed on the local system.

.PARAMETER Filter
Used to search across multiple fields of the package.

.PARAMETER Id
Used to specify the Id of the package

.PARAMETER Name
Used to specify the Name of the package

.PARAMETER Moniker
Used to specify the Moniker of the package

.PARAMETER Tag
Used to specify the Tag of the package

.PARAMETER Command
Used to specify the Command of the package

.PARAMETER Count
Used to specify the maximum number of packages to return

.PARAMETER Exact
Used to specify an exact match for any parameters provided. Many of the other parameters may be used for case-insensitive substring matches if Exact is not specified.

.PARAMETER Source
Name of the Windows Package Manager private source. Can be identified by running: "Get-WinGetSource" and using the source Name

.PARAMETER Header
Used to specify the value to pass as the "Windows-Package-Manager" HTTP header for a REST source.

.PARAMETER AcceptSourceAgreement
Used to accept any source agreements required by a REST source.

.EXAMPLE
Get-WinGetPackage -id "Publisher.Package"

This example expects only a single configured REST source with a package containing "Publisher.Package" as a valid identifier.

.EXAMPLE
Get-WinGetPackage -id "Publisher.Package" -source "Private"

This example expects the REST source named "Private" with a package containing "Publisher.Package" as a valid identifier.

.EXAMPLE
Get-WinGetPackage -Name "Package"

This example expects the REST source named "Private" with a package containing "Package" as a valid name.
#>

PARAM(
[Parameter(Position=0)] $Filter,
[Parameter()] $Name,
[Parameter()] $Id,
[Parameter()] $Moniker,
[Parameter()] $Tag,
[Parameter()] $Source,
[Parameter()] $Command,
[Parameter()] [ValidateRange(1, [int]::maxvalue)][int]$Count,
[Parameter()] [switch]$Exact,
[Parameter()] [ValidateLength(1, 1024)]$Header,
[Parameter()] [switch]$AcceptSourceAgreement
)
BEGIN
{
[string[]] $WinGetArgs = @("List")
[WinGetPackage[]]$Result = @()
[string[]] $IndexTitles = @("Name", "Id", "Version", "Available", "Source")

if($Filter){
## Search across Name, ID, moniker, and tags
$WinGetArgs += $Filter
}
if($PSBoundParameters.ContainsKey('Name')){
## Search for the Name
$WinGetArgs += "--Name", $Name.Replace("…", "")
}
if($PSBoundParameters.ContainsKey('Id')){
## Search for the ID
$WinGetArgs += "--Id", $Id.Replace("…", "")
}
if($PSBoundParameters.ContainsKey('Moniker')){
## Search for the Moniker
$WinGetArgs += "--Moniker", $Moniker.Replace("…", "")
}
if($PSBoundParameters.ContainsKey('Tag')){
## Search for the Tag
$WinGetArgs += "--Tag", $Tag.Replace("…", "")
}
if($PSBoundParameters.ContainsKey('Source')){
## Search for the Source
$WinGetArgs += "--Source", $Source.Replace("…", "")
}
if($PSBoundParameters.ContainsKey('Count')){
## Specify the number of results to return
$WinGetArgs += "--Count", $Count
}
if($Exact){
## Search using exact values specified (case-sensitive)
$WinGetArgs += "--Exact"
}
if($PSBoundParameters.ContainsKey('Header')){
## Pass the value specified as the Windows-Package-Manager HTTP header
$WinGetArgs += "--header", $Header
}
if($AcceptSourceAgreement){
## Accept source agreements
$WinGetArgs += "--accept-source-agreements"
}
}
PROCESS
{
$List = Invoke-WinGetCommand -WinGetArgs $WinGetArgs -IndexTitles $IndexTitles

foreach ($Obj in $List) {
$Result += [WinGetPackage]::New($Obj)
}
}
END
{
return $Result
}
}

Export-ModuleMember -Function Get-WinGetPackage
Function Get-WinGetPackage{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is not used; the PowerShell is all C# in \src\PowerShell.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like that should be removed then? Seems really confusing.

<#
.SYNOPSIS
Gets installed packages on the local system. displays the packages installed on the system, as well as whether an update is available.
Additional options can be provided to filter the output, much like the search command.

.DESCRIPTION
By running this cmdlet with the required inputs, it will retrieve the packages installed on the local system.

.PARAMETER Filter
Used to search across multiple fields of the package.

.PARAMETER Id
Used to specify the Id of the package

.PARAMETER Name
Used to specify the Name of the package

.PARAMETER Moniker
Used to specify the Moniker of the package

.PARAMETER Tag
Used to specify the Tag of the package

.PARAMETER Command
Used to specify the Command of the package

.PARAMETER Count
Used to specify the maximum number of packages to return

.PARAMETER Exact
Used to specify an exact match for any parameters provided. Many of the other parameters may be used for case-insensitive substring matches if Exact is not specified.

.PARAMETER Source
Name of the Windows Package Manager private source. Can be identified by running: "Get-WinGetSource" and using the source Name

.PARAMETER Scope
Used to specify the Scope of the Windows Package Manager packages to return. Can be either "User" or "Machine". If not specified, packages from both scopes will be returned.

.PARAMETER Header
Used to specify the value to pass as the "Windows-Package-Manager" HTTP header for a REST source.

.PARAMETER AcceptSourceAgreement
Used to accept any source agreements required by a REST source.

.EXAMPLE
Get-WinGetPackage -id "Publisher.Package"

This example expects only a single configured REST source with a package containing "Publisher.Package" as a valid identifier.

.EXAMPLE
Get-WinGetPackage -id "Publisher.Package" -source "Private"

This example expects the REST source named "Private" with a package containing "Publisher.Package" as a valid identifier.

.EXAMPLE
Get-WinGetPackage -Name "Package"

This example expects the REST source named "Private" with a package containing "Package" as a valid name.
#>

PARAM(
[Parameter(Position=0)] $Filter,
[Parameter()] $Name,
[Parameter()] $Id,
[Parameter()] $Moniker,
[Parameter()] $Tag,
[Parameter()] $Source,
[Parameter()] $Scope,
[Parameter()] $Command,
[Parameter()] [ValidateRange(1, [int]::maxvalue)][int]$Count,
[Parameter()] [switch]$Exact,
[Parameter()] [ValidateLength(1, 1024)]$Header,
[Parameter()] [switch]$AcceptSourceAgreement
)
BEGIN
{
[string[]] $WinGetArgs = @("List")
[WinGetPackage[]]$Result = @()
[string[]] $IndexTitles = @("Name", "Id", "Version", "Available", "Source")

if($Filter){
## Search across Name, ID, moniker, and tags
$WinGetArgs += $Filter
}
if($PSBoundParameters.ContainsKey('Name')){
## Search for the Name
$WinGetArgs += "--Name", $Name.Replace("…", "")
}
if($PSBoundParameters.ContainsKey('Id')){
## Search for the ID
$WinGetArgs += "--Id", $Id.Replace("…", "")
}
if($PSBoundParameters.ContainsKey('Moniker')){
## Search for the Moniker
$WinGetArgs += "--Moniker", $Moniker.Replace("…", "")
}
if($PSBoundParameters.ContainsKey('Tag')){
## Search for the Tag
$WinGetArgs += "--Tag", $Tag.Replace("…", "")
}
if($PSBoundParameters.ContainsKey('Source')){
## Search for the Source
$WinGetArgs += "--Source", $Source.Replace("…", "")
}
if($PSBoundParameters.ContainsKey('Scope')){
## Search for the Scope
$WinGetArgs += "--Scope", $Scope.Replace("…", "")
}
if($PSBoundParameters.ContainsKey('Count')){
## Specify the number of results to return
$WinGetArgs += "--Count", $Count
}
if($Exact){
## Search using exact values specified (case-sensitive)
$WinGetArgs += "--Exact"
}
if($PSBoundParameters.ContainsKey('Header')){
## Pass the value specified as the Windows-Package-Manager HTTP header
$WinGetArgs += "--header", $Header
}
if($AcceptSourceAgreement){
## Accept source agreements
$WinGetArgs += "--accept-source-agreements"
}
}
PROCESS
{
$List = Invoke-WinGetCommand -WinGetArgs $WinGetArgs -IndexTitles $IndexTitles

foreach ($Obj in $List) {
$Result += [WinGetPackage]::New($Obj)
}
}
END
{
return $Result
}
}

Export-ModuleMember -Function Get-WinGetPackage