import subprocess
import os
import xml.etree.ElementTree as ET
+from pathlib import Path
verbose = False
# 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
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
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
}
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,
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)