Configure github pages
[platform/upstream/libxkbcommon.git] / test / xkeyboard-config-test.py.in
index cc53da4..66deca4 100755 (executable)
@@ -5,6 +5,7 @@ import sys
 import subprocess
 import os
 import xml.etree.ElementTree as ET
+from pathlib import Path
 
 
 verbose = False
@@ -22,7 +23,7 @@ def escape(s):
 
 # The function generating the progress bar (if any).
 def create_progress_bar(verbose):
-    def noop_progress_bar(x, total):
+    def noop_progress_bar(x, total, file=None):
         return x
 
     progress_bar = noop_progress_bar
@@ -195,11 +196,22 @@ def parse(path):
     return combos
 
 
-def run(combos, tool, njobs):
+def run(combos, tool, njobs, keymap_output_dir):
+    if keymap_output_dir:
+        keymap_output_dir = Path(keymap_output_dir)
+        try:
+            keymap_output_dir.mkdir()
+        except FileExistsError as e:
+            print(e, file=sys.stderr)
+            return False
+
+    keymap_file = None
+    keymap_file_fd = None
+
     failed = False
     with multiprocessing.Pool(njobs) as p:
         results = p.imap_unordered(tool, combos)
-        for invocation in progress_bar(results, total=len(combos)):
+        for invocation in progress_bar(results, total=len(combos), file=sys.stdout):
             if invocation.exitstatus != 0:
                 failed = True
                 target = sys.stderr
@@ -209,6 +221,24 @@ def run(combos, tool, njobs):
             if target:
                 print(invocation, file=target)
 
+            if keymap_output_dir:
+                # we're running through the layouts in a somewhat sorted manner,
+                # so let's keep the fd open until we switch layouts
+                layout = invocation.layout
+                if invocation.variant:
+                    layout += f"({invocation.variant})"
+                fname = keymap_output_dir / layout
+                if fname != keymap_file:
+                    keymap_file = fname
+                    if keymap_file_fd:
+                        keymap_file_fd.close()
+                    keymap_file_fd = open(keymap_file, 'a')
+
+                rmlvo = ', '.join([x or '' for x in invocation.rmlvo])
+                print(f"// {rmlvo}", file=keymap_file_fd)
+                print(invocation.keymap, file=keymap_file_fd)
+                keymap_file_fd.flush()
+
     return failed
 
 
@@ -222,7 +252,12 @@ def main(args):
     }
 
     parser = argparse.ArgumentParser(
-        description='Tool to test all layout/variant/option combinations.'
+        description='''
+                    This tool compiles a keymap for each layout, variant and
+                    options combination in the given rules XML file. The output
+                    of this tool is YAML, use your favorite YAML parser to
+                    extract error messages. Errors are printed to stderr.
+                    '''
     )
     parser.add_argument('path', metavar='/path/to/evdev.xml',
                         nargs='?', type=str,
@@ -235,15 +270,32 @@ def main(args):
                         default=os.cpu_count() * 4,
                         help='number of processes to use')
     parser.add_argument('--verbose', '-v', default=False, action="store_true")
+    parser.add_argument('--keymap-output-dir', default=None, type=str,
+                        help='Directory to print compiled keymaps to')
+    parser.add_argument('--layout', default=None, type=str,
+                        help='Only test the given layout')
+    parser.add_argument('--variant', default=None, type=str,
+                        help='Only test the given variant')
+    parser.add_argument('--option', default=None, type=str,
+                        help='Only test the given option')
+
     args = parser.parse_args()
 
     verbose = args.verbose
+    keymapdir = args.keymap_output_dir
     progress_bar = create_progress_bar(verbose)
 
     tool = tools[args.tool]
 
-    combos = parse(args.path)
-    failed = run(combos, tool, args.jobs)
+    if any([args.layout, args.variant, args.option]):
+        combos = [{
+            'l': args.layout,
+            'v': args.variant,
+            'o': args.option,
+        }]
+    else:
+        combos = parse(args.path)
+    failed = run(combos, tool, args.jobs, keymapdir)
     sys.exit(failed)