From 8ea955c72ff9c2888a08c9b6b2f5dda8b49eb856 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Wed, 1 Nov 2023 22:37:05 +0000 Subject: Improve argument handling of c2json (#22170) * Improve argument handling of c2json * Add automagic --- lib/python/qmk/cli/c2json.py | 59 +++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 26 deletions(-) (limited to 'lib/python/qmk/cli') diff --git a/lib/python/qmk/cli/c2json.py b/lib/python/qmk/cli/c2json.py index 7f6aca070a..f7f1f2ffba 100644 --- a/lib/python/qmk/cli/c2json.py +++ b/lib/python/qmk/cli/c2json.py @@ -1,45 +1,57 @@ """Generate a keymap.json from a keymap.c file. """ +import re import json from argcomplete.completers import FilesCompleter from milc import cli -import qmk.keymap import qmk.path from qmk.json_encoders import InfoJSONEncoder +from qmk.decorators import automagic_keyboard, automagic_keymap from qmk.keyboard import keyboard_completer, keyboard_folder +from qmk.keymap import locate_keymap, find_keymap_from_dir, generate_json, c2json as c2json_impl from qmk.errors import CppError +from qmk.commands import dump_lines @cli.argument('--no-cpp', arg_only=True, action='store_false', help='Do not use \'cpp\' on keymap.c') @cli.argument('-o', '--output', arg_only=True, type=qmk.path.normpath, help='File to write to') @cli.argument('-q', '--quiet', arg_only=True, action='store_true', help="Quiet mode, only output error messages") -@cli.argument('-kb', '--keyboard', arg_only=True, type=keyboard_folder, completer=keyboard_completer, required=True, help='The keyboard\'s name') -@cli.argument('-km', '--keymap', arg_only=True, required=True, help='The keymap\'s name') -@cli.argument('filename', arg_only=True, completer=FilesCompleter('.c'), help='keymap.c file') +@cli.argument('-kb', '--keyboard', type=keyboard_folder, completer=keyboard_completer, help='The keyboard\'s name') +@cli.argument('-km', '--keymap', help='The keymap\'s name') +@cli.argument('filename', nargs='?', type=qmk.path.FileType('r'), arg_only=True, completer=FilesCompleter('.c'), help='keymap.c file') @cli.subcommand('Creates a keymap.json from a keymap.c file.') +@automagic_keyboard +@automagic_keymap def c2json(cli): """Generate a keymap.json from a keymap.c file. This command uses the `qmk.keymap` module to generate a keymap.json from a keymap.c file. The generated keymap is written to stdout, or to a file if -o is provided. """ - if cli.args.filename != '-': - cli.args.filename = qmk.path.normpath(cli.args.filename) + filename = cli.args.filename + keyboard = cli.config.c2json.keyboard + keymap = cli.config.c2json.keymap - # Error checking - if not cli.args.filename.exists(): - cli.log.error('C file does not exist!') - cli.print_usage() - return False + if filename: + if not keyboard and not keymap: + # fallback to inferring keyboard/keymap from path + (keymap, found_type) = find_keymap_from_dir(filename) + if found_type == 'keymap_directory': + keyboard = re.search(fr"keyboards/(.+)/keymaps/{keymap}/.*", filename.as_posix()).group(1) - # Environment processing - if cli.args.output == ('-'): - cli.args.output = None + elif keyboard and keymap: + if not filename: + # fallback to inferring keyboard/keymap from path + filename = locate_keymap(keyboard, keymap) + + if not all((filename, keyboard, keymap)): + cli.log.error('You must supply keyboard and keymap, a path to a keymap.c within qmk_firmware, or absolute filename and keyboard and keymap') + cli.print_help() + return False - # Parse the keymap.c try: - keymap_json = qmk.keymap.c2json(cli.args.keyboard, cli.args.keymap, cli.args.filename, use_cpp=cli.args.no_cpp) + keymap_json = c2json_impl(keyboard, keymap, filename, use_cpp=cli.args.no_cpp) except CppError as e: if cli.config.general.verbose: cli.log.debug('The C pre-processor ran into a fatal error: %s', e) @@ -48,19 +60,14 @@ def c2json(cli): # Generate the keymap.json try: - keymap_json = qmk.keymap.generate_json(keymap_json['keymap'], keymap_json['keyboard'], keymap_json['layout'], keymap_json['layers']) + keymap_json = generate_json(keymap_json['keymap'], keymap_json['keyboard'], keymap_json['layout'], keymap_json['layers']) except KeyError: cli.log.error('Something went wrong. Try to use --no-cpp.') return False if cli.args.output: - cli.args.output.parent.mkdir(parents=True, exist_ok=True) - if cli.args.output.exists(): - cli.args.output.replace(cli.args.output.parent / (cli.args.output.name + '.bak')) - cli.args.output.write_text(json.dumps(keymap_json, cls=InfoJSONEncoder, sort_keys=True)) - - if not cli.args.quiet: - cli.log.info('Wrote keymap to %s.', cli.args.output) - + keymap_lines = [json.dumps(keymap_json, cls=InfoJSONEncoder, sort_keys=True)] else: - print(json.dumps(keymap_json)) + keymap_lines = [json.dumps(keymap_json)] + + dump_lines(cli.args.output, keymap_lines, cli.args.quiet) -- cgit v1.2.3