Repository navigation
fix(categories): treat blank regex rules as matching nothing everywhere - #1026
Conversation
aw-core's server-side categorize() ignores a rule whose regex is empty,
because it would otherwise match every event. The client-side matchers
compiled RegExp(''), which matches everything. So Top Applications and
Top Window Titles put every event in a blank-regex category, while
Sunburst, Timeline and Top Categories ignored it.
Skip blank regexes in matchString/classifyEvents, and send them to the
server as 'none' so aw-server-rust (which compiles '' as match-all)
agrees too.
Fixes ActivityWatch#382
Git-Session-Id: 1bfb
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1026 +/- ##
==========================================
+ Coverage 63.30% 63.37% +0.07%
==========================================
Files 52 52
Lines 3608 3607 -1
Branches 840 894 +54
==========================================
+ Hits 2284 2286 +2
+ Misses 1309 1306 -3
Partials 15 15 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
CI-green and mergeable (Greptile 5/5) — waiting only on a maintainer click. This PR is ready to merge, but the bot has pull-only access to this repo and can't self-merge — surfacing it here so it isn't lost. The monitoring loop will stop re-flagging it now that this note is posted. |
🤖 AI code reviewAdds hasMatchableRegex() to util/classes.ts, which returns false for regex rules with an empty regex string. matchString and classifyEvents now filter categories through it so blank regexes never match client-side. classes_for_query converts blank-regex rules to { type: 'none' } before sending them to the server. Adds unit tests for both matching and the query getter. Safe to merge — no P0/P1 findingsConfidence 5/5 ✅ No findings. The diff looks correct to me on this pass. Files changed (4) — the diff as I read it
Reviewed Maintainer commands
|
* fix(aw-transform): empty regex rules never match
RegexRule::new("") compiled to a match-all regex in fancy_regex, so a
blank category rule matched every event. aw-core's Python
aw_transform.classify.Rule deliberately never matches an empty regex
("would erroneously match everything") — aw-server-rust silently
diverged from it. ActivityWatch/aw-webui#1026 hides this for the web UI
by sending blank rules as {type: 'none'}, but other clients (aw-client
categorize queries, scripts, the CLI) still see the divergence.
Add a never_matches flag set when the pattern is empty, checked before
any regex evaluation, so an empty-regex rule behaves like Rule::None
instead of a wildcard. Covered by a new regression test that fails on
master.
Also carries the aw-query clippy::block_scrutinee allow from #771/#772
(unrelated Rust 1.99+ toolchain drift) so this branch's own CI/clippy
passes independently of that PR's merge.
Git-Session-Id: 1d99
* fix(aw-transform): derive never_matches in From<Regex> conversion
Greptile P1: Rule::from(Regex::new("").unwrap()) hard-coded
never_matches: false, so the public conversion path still let an empty
regex match every event — the exact bug this PR fixes, reachable past
the new guard. Derive the flag from the source pattern and cover the
From path in the regression test.
Git-Session-Id: 2b7710f0-a6ec-5fa0-b895-bf715c0f8ab4
Fixes #382.
Root cause
The views don't agree on what a blank regex rule means:
$categoryfromcategorize()in the query. aw-core'sRuledeliberately never matches an empty regex (aw_transform/classify.py: "also checks that the regex isn't an empty string (which would erroneously match everything)"), so those views ignore the category.matchString(), which compilesRegExp(''). That matches every string, so every app or title not claimed by a more specific rule lands in the blank-regex category.aw-server-rust differs from aw-core here as well: its
RegexRule::new("")compiles to a match-all regex.The editor has refused empty patterns since 9f37315 (
validateRegex('') === false). Blank rules still reach users through older stored settings and imported category files.Fix
hasMatchableRegex(c)inutil/classes.tsis used by bothmatchStringandclassifyEvents, so client-side matching skips blank regexes the same way aw-core does.classes_for_querysends blank-regex rules as{ type: 'none' }, so aw-server-rust and aw-server give the same result. The category still exists as a container, and its children match as before.Tests
classes.test.node.ts: with a blank-regexWorkparent and aWork > Programming(vim) child,matchString/classifyEventsreturn Uncategorized for unrelated strings (master returnedWork) and still return the child forvim.store/categories.test.node.ts:classes_for_querysends the blank rule asnoneand leaves real regex rules unchanged.Ran locally:
jeston the classes, categories store, categorization, queries and Sunburst suites (42 passed),tsc --noEmitis clean, and prettier passes. No.vuefiles changed.