diff options
Diffstat (limited to 'bin')
| -rwxr-xr-x | bin/udt-palette | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/bin/udt-palette b/bin/udt-palette index 1df0c4f..18dc0b1 100755 --- a/bin/udt-palette +++ b/bin/udt-palette @@ -417,8 +417,8 @@ TARGETS = [ ] -def generate(roles_path, out_dir): - scheme, palette, res, snap_names = load(roles_path) +def generate(roles_path, out_dir, scheme=None): + scheme, palette, res, snap_names = load(roles_path, scheme=scheme) written = [] for target, fn, template in TARGETS: dest = out_dir / target @@ -437,6 +437,44 @@ def generate(roles_path, out_dir): return scheme, written +def check_rofi_parses(scheme): + """Render `scheme` to a temp dir and have rofi parse every theme. + + The role checks below prove a scheme resolves, not that what it emits is + valid. A palette missing a name the themes reference parses as a broken + theme and every launcher stops opening, which is how exactly that bug + shipped once. rofi needs no display for -dump-theme. + """ + import shutil + import subprocess + import tempfile + + if not shutil.which("rofi"): + return None + + with tempfile.TemporaryDirectory() as tmp: + out = Path(tmp) + generate(None, out, scheme=scheme) + udt = out / "rofi" / "udt" + # The themes @import siblings, so they need the whole directory. + for extra in (REPO / "rofi" / "udt").glob("*.rasi"): + if not (udt / extra.name).exists(): + shutil.copy(extra, udt / extra.name) + # accent.rasi is generated per wallpaper; seed it so themes resolve. + (udt / "accent.rasi").write_text("* { accent: #ffffffff; }\n") + + for theme in sorted(udt.glob("*.rasi")): + if theme.name in ("palette.rasi", "accent.rasi", "common.rasi"): + continue + proc = subprocess.run( + ["rofi", "-no-config", "-theme", str(theme), "-dump-theme"], + capture_output=True, text=True) + if "Failed to parse" in proc.stderr: + raise AssertionError( + f"{scheme}: rofi cannot parse {theme.name}\n{proc.stderr.strip()}") + return True + + def selftest(): # Every shipped scheme must satisfy every role, or switching to it breaks # at install time. load() raises on any role the palette cannot supply. @@ -449,7 +487,9 @@ def selftest(): assert res["bg"] != res["fg"], f"{scheme}: bg and fg are the same colour" assert len(snap) >= 5, f"{scheme}: only {len(snap)} snap candidates" seen[scheme] = set(res) - print(f" {scheme}: {len(res)} roles, {len(snap)} accents") + parsed = check_rofi_parses(scheme) + note = "" if parsed else " (rofi not installed, parse unchecked)" + print(f" {scheme}: {len(res)} roles, {len(snap)} accents{note}") # Every scheme must define the SAME roles: a generator asks for a role by # name, so one scheme missing it would fail only once that scheme was |
