From 5501e804ff8d41ce656061b91896c4ac8c681d78 Mon Sep 17 00:00:00 2001 From: Nick Brassel Date: Tue, 28 Nov 2023 07:53:43 +1100 Subject: QMK Userspace (#22222) Co-authored-by: Duncan Sutherland --- lib/python/qmk/cli/format/json.py | 70 +++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 22 deletions(-) (limited to 'lib/python/qmk/cli/format/json.py') 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 from qmk.info import info_json from qmk.json_schema import json_load, validate -from qmk.json_encoders import InfoJSONEncoder, KeymapJSONEncoder +from qmk.json_encoders import InfoJSONEncoder, KeymapJSONEncoder, UserspaceJSONEncoder from qmk.path import normpath -@cli.argument('json_file', arg_only=True, type=normpath, help='JSON file to format') -@cli.argument('-f', '--format', choices=['auto', 'keyboard', 'keymap'], default='auto', arg_only=True, help='JSON formatter to use (Default: autodetect)') -@cli.argument('-i', '--inplace', action='store_true', arg_only=True, help='If set, will operate in-place on the input file') -@cli.argument('-p', '--print', action='store_true', arg_only=True, help='If set, will print the formatted json to stdout ') -@cli.subcommand('Generate an info.json file for a keyboard.', hidden=False if cli.config.user.developer else True) -def format_json(cli): - """Format a json file. +def _detect_json_format(file, json_data): + """Detect the format of a json file. """ - json_file = json_load(cli.args.json_file) - - if cli.args.format == 'auto': + json_encoder = None + try: + validate(json_data, 'qmk.user_repo.v1') + json_encoder = UserspaceJSONEncoder + except ValidationError: + pass + + if json_encoder is None: try: - validate(json_file, 'qmk.keyboard.v1') + validate(json_data, 'qmk.keyboard.v1') json_encoder = InfoJSONEncoder - except ValidationError as e: - cli.log.warning('File %s did not validate as a keyboard:\n\t%s', cli.args.json_file, e) - cli.log.info('Treating %s as a keymap file.', cli.args.json_file) + cli.log.warning('File %s did not validate as a keyboard info.json or userspace qmk.json:\n\t%s', file, e) + cli.log.info('Treating %s as a keymap file.', file) json_encoder = KeymapJSONEncoder + + return json_encoder + + +def _get_json_encoder(file, json_data): + """Get the json encoder for a file. + """ + json_encoder = None + if cli.args.format == 'auto': + json_encoder = _detect_json_format(file, json_data) elif cli.args.format == 'keyboard': json_encoder = InfoJSONEncoder elif cli.args.format == 'keymap': json_encoder = KeymapJSONEncoder + elif cli.args.format == 'userspace': + json_encoder = UserspaceJSONEncoder else: # This should be impossible cli.log.error('Unknown format: %s', cli.args.format) + return json_encoder + + +@cli.argument('json_file', arg_only=True, type=normpath, help='JSON file to format') +@cli.argument('-f', '--format', choices=['auto', 'keyboard', 'keymap', 'userspace'], default='auto', arg_only=True, help='JSON formatter to use (Default: autodetect)') +@cli.argument('-i', '--inplace', action='store_true', arg_only=True, help='If set, will operate in-place on the input file') +@cli.argument('-p', '--print', action='store_true', arg_only=True, help='If set, will print the formatted json to stdout ') +@cli.subcommand('Generate an info.json file for a keyboard.', hidden=False if cli.config.user.developer else True) +def format_json(cli): + """Format a json file. + """ + json_data = json_load(cli.args.json_file) + + json_encoder = _get_json_encoder(cli.args.json_file, json_data) + if json_encoder is None: return False - if json_encoder == KeymapJSONEncoder and 'layout' in json_file: + if json_encoder == KeymapJSONEncoder and 'layout' in json_data: # Attempt to format the keycodes. - layout = json_file['layout'] - info_data = info_json(json_file['keyboard']) + layout = json_data['layout'] + info_data = info_json(json_data['keyboard']) if layout in info_data.get('layout_aliases', {}): - layout = json_file['layout'] = info_data['layout_aliases'][layout] + layout = json_data['layout'] = info_data['layout_aliases'][layout] if layout in info_data.get('layouts'): - for layer_num, layer in enumerate(json_file['layers']): + for layer_num, layer in enumerate(json_data['layers']): current_layer = [] last_row = 0 @@ -61,9 +87,9 @@ def format_json(cli): current_layer.append(keymap_key) - json_file['layers'][layer_num] = current_layer + json_data['layers'][layer_num] = current_layer - output = json.dumps(json_file, cls=json_encoder, sort_keys=True) + output = json.dumps(json_data, cls=json_encoder, sort_keys=True) if cli.args.inplace: with open(cli.args.json_file, 'w+', encoding='utf-8') as outfile: -- cgit v1.2.3