diff options
| author | Joel Challis <git@zvecr.com> | 2023-11-01 22:37:05 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-11-01 22:37:05 +0000 |
| commit | 8ea955c72ff9c2888a08c9b6b2f5dda8b49eb856 (patch) | |
| tree | 425166e843c8d897e77e44f68a9e3abbe42d13d1 /lib/python/qmk/cli/c2json.py | |
| parent | a27bc60703dda744309c5f13320f667f5c766260 (diff) | |
Improve argument handling of c2json (#22170)
* Improve argument handling of c2json
* Add automagic
Diffstat (limited to 'lib/python/qmk/cli/c2json.py')
| -rw-r--r-- | lib/python/qmk/cli/c2json.py | 59 |
1 files changed, 33 insertions, 26 deletions
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 @@ | |||
| 1 | """Generate a keymap.json from a keymap.c file. | 1 | """Generate a keymap.json from a keymap.c file. |
| 2 | """ | 2 | """ |
| 3 | import re | ||
| 3 | import json | 4 | import json |
| 4 | 5 | ||
| 5 | from argcomplete.completers import FilesCompleter | 6 | from argcomplete.completers import FilesCompleter |
| 6 | from milc import cli | 7 | from milc import cli |
| 7 | 8 | ||
| 8 | import qmk.keymap | ||
| 9 | import qmk.path | 9 | import qmk.path |
| 10 | from qmk.json_encoders import InfoJSONEncoder | 10 | from qmk.json_encoders import InfoJSONEncoder |
| 11 | from qmk.decorators import automagic_keyboard, automagic_keymap | ||
| 11 | from qmk.keyboard import keyboard_completer, keyboard_folder | 12 | from qmk.keyboard import keyboard_completer, keyboard_folder |
| 13 | from qmk.keymap import locate_keymap, find_keymap_from_dir, generate_json, c2json as c2json_impl | ||
| 12 | from qmk.errors import CppError | 14 | from qmk.errors import CppError |
| 15 | from qmk.commands import dump_lines | ||
| 13 | 16 | ||
| 14 | 17 | ||
| 15 | @cli.argument('--no-cpp', arg_only=True, action='store_false', help='Do not use \'cpp\' on keymap.c') | 18 | @cli.argument('--no-cpp', arg_only=True, action='store_false', help='Do not use \'cpp\' on keymap.c') |
| 16 | @cli.argument('-o', '--output', arg_only=True, type=qmk.path.normpath, help='File to write to') | 19 | @cli.argument('-o', '--output', arg_only=True, type=qmk.path.normpath, help='File to write to') |
| 17 | @cli.argument('-q', '--quiet', arg_only=True, action='store_true', help="Quiet mode, only output error messages") | 20 | @cli.argument('-q', '--quiet', arg_only=True, action='store_true', help="Quiet mode, only output error messages") |
| 18 | @cli.argument('-kb', '--keyboard', arg_only=True, type=keyboard_folder, completer=keyboard_completer, required=True, help='The keyboard\'s name') | 21 | @cli.argument('-kb', '--keyboard', type=keyboard_folder, completer=keyboard_completer, help='The keyboard\'s name') |
| 19 | @cli.argument('-km', '--keymap', arg_only=True, required=True, help='The keymap\'s name') | 22 | @cli.argument('-km', '--keymap', help='The keymap\'s name') |
| 20 | @cli.argument('filename', arg_only=True, completer=FilesCompleter('.c'), help='keymap.c file') | 23 | @cli.argument('filename', nargs='?', type=qmk.path.FileType('r'), arg_only=True, completer=FilesCompleter('.c'), help='keymap.c file') |
| 21 | @cli.subcommand('Creates a keymap.json from a keymap.c file.') | 24 | @cli.subcommand('Creates a keymap.json from a keymap.c file.') |
| 25 | @automagic_keyboard | ||
| 26 | @automagic_keymap | ||
| 22 | def c2json(cli): | 27 | def c2json(cli): |
| 23 | """Generate a keymap.json from a keymap.c file. | 28 | """Generate a keymap.json from a keymap.c file. |
| 24 | 29 | ||
| 25 | 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. | 30 | 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. |
| 26 | """ | 31 | """ |
| 27 | if cli.args.filename != '-': | 32 | filename = cli.args.filename |
| 28 | cli.args.filename = qmk.path.normpath(cli.args.filename) | 33 | keyboard = cli.config.c2json.keyboard |
| 34 | keymap = cli.config.c2json.keymap | ||
| 29 | 35 | ||
| 30 | # Error checking | 36 | if filename: |
| 31 | if not cli.args.filename.exists(): | 37 | if not keyboard and not keymap: |
| 32 | cli.log.error('C file does not exist!') | 38 | # fallback to inferring keyboard/keymap from path |
| 33 | cli.print_usage() | 39 | (keymap, found_type) = find_keymap_from_dir(filename) |
| 34 | return False | 40 | if found_type == 'keymap_directory': |
| 41 | keyboard = re.search(fr"keyboards/(.+)/keymaps/{keymap}/.*", filename.as_posix()).group(1) | ||
| 35 | 42 | ||
| 36 | # Environment processing | 43 | elif keyboard and keymap: |
| 37 | if cli.args.output == ('-'): | 44 | if not filename: |
| 38 | cli.args.output = None | 45 | # fallback to inferring keyboard/keymap from path |
| 46 | filename = locate_keymap(keyboard, keymap) | ||
| 47 | |||
| 48 | if not all((filename, keyboard, keymap)): | ||
| 49 | 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') | ||
| 50 | cli.print_help() | ||
| 51 | return False | ||
| 39 | 52 | ||
| 40 | # Parse the keymap.c | ||
| 41 | try: | 53 | try: |
| 42 | keymap_json = qmk.keymap.c2json(cli.args.keyboard, cli.args.keymap, cli.args.filename, use_cpp=cli.args.no_cpp) | 54 | keymap_json = c2json_impl(keyboard, keymap, filename, use_cpp=cli.args.no_cpp) |
| 43 | except CppError as e: | 55 | except CppError as e: |
| 44 | if cli.config.general.verbose: | 56 | if cli.config.general.verbose: |
| 45 | cli.log.debug('The C pre-processor ran into a fatal error: %s', e) | 57 | cli.log.debug('The C pre-processor ran into a fatal error: %s', e) |
| @@ -48,19 +60,14 @@ def c2json(cli): | |||
| 48 | 60 | ||
| 49 | # Generate the keymap.json | 61 | # Generate the keymap.json |
| 50 | try: | 62 | try: |
| 51 | keymap_json = qmk.keymap.generate_json(keymap_json['keymap'], keymap_json['keyboard'], keymap_json['layout'], keymap_json['layers']) | 63 | keymap_json = generate_json(keymap_json['keymap'], keymap_json['keyboard'], keymap_json['layout'], keymap_json['layers']) |
| 52 | except KeyError: | 64 | except KeyError: |
| 53 | cli.log.error('Something went wrong. Try to use --no-cpp.') | 65 | cli.log.error('Something went wrong. Try to use --no-cpp.') |
| 54 | return False | 66 | return False |
| 55 | 67 | ||
| 56 | if cli.args.output: | 68 | if cli.args.output: |
| 57 | cli.args.output.parent.mkdir(parents=True, exist_ok=True) | 69 | keymap_lines = [json.dumps(keymap_json, cls=InfoJSONEncoder, sort_keys=True)] |
| 58 | if cli.args.output.exists(): | ||
| 59 | cli.args.output.replace(cli.args.output.parent / (cli.args.output.name + '.bak')) | ||
| 60 | cli.args.output.write_text(json.dumps(keymap_json, cls=InfoJSONEncoder, sort_keys=True)) | ||
| 61 | |||
| 62 | if not cli.args.quiet: | ||
| 63 | cli.log.info('Wrote keymap to %s.', cli.args.output) | ||
| 64 | |||
| 65 | else: | 70 | else: |
| 66 | print(json.dumps(keymap_json)) | 71 | keymap_lines = [json.dumps(keymap_json)] |
| 72 | |||
| 73 | dump_lines(cli.args.output, keymap_lines, cli.args.quiet) | ||
