-
Notifications
You must be signed in to change notification settings - Fork 0
m3 alias resolution and regex rules
Status: Planned, reviewed. Tracked by issue #5 and sub-issues #37 through #43. A pre-implementation review found two blockers and several should-fix items, folded into the sections below and into comments on the affected sub-issues.
This plan implements every M3 item that does not depend on another milestone:
- #37: load and validate rules JSON
- #38: embed ordered default alias rules
- #39: resolve aliases by the accepted regex-to-raw priority
- #41: test alias and rule behavior
- #42: select explicit, user, or embedded rules
- #43: finalize canonical documentation
#40 remained open at the time of this plan because an executable test-rule command
requires #53 for command-line parsing and #56 for process dispatch. Those dependencies
were recorded as structured blocked-by relationships. Consequently, parent issue #5 also
remained open after this plan was complete.
Resolved after M6 merged. #56 delivered the presentation itself: runTestRule() in
src/cli/Dispatch.cpp prints file name → matched rule name → alias, which is what #40
asked for. #40 was reviewed against the merged code and closed as already implemented, so
no separate M3 change is outstanding. docs/TODO.md M3's test-rule checkbox is still
unticked and is corrected by M8's #64.
- ADR-0009 is authoritative: the winget COM API does not expose portable command-alias metadata. Alias resolution therefore starts with regex rules and falls back to the raw executable filename.
- The permanently unused
PackageExe::metadataAliasfield is removed. - JSON is parsed with
winrt::Windows::Data::Json, using the existingComApartment. No third-party dependency is introduced. - Regexes use
std::wregexwith ECMAScript grammar, full-filename matching, ordered first-match semantics, numbered captures, and the optionalignorecaseflag. - Resolved aliases must be non-empty
.exefilenames without path separators or dot path components. Reject (not normalize) an empty stem, a replacement that does not end in.exe, and cover extension case-folding explicitly in tests. -
winrt::Windows::Data::Jsonparsesrules.json(per ADR-0005; no header-only parser is introduced), but this requires an initialized apartment at runtime — the known tension already flagged inadr.mdADR-0005 and thecpp-msbuildskill. #37 resolves this tension with a new ADR entry rather than leaving it implicit, and givesRuleSet's own tests aComApartmentfixture. The translation unit that calls intowinrt::Windows::Data::Jsoncarries its own#pragma comment(lib, "runtimeobject.lib")— the existing one inWingetComSource.cpponly propagates into links that pull inWingetComSource.obj, which aRuleSet-only test link need not do. - Matching uses
std::regex_match(whole-string), matching the "full-filename matching" design intent, notstd::regex_search. - Malformed user rules file behavior (resolves the ambiguity in the prior draft of this
page): an absent user rules file (
%LOCALAPPDATA%\syncwingetlink\rules.json) falls through to the embedded defaults — that is the normal, unconfigured state. A present but malformed/invalid user rules file is an error, exit code 3, identical to a broken--rules <path>file. It never silently falls back to embedded defaults, since that would hide a config mistake the user made themselves.
Each sub-issue is delivered as a separate branch and pull request, based on main after the preceding dependency is merged:
- #37 adds
rules/RuleSet, typed configuration errors, JSON parsing, and validation. Parsing is string-based (parse(text) -> rules); file I/O is left to #42's source selection so these tests stay filesystem-free. Also adds the ADR entry for the WinRT-Json/apartment decision above, theComApartmenttest fixture, and theruntimeobject.libpragma in the JSON-parsing translation unit. - #38 adds embedded Rust-target-triple and version/architecture rules, plus at least one
negative test proving the broad
strip-version-and-archdefault does not over-match a file name it should leave alone. - #39 adds
core/AliasResolver, removes the dead metadata field, and records the M3 architecture decision. RemovingPackageExe::metadataAliasalso requires removing or rewritingtests/ExecutableScannerTests.cpp'smetadataAliasIsNotSuppliedByTheFilesystem, which asserts on that field directly and would otherwise fail to compile under/W4 /WX. - #42 adds source selection in the order explicit rules, user rules, then embedded
rules. An explicitly selected (
--rules <path>) file that is missing, unreadable, or invalid is an error (exit 3) and never silently falls through. The auto-discovered user rules file follows the absent/malformed distinction above. - #41 adds the cross-component regression matrix, including the alias-validation edge cases and rule over-matching tests called out above.
- #43 corrects
docs/rules.md, the design, the TODO, agent guidance, and the work log: the currently documented "COM metadata" tier-1 alias priority describes an API that does not exist (ADR-0009) and must be dropped, not merely synced — the priority list is regex rules, then raw file name.
Every added source file is registered in both the core or test project and its filters file. Core logic stays in the static library.
- Validate accepted and rejected version 1 JSON documents, required field types, unique non-empty rule names, flags, malformed regexes, and UTF-8 input.
- Verify rule ordering, case behavior, numbered replacement captures, invalid alias rejection, and raw-filename fallback.
- Verify the Codex x64, ARM64, and GNU target suffixes plus a representative version/architecture suffix.
- Verify explicit rules beat user rules, user rules beat embedded rules, an absent user rules file selects embedded rules, and a present-but-malformed user rules file errors (exit 3) rather than falling back to embedded rules.
- Verify alias-validation edge cases: an empty capture that would yield a bare
.exe, a replacement not ending in.exe, and extension case-folding. - Confirm a
RuleSetparsing test fails clearly if theComApartmentfixture is absent, and that a tests-only link exercisingRuleSetwithoutWingetComSourcesucceeds. - Build core and tests in Debug and Release for x64 and ARM64 at the warnings-as-errors setting.
- Run the x64 Debug and Release test DLLs and record actual results. Record ARM64 as cross-built rather than run unless execution occurs on an ARM64 host.
The full solution continues to have the known unresolved executable entry point until
#56 supplies main.cpp; targeted core and test builds are the completion evidence for
this milestone.
- #37, #38, #39, #41, #42, and #43 are merged and closed.
- #40 was open and structurally blocked by #53 and #56 at the time of this plan; it was
later closed as already implemented by #56's
runTestRule()(see above). - Issue #5,
docs/TODO.md,docs/task.md, and this Wiki page report the same state. - All targeted builds and x64 tests pass, with no new warning or dependency.
- Canonical documentation and code comments are English. Localized
*_ja.mdfiles are not read or changed.