Skip to content

[Settings] Add sort field and direction types for output ordering#6176

Closed
Madhusudhan-MSFT wants to merge 4 commits intomicrosoft:masterfrom
Madhusudhan-MSFT:user/masudars/list-sort-settings
Closed

[Settings] Add sort field and direction types for output ordering#6176
Madhusudhan-MSFT wants to merge 4 commits intomicrosoft:masterfrom
Madhusudhan-MSFT:user/masudars/list-sort-settings

Conversation

@Madhusudhan-MSFT
Copy link
Copy Markdown
Contributor

@Madhusudhan-MSFT Madhusudhan-MSFT commented Apr 25, 2026

Summary

Add settings infrastructure for configurable output sorting in winget list. This is
part 1 of a 3-part stack that lays the type system and settings foundation without
changing any runtime behavior.

Part of #4238

Changes

  • SortField and SortDirection enums: Add SortField (Relevance, Name, Id, Version,
    Source, Available) and SortDirection (Ascending, Descending) to the settings type
    system. Relevance is internal-only and not exposed as a valid settings value.
  • Settings entries: Register OutputSortOrder and OutputSortDirection with typed
    validation that maps JSON string values to enums using case-insensitive comparison.
    Default sort order is [Name] ascending. Invalid field names reject the entire
    setting and fall back to default.
  • JSON schema: Extend settings.schema.0.2.json with an output section containing
    sortOrder (string array) and sortDirection (string enum with ascending default).
  • Static constexpr pattern: String constants for field name and direction comparisons
    follow the established static constexpr std::string_view pattern used by
    NetworkDownloader, LoggingLevelPreference, and other existing validators.

Impact

  • No behavioral change — settings are defined but not yet consumed by any command or
    workflow. Existing winget list output remains unchanged.
  • Users who edit settings.json to add output.sortOrder or output.sortDirection
    will have their values validated and stored, but the values will not take effect
    until the sort logic is wired in a follow-up PR.

How Validated

  • Unit tests added: 16 test sections across SettingOutputSortOrder and
    SettingOutputSortDirection test cases covering default values, single and multi-field
    configurations, case insensitivity, empty array, invalid fields, mixed valid/invalid,
    and wrong JSON types (62 assertions total).
  • Compilation verified for AppInstallerCommonCore and AppInstallerCLITests.

Follow-up

This PR is part 1 of a 3-PR stack:

  • PR1 (this): Settings types and schema
  • PR2: CLI arguments (--sort, --ascending, --descending)
  • PR3: Sort logic wiring, ConvertToSortField shared parser, and comprehensive tests
Microsoft Reviewers: Open in CodeFlow

…gs infrastructure

## Summary

Introduce configurable output sorting for `winget list` as part of issue
the sorting feature request. This is part 1 of a 3-PR stack that lays the
type system and settings foundation without changing any runtime behavior.

## Changes

- **SortField and SortDirection enums**: Add `SortField` (Relevance, Name, Id,
  Version, Source, Available) and `SortDirection` (Ascending, Descending) to
  the settings type system. Relevance is internal-only and not exposed as a
  valid settings value.
- **Settings entries**: Register `OutputSortOrder` and `OutputSortDirection`
  with typed validation that maps JSON string values to enums using
  case-insensitive comparison. Default sort order is `[Name]` ascending.
  Invalid field names reject the entire setting and fall back to default.
- **JSON schema**: Extend `settings.schema.0.2.json` with an `output`
  section containing `sortOrder` (string array) and `sortDirection` (string
  enum with ascending default).
- **Unit tests**: Add 16 test sections covering default values, single and
  multi-field configurations, case insensitivity, empty array (disables
  sorting), invalid fields, mixed valid/invalid, and wrong JSON types.

## Impact

- No behavioral change ΓÇö settings are defined but not yet consumed by any
  command or workflow. Existing `winget list` output remains unchanged.
- Users who edit `settings.json` to add `output.sortOrder` or
  `output.sortDirection` will have their values validated and stored, but
  the values will not take effect until PR3 wires the sort logic.

## How Validated

- Unit tests added (16 test sections across SettingOutputSortOrder and
  SettingOutputSortDirection test cases)
- Compilation verified via msbuild for AppInstallerCommonCore and
  AppInstallerCLITests (compile-only)
…dators

Follow established codebase pattern (NetworkDownloader, LoggingLevel) of
declaring static constexpr std::string_view variables for string comparisons
instead of inline string literals.
@Trenly
Copy link
Copy Markdown
Contributor

Trenly commented Apr 25, 2026

Relevance is internal-only and not exposed as a valid settings value.

