Index every package, and use canonical names for exact matching only - #8
Merged
Merged
Conversation
The detection index excluded packages whose manifests declare neither a product code nor an MSIX package family name, on the grounds that they cannot be matched by code. That also dropped their canonical display name, which is the more broadly useful field: it is what bridges a package ID to its ARP entry, and "Valve.Steam" never matches "Steam" on its own. Those packages were therefore undetectable by any route. Every package now gets an entry. A name-only row costs about 80 bytes. Detection also uses the canonical name from the index as a name candidate. Product codes alone are not sufficient even where the index has them: Chrome's installed product code varies by build, so the three its manifests declare missed a live install of Google Chrome 153.0.8010.52, which the canonical name then matched exactly.
A winget package folder can contain siblings that are not versions. Discord carries x86, arm64, Canary, PTB and Development alongside 144 real versions. The version key ranked those as versions because it simply extracted digits: "x86" yields 86, which outranks the leading component of 1.0.9258 and won the sort, so resolution then looked for an installer manifest inside the x86 folder and threw. Discord.Discord could not be installed at all. Version folders start with a digit, so names that do not are now rejected outright. The original implementation on main filtered on ^\d; that guard was lost when the sort was rewritten to handle non-[Version] formats. Verified: Discord.Discord resolves to 1.0.9258, and x86, arm64, Canary, PTB and Development are rejected while 1.0.9258, v2.1 and 20240101 are kept.
Adding the index's canonical display name to the substring tier as well as the exact tier reported applications that are not installed. Those names are short and generic: "Steam" matched the MSIX package MSTeams and reported Valve.Steam as installed on a machine that has never had it, and "Git" would match "GitHub CLI" the same way. Candidates are now split. Exact comparison uses the supplied name, the custom catalogue display name and the index canonical name. Substring and MSIX name matching use only the first two, which is the behaviour before the canonical name was introduced. Verified against ground truth on a real machine, 8 packages, no failures: 7-Zip, Firefox, Chrome, Zoom, Git and Windows Terminal detected as installed, Steam and Discord as not installed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #7. Three defects found by testing detection against ground truth on a real machine.
Packages with no product code were undetectable
The index excluded packages whose manifests declare neither a product code nor an MSIX package family name, on the grounds that they cannot be matched by code. That also dropped their canonical display name, which is the more broadly useful field — it is what bridges a package ID to its ARP entry, and
Valve.Steamnever matchesSteamon its own. Those packages were undetectable by any route.Every package now gets an entry; a name-only row costs about 80 bytes.
Product codes alone are not sufficient
Chrome's installed product code varies by build. The three its manifests declare did not include
{237809A0-C1B6-3ABE-9AEB-BB2C80AEE802}, the code on a live install of Google Chrome 153.0.8010.52, so detection returnedFalsefor an application plainly present. The canonical name matches it exactly.Detection now uses the index's canonical name as an exact-match candidate.
Canonical names are unsafe as substrings
Adding those names to the substring tier as well reported applications that are not installed:
Steamis a substring of the MSIX packageMSTeams;Gitwould matchGitHub CLIthe same way.Candidates are now split. Exact comparison uses the supplied name, the custom catalogue display name and the index canonical name. Substring and MSIX name matching use only the first two, which is the behaviour before the canonical name existed.
Architecture and channel folders were ranked as versions
A winget package folder can contain siblings that are not versions. Discord carries
x86,arm64,Canary,PTBandDevelopmentalongside 144 real versions.The version key extracted digits, so
x86yielded 86, which outranks the leading component of1.0.9258and won the sort. Resolution then looked for an installer manifest inside thex86folder and threw —Discord.Discordcould not be installed at all.Version folders start with a digit, so names that do not are rejected. The implementation on
mainfiltered on^\d; that guard was lost when the sort was rewritten to handle non-[Version]formats in #2.Verification
Against ground truth on a real machine — 7-Zip, Firefox, Chrome, Zoom, Git and Windows Terminal installed; Steam and Discord not:
Version selection:
x86,arm64,Canary,PTBandDevelopmentrejected;1.0.9258,v2.1and20240101kept.Discord.Discordresolves to 1.0.9258,Valve.Steamto 2.10.91.91,Git.Gitto 2.55.0.3 — none of which are inIndex/Catalog.json, confirming install is not limited to the curated list.