summaryrefslogtreecommitdiff
path: root/lib/python/qmk/cli/c2json.py
diff options
context:
space:
mode:
authorJoel Challis <git@zvecr.com>2023-11-01 22:37:05 +0000
committerGitHub <noreply@github.com>2023-11-01 22:37:05 +0000
commit8ea955c72ff9c2888a08c9b6b2f5dda8b49eb856 (patch)
tree425166e843c8d897e77e44f68a9e3abbe42d13d1 /lib/python/qmk/cli/c2json.py
parenta27bc60703dda744309c5f13320f667f5c766260 (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.py59
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"""
3import re
3import json 4import json
4 5
5from argcomplete.completers import FilesCompleter 6from argcomplete.completers import FilesCompleter
6from milc import cli 7from milc import cli
7 8
8import qmk.keymap
9import qmk.path 9import qmk.path
10from qmk.json_encoders import InfoJSONEncoder 10from qmk.json_encoders import InfoJSONEncoder
11from qmk.decorators import automagic_keyboard, automagic_keymap
11from qmk.keyboard import keyboard_completer, keyboard_folder 12from qmk.keyboard import keyboard_completer, keyboard_folder
13from qmk.keymap import locate_keymap, find_keymap_from_dir, generate_json, c2json as c2json_impl
12from qmk.errors import CppError 14from qmk.errors import CppError
15from 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
22def c2json(cli): 27def 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)