Is there a reason not to expose this? It feels like some users may specifically want this like if they want to sort by Source then by Relevance

REQUIRE(sortOrder[0] == SortField::Name);
REQUIRE(userSettingTest.GetWarnings().size() == 1);
}
SECTION("Wrong type - number in array")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd also appreciate a test case for duplicate values, something like ["name", "id", "Name"]

Madhusudhan-MSFT added a commit to Madhusudhan-MSFT/winget-cli that referenced this pull request Apr 27, 2026
Add test case verifying behavior when duplicate field names appear in
sortOrder settings (e.g., ["name", "id", "Name"]). Duplicates are
accepted and preserved — case-insensitive matching maps both "name"
and "Name" to SortField::Name.

Addresses reviewer feedback from PR microsoft#6176.
@github-actions

This comment has been minimized.

Add test case verifying behavior when duplicate field names appear in
sortOrder settings (e.g., ["name", "id", "Name"]). Duplicates are
accepted and preserved — case-insensitive matching maps both "name"
and "Name" to SortField::Name.

Addresses reviewer feedback from PR microsoft#6176.
@Madhusudhan-MSFT Madhusudhan-MSFT force-pushed the user/masudars/list-sort-settings branch from ec489c4 to 184cacd Compare April 27, 2026 17:11
@JohnMcPMS

This comment was marked as duplicate.

@JohnMcPMS JohnMcPMS closed this Apr 27, 2026
@JohnMcPMS JohnMcPMS reopened this Apr 27, 2026
@JohnMcPMS
Copy link
Copy Markdown
Member

Sorry, misclick...

@Madhusudhan-MSFT
Copy link
Copy Markdown
Contributor Author

Good question @Trenlyrelevance means "preserve the current natural ordering" (i.e., don't re-sort). It's internal-only today for two reasons:

  1. sortOrder: ["relevance"] would be a no-op — identical to having no sort setting at all
  2. Combining it with other fields (e.g., ["source", "relevance"]) isn't meaningful — once a primary sort reshuffles results, the original ordering is lost, so relevance as a tiebreaker would be non-deterministic and potentially confusing

If we were to expose it, it would only make sense as the sole value (e.g., sortOrder: ["relevance"]) to explicitly opt out of sorting — not combined with other fields.

@denelon — would you like us to expose relevance as a valid settings value (restricted to standalone use), or keep it internal-only?

Comment thread src/AppInstallerCommonCore/Public/winget/UserSettings.h Outdated
Comment thread src/AppInstallerCommonCore/Public/winget/UserSettings.h Outdated
Comment thread src/AppInstallerCommonCore/UserSettings.cpp Outdated
@denelon
Copy link
Copy Markdown
Collaborator

denelon commented Apr 27, 2026

I like the idea of exposing "relevance" since someone might want to have that documented and be able to put it in their settings.

… relevance, lowercase-once

- Change OutputSortOrder default from [Name] to empty vector (sentinel for
  context-aware defaults: relevance when query, Name when no query)
- Make Relevance a publicly visible sort field in settings and schema
- Refactor OutputSortOrder validator to ToLower once then compare with ==
- Update tests for new default, add relevance field test section
@Madhusudhan-MSFT Madhusudhan-MSFT marked this pull request as ready for review April 27, 2026 18:45
@Madhusudhan-MSFT Madhusudhan-MSFT requested a review from a team as a code owner April 27, 2026 18:45
@Trenly
Copy link
Copy Markdown
Contributor

Trenly commented Apr 27, 2026

If we were to expose it, it would only make sense as the sole value (e.g., sortOrder: ["relevance"]) to explicitly opt out of sorting — not combined with other fields.

I suppose it depends on the use case? The 'Source -> Relevance' one makes sense to me, since you may want that as opposed to Source -> Name, but there is also a case where the match strength of several items is the same.

Take, for example, the case where I do winget search <query>. Relevance ordering places monikers first, then IDs, followed by product codes / commands / tags. I could see where a user may want to keep the relevance order there, but in each section have the results sorted by Name so that it would be something like this (Assuming Relevance -> Name)

Name ID Match
This Package Example.One moniker: query
Query Viewer Query.Viewer
Four Example.Four tag: query
Three Example.Three tag: query
Two Example.Two tag: query

@Madhusudhan-MSFT
Copy link
Copy Markdown
Contributor Author

Closing in favor of #6177 which now includes all changes from this PR plus the CLI argument registration. Reviewer feedback to consolidate into a single PR.

@Madhusudhan-MSFT
Copy link
Copy Markdown
Contributor Author

This PR has been closed. All changes have been consolidated into PR #6177.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants