diff options
| author | Nick Brassel <nick@tzarc.org> | 2023-11-28 07:53:43 +1100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-11-28 07:53:43 +1100 |
| commit | 5501e804ff8d41ce656061b91896c4ac8c681d78 (patch) | |
| tree | 6a655fbceaeab67cf727dbe4318721407dd31824 /lib/python/qmk/cli/format/json.py | |
| parent | 094357c40347e8a5db36578851f1af34a92e9f68 (diff) | |
QMK Userspace (#22222)
Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>
Diffstat (limited to 'lib/python/qmk/cli/format/json.py')
| -rwxr-xr-x | lib/python/qmk/cli/format/json.py | 70 |
1 files changed, 48 insertions, 22 deletions
diff --git a/lib/python/qmk/cli/format/json.py b/lib/python/qmk/cli/format/json.py index 3299a0d807..283513254c 100755 --- a/lib/python/qmk/cli/format/json.py +++ b/lib/python/qmk/cli/format/json.py | |||
| @@ -9,48 +9,74 @@ from milc import cli | |||
| 9 | 9 | ||
| 10 | from qmk.info import info_json | 10 | from qmk.info import info_json |
| 11 | from qmk.json_schema import json_load, validate | 11 | from qmk.json_schema import json_load, validate |
| 12 | from qmk.json_encoders import InfoJSONEncoder, KeymapJSONEncoder | 12 | from qmk.json_encoders import InfoJSONEncoder, KeymapJSONEncoder, UserspaceJSONEncoder |
| 13 | from qmk.path import normpath | 13 | from qmk.path import normpath |
| 14 | 14 | ||
| 15 | 15 | ||
| 16 | @cli.argument('json_file', arg_only=True, type=normpath, help='JSON file to format') | 16 | def _detect_json_format(file, json_data): |
| 17 | @cli.argument('-f', '--format', choices=['auto', 'keyboard', 'keymap'], default='auto', arg_only=True, help='JSON formatter to use (Default: autodetect)') | 17 | """Detect the format of a json file. |
| 18 | @cli.argument('-i', '--inplace', action='store_true', arg_only=True, help='If set, will operate in-place on the input file') | ||
| 19 | @cli.argument('-p', '--print', action='store_true', arg_only=True, help='If set, will print the formatted json to stdout ') | ||
| 20 | @cli.subcommand('Generate an info.json file for a keyboard.', hidden=False if cli.config.user.developer else True) | ||
| 21 | def format_json(cli): | ||
| 22 | """Format a json file. | ||
| 23 | """ | 18 | """ |
| 24 | json_file = json_load(cli.args.json_file) | 19 | json_encoder = None |
| 25 | 20 | try: | |
| 26 | if cli.args.format == 'auto': | 21 | validate(json_data, 'qmk.user_repo.v1') |
| 22 | json_encoder = UserspaceJSONEncoder | ||
| 23 | except ValidationError: | ||
| 24 | pass | ||
| 25 | |||
| 26 | if json_encoder is None: | ||
| 27 | try: | 27 | try: |
| 28 | validate(json_file, 'qmk.keyboard.v1') | 28 | validate(json_data, 'qmk.keyboard.v1') |
| 29 | json_encoder = InfoJSONEncoder | 29 | json_encoder = InfoJSONEncoder |
| 30 | |||
| 31 | except ValidationError as e: | 30 | except ValidationError as e: |
| 32 | cli.log.warning('File %s did not validate as a keyboard:\n\t%s', cli.args.json_file, e) | 31 | cli.log.warning('File %s did not validate as a keyboard info.json or userspace qmk.json:\n\t%s', file, e) |
| 33 | cli.log.info('Treating %s as a keymap file.', cli.args.json_file) | 32 | cli.log.info('Treating %s as a keymap file.', file) |
| 34 | json_encoder = KeymapJSONEncoder | 33 | json_encoder = KeymapJSONEncoder |
| 34 | |||
| 35 | return json_encoder | ||
| 36 | |||
| 37 | |||
| 38 | def _get_json_encoder(file, json_data): | ||
| 39 | """Get the json encoder for a file. | ||
| 40 | """ | ||
| 41 | json_encoder = None | ||
| 42 | if cli.args.format == 'auto': | ||
| 43 | json_encoder = _detect_json_format(file, json_data) | ||
| 35 | elif cli.args.format == 'keyboard': | 44 | elif cli.args.format == 'keyboard': |
| 36 | json_encoder = InfoJSONEncoder | 45 | json_encoder = InfoJSONEncoder |
| 37 | elif cli.args.format == 'keymap': | 46 | elif cli.args.format == 'keymap': |
| 38 | json_encoder = KeymapJSONEncoder | 47 | json_encoder = KeymapJSONEncoder |
| 48 | elif cli.args.format == 'userspace': | ||
| 49 | json_encoder = UserspaceJSONEncoder | ||
| 39 | else: | 50 | else: |
| 40 | # This should be impossible | 51 | # This should be impossible |
| 41 | cli.log.error('Unknown format: %s', cli.args.format) | 52 | cli.log.error('Unknown format: %s', cli.args.format) |
| 53 | return json_encoder | ||
| 54 | |||
| 55 | |||
| 56 | @cli.argument('json_file', arg_only=True, type=normpath, help='JSON file to format') | ||
| 57 | @cli.argument('-f', '--format', choices=['auto', 'keyboard', 'keymap', 'userspace'], default='auto', arg_only=True, help='JSON formatter to use (Default: autodetect)') | ||
| 58 | @cli.argument('-i', '--inplace', action='store_true', arg_only=True, help='If set, will operate in-place on the input file') | ||
| 59 | @cli.argument('-p', '--print', action='store_true', arg_only=True, help='If set, will print the formatted json to stdout ') | ||
| 60 | @cli.subcommand('Generate an info.json file for a keyboard.', hidden=False if cli.config.user.developer else True) | ||
| 61 | def format_json(cli): | ||
| 62 | """Format a json file. | ||
| 63 | """ | ||
| 64 | json_data = json_load(cli.args.json_file) | ||
| 65 | |||
| 66 | json_encoder = _get_json_encoder(cli.args.json_file, json_data) | ||
| 67 | if json_encoder is None: | ||
| 42 | return False | 68 | return False |
| 43 | 69 | ||
| 44 | if json_encoder == KeymapJSONEncoder and 'layout' in json_file: | 70 | if json_encoder == KeymapJSONEncoder and 'layout' in json_data: |
| 45 | # Attempt to format the keycodes. | 71 | # Attempt to format the keycodes. |
| 46 | layout = json_file['layout'] | 72 | layout = json_data['layout'] |
| 47 | info_data = info_json(json_file['keyboard']) | 73 | info_data = info_json(json_data['keyboard']) |
| 48 | 74 | ||
| 49 | if layout in info_data.get('layout_aliases', {}): | 75 | if layout in info_data.get('layout_aliases', {}): |
| 50 | layout = json_file['layout'] = info_data['layout_aliases'][layout] | 76 | layout = json_data['layout'] = info_data['layout_aliases'][layout] |
| 51 | 77 | ||
| 52 | if layout in info_data.get('layouts'): | 78 | if layout in info_data.get('layouts'): |
| 53 | for layer_num, layer in enumerate(json_file['layers']): | 79 | for layer_num, layer in enumerate(json_data['layers']): |
| 54 | current_layer = [] | 80 | current_layer = [] |
| 55 | last_row = 0 | 81 | last_row = 0 |
| 56 | 82 | ||
| @@ -61,9 +87,9 @@ def format_json(cli): | |||
| 61 | 87 | ||
| 62 | current_layer.append(keymap_key) | 88 | current_layer.append(keymap_key) |
| 63 | 89 | ||
| 64 | json_file['layers'][layer_num] = current_layer | 90 | json_data['layers'][layer_num] = current_layer |
| 65 | 91 | ||
| 66 | output = json.dumps(json_file, cls=json_encoder, sort_keys=True) | 92 | output = json.dumps(json_data, cls=json_encoder, sort_keys=True) |
| 67 | 93 | ||
| 68 | if cli.args.inplace: | 94 | if cli.args.inplace: |
| 69 | with open(cli.args.json_file, 'w+', encoding='utf-8') as outfile: | 95 | with open(cli.args.json_file, 'w+', encoding='utf-8') as outfile: |
