aboutsummaryrefslogtreecommitdiffstats
path: root/mailrules.py
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-08-12 11:29:24 +0200
committerDanilo M. <danix@danix.xyz>2026-08-12 11:29:24 +0200
commit99bbd07a21bf43617eddfc53ae9065a6550d5155 (patch)
tree2041dcb72f51f7c8c52a4bd97dd6e38c839c16f0 /mailrules.py
parentaa10536a548032f861a860406c3106e123048d37 (diff)
downloadmailctl-99bbd07a21bf43617eddfc53ae9065a6550d5155.tar.gz
mailctl-99bbd07a21bf43617eddfc53ae9065a6550d5155.zip
feat(rules): order rules by stage, ties by file position
Account tags must run before topic rules, which is what the stage field is for. Disabled rules stay loaded so a UI can re-enable them.
Diffstat (limited to 'mailrules.py')
-rwxr-xr-xmailrules.py11
1 files changed, 11 insertions, 0 deletions
diff --git a/mailrules.py b/mailrules.py
index 26ed698..7df1b42 100755
--- a/mailrules.py
+++ b/mailrules.py
@@ -125,6 +125,17 @@ def load(path=None):
return store
+def ordered(rules):
+ """Enabled rules in execution order: by stage ascending, ties by position.
+
+ `sorted` is stable, so sorting on stage alone preserves file order within
+ a stage. That is the tie-break the format promises, and it is why this
+ does not sort on (stage, id): an id-sorted tie would reorder rules a user
+ deliberately sequenced.
+ """
+ return sorted([r for r in rules if r.enabled], key=lambda r: r.stage)
+
+
def _parse_rule(obj, index, seen, warnings):
"""One rule, or None with a warning appended. `index` names the rule when
it has no usable id of its own."""