67 lines
2.2 KiB
Python
Executable File
67 lines
2.2 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Verify archinstall/tui/binding_descriptions.py against the installed textual.
|
|
|
|
Run manually after a textual upgrade or after introducing a new textual
|
|
widget in archinstall/tui/components.py:
|
|
|
|
python3 test_tooling/check_binding_descriptions.py
|
|
|
|
The script parses the tr_noop() entries from binding_descriptions.py (no
|
|
archinstall import needed) and compares them with the MRO-merged binding
|
|
descriptions of the textual classes used in components.py. Exits non-zero
|
|
on any difference and prints the exact missing/stale entries.
|
|
"""
|
|
|
|
import re
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
from textual.app import App
|
|
from textual.screen import Screen
|
|
from textual.widgets import Button, DataTable, HelpPanel, Input, OptionList, SelectionList
|
|
|
|
# Must mirror the textual widget classes used in archinstall/tui/components.py.
|
|
# Extend when a new widget is introduced there.
|
|
TEXTUAL_CLASSES = (App, Screen, Button, DataTable, HelpPanel, Input, OptionList, SelectionList)
|
|
|
|
MODULE_PATH = Path(__file__).parent.parent / 'archinstall/tui/binding_descriptions.py'
|
|
|
|
|
|
def live_descriptions() -> set[str]:
|
|
descriptions: set[str] = set()
|
|
# Walk the full MRO: _translate_bindings() operates on the merged bindings
|
|
# map, so descriptions inherited from ancestors are translated too.
|
|
for cls in TEXTUAL_CLASSES:
|
|
for klass in cls.__mro__:
|
|
for binding in klass.__dict__.get('BINDINGS', []):
|
|
description = getattr(binding, 'description', None)
|
|
if not description and isinstance(binding, tuple) and len(binding) > 2:
|
|
description = binding[2]
|
|
if description:
|
|
descriptions.add(str(description))
|
|
return descriptions
|
|
|
|
|
|
def listed_descriptions() -> set[str]:
|
|
content = MODULE_PATH.read_text(encoding='utf-8')
|
|
return set(re.findall(r"tr_noop\('([^']+)'\)", content))
|
|
|
|
|
|
def main() -> int:
|
|
live = live_descriptions()
|
|
listed = listed_descriptions()
|
|
|
|
if live == listed:
|
|
print(f'OK: {len(listed)} descriptions in sync with installed textual')
|
|
return 0
|
|
|
|
for description in sorted(live - listed):
|
|
print(f'missing from binding_descriptions.py: {description}')
|
|
for description in sorted(listed - live):
|
|
print(f'stale in binding_descriptions.py: {description}')
|
|
return 1
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main())
|