summaryrefslogtreecommitdiff
path: root/rules
diff options
context:
space:
mode:
authorPierre Le Marre <dev@wismill.eu>2024-08-23 13:22:29 +0200
committerMarge Bot <emma+marge@anholt.net>2024-08-23 14:53:55 +0000
commitd75647bc62ec6a469271a4d54bcb3150efee7dc6 (patch)
tree94f5e81060d36c740bd5222d8979a8d3dbca4565 /rules
parentd68a1a23f9db06085c4b7f45406c59fb784d3133 (diff)
rules: Fix merging explicit and implicit merge modes
Since c4f76b584fe10bc2037966a70efad9bc5b682a4a we merge rule sets with and without explicit merge modes (i.e. *explicit* merge mode are section starting with either `+` or `|`). This is wrong, as these are not supposed to be matched at in the same rule set. Part-of: <https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/merge_requests/729>
Diffstat (limited to 'rules')
-rwxr-xr-xrules/merge.py33
1 files changed, 30 insertions, 3 deletions
diff --git a/rules/merge.py b/rules/merge.py
index 95e30f7d..0018f8a9 100755
--- a/rules/merge.py
+++ b/rules/merge.py
@@ -4,6 +4,7 @@
from __future__ import annotations
import argparse
+import dataclasses
import sys
from collections import defaultdict
from contextlib import AbstractContextManager, nullcontext
@@ -25,6 +26,13 @@ class Header:
def parse(cls, raw: str) -> Header:
return Header(raw, tuple(raw.split()))
+ def set_merge_mode(self, merge_mode: bool) -> Header:
+ if merge_mode:
+ key = self.key + ("+",)
+ return dataclasses.replace(self, key=key)
+ else:
+ return self
+
def handle_file(path: Path) -> tuple[Header, Path]:
"""
@@ -32,9 +40,28 @@ def handle_file(path: Path) -> tuple[Header, Path]:
If the file does not have a header, the header is the empty string.
"""
with open(path) as fd:
- header = fd.readline()
- if header.startswith("! "):
- return Header.parse(header), path
+ file_header = fd.readline().split("//")[0]
+ if file_header.startswith("! "):
+ header = Header.parse(file_header)
+ if "$" in file_header or "include" in file_header:
+ # Do not process group definition further
+ return header, path
+ # Get merge mode: we do not want to mix rules sets with
+ # explicit and implicit merge modes.
+ has_explicit_merge_mode: bool | None = None
+ for line in fd:
+ if line.startswith("! "):
+ break
+ entry = line.split("//")[0].split()
+ if not entry:
+ continue
+ section = entry[-1]
+ if section.startswith("+") or section.startswith("|"):
+ has_explicit_merge_mode = True
+ # Ensure any explicit merge mode takes precedence
+ elif has_explicit_merge_mode is None:
+ has_explicit_merge_mode = False
+ return header.set_merge_mode(bool(has_explicit_merge_mode)), path
else:
return Header.empty(), path