diff options
Diffstat (limited to 'lib/python/qmk')
| -rw-r--r-- | lib/python/qmk/cli/c2json.py | 2 | ||||
| -rwxr-xr-x | lib/python/qmk/cli/format/json.py | 2 | ||||
| -rwxr-xr-x | lib/python/qmk/cli/generate/info_json.py | 2 | ||||
| -rwxr-xr-x | lib/python/qmk/cli/info.py | 2 | ||||
| -rw-r--r-- | lib/python/qmk/cli/migrate.py | 2 | ||||
| -rw-r--r-- | lib/python/qmk/cli/new/keyboard.py | 2 | ||||
| -rwxr-xr-x | lib/python/qmk/cli/via2json.py | 2 | ||||
| -rw-r--r-- | lib/python/qmk/importers.py | 6 | ||||
| -rwxr-xr-x | lib/python/qmk/json_encoders.py | 80 | 
9 files changed, 48 insertions, 52 deletions
| diff --git a/lib/python/qmk/cli/c2json.py b/lib/python/qmk/cli/c2json.py index 43110a9387..7f6aca070a 100644 --- a/lib/python/qmk/cli/c2json.py +++ b/lib/python/qmk/cli/c2json.py @@ -57,7 +57,7 @@ def c2json(cli):          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)) +        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) diff --git a/lib/python/qmk/cli/format/json.py b/lib/python/qmk/cli/format/json.py index 19d504491f..058b613294 100755 --- a/lib/python/qmk/cli/format/json.py +++ b/lib/python/qmk/cli/format/json.py @@ -62,4 +62,4 @@ def format_json(cli):                  json_file['layers'][layer_num] = current_layer      # Display the results -    print(json.dumps(json_file, cls=json_encoder)) +    print(json.dumps(json_file, cls=json_encoder, sort_keys=True)) diff --git a/lib/python/qmk/cli/generate/info_json.py b/lib/python/qmk/cli/generate/info_json.py index 0dc80f10cc..08c294146b 100755 --- a/lib/python/qmk/cli/generate/info_json.py +++ b/lib/python/qmk/cli/generate/info_json.py @@ -76,7 +76,7 @@ def generate_info_json(cli):      # Build the info.json file      kb_info_json = info_json(cli.config.generate_info_json.keyboard)      strip_info_json(kb_info_json) -    info_json_text = json.dumps(kb_info_json, indent=4, cls=InfoJSONEncoder) +    info_json_text = json.dumps(kb_info_json, indent=4, cls=InfoJSONEncoder, sort_keys=True)      if cli.args.output:          # Write to a file diff --git a/lib/python/qmk/cli/info.py b/lib/python/qmk/cli/info.py index 839139346c..cfb73ce1fd 100755 --- a/lib/python/qmk/cli/info.py +++ b/lib/python/qmk/cli/info.py @@ -200,7 +200,7 @@ def info(cli):      # Output in the requested format      if cli.args.format == 'json': -        print(json.dumps(kb_info_json, cls=InfoJSONEncoder)) +        print(json.dumps(kb_info_json, cls=InfoJSONEncoder, sort_keys=True))          return True      elif cli.args.format == 'text':          print_dotted_output(kb_info_json) diff --git a/lib/python/qmk/cli/migrate.py b/lib/python/qmk/cli/migrate.py index 4164f9c8ad..c1b1ad1ea9 100644 --- a/lib/python/qmk/cli/migrate.py +++ b/lib/python/qmk/cli/migrate.py @@ -75,7 +75,7 @@ def migrate(cli):      # Finally write out updated info.json      cli.log.info(f'  Updating {target_info}') -    target_info.write_text(json.dumps(info_data.to_dict(), cls=InfoJSONEncoder)) +    target_info.write_text(json.dumps(info_data.to_dict(), cls=InfoJSONEncoder, sort_keys=True))      cli.log.info(f'{{fg_green}}Migration of keyboard {{fg_cyan}}{cli.args.keyboard}{{fg_green}} complete!{{fg_reset}}')      cli.log.info(f"Verify build with {{fg_yellow}}qmk compile -kb {cli.args.keyboard} -km default{{fg_reset}}.") diff --git a/lib/python/qmk/cli/new/keyboard.py b/lib/python/qmk/cli/new/keyboard.py index cdd3919168..ce956d0ce1 100644 --- a/lib/python/qmk/cli/new/keyboard.py +++ b/lib/python/qmk/cli/new/keyboard.py @@ -102,7 +102,7 @@ def augment_community_info(src, dest):          item["matrix"] = [int(item["y"]), int(item["x"])]      # finally write out the updated info.json -    dest.write_text(json.dumps(info, cls=InfoJSONEncoder)) +    dest.write_text(json.dumps(info, cls=InfoJSONEncoder, sort_keys=True))  def _question(*args, **kwargs): diff --git a/lib/python/qmk/cli/via2json.py b/lib/python/qmk/cli/via2json.py index 6edc9dfbe5..77823b5d9d 100755 --- a/lib/python/qmk/cli/via2json.py +++ b/lib/python/qmk/cli/via2json.py @@ -141,5 +141,5 @@ def via2json(cli):      # Generate the keymap.json      keymap_json = generate_json(cli.args.keymap, cli.args.keyboard, keymap_layout, keymap_data, macro_data) -    keymap_lines = [json.dumps(keymap_json, cls=KeymapJSONEncoder)] +    keymap_lines = [json.dumps(keymap_json, cls=KeymapJSONEncoder, sort_keys=True)]      dump_lines(cli.args.output, keymap_lines, cli.args.quiet) diff --git a/lib/python/qmk/importers.py b/lib/python/qmk/importers.py index edc1f940da..8c449a7194 100644 --- a/lib/python/qmk/importers.py +++ b/lib/python/qmk/importers.py @@ -91,7 +91,7 @@ def import_keymap(keymap_data):      keyboard_keymap.parent.mkdir(parents=True, exist_ok=True)      # Dump out all those lovely files -    keyboard_keymap.write_text(json.dumps(keymap_data, cls=KeymapJSONEncoder)) +    keyboard_keymap.write_text(json.dumps(keymap_data, cls=KeymapJSONEncoder, sort_keys=True))      return (kb_name, km_name) @@ -139,8 +139,8 @@ def import_keyboard(info_data, keymap_data=None):      temp = json_load(keyboard_info)      deep_update(temp, info_data) -    keyboard_info.write_text(json.dumps(temp, cls=InfoJSONEncoder)) -    keyboard_keymap.write_text(json.dumps(keymap_data, cls=KeymapJSONEncoder)) +    keyboard_info.write_text(json.dumps(temp, cls=InfoJSONEncoder, sort_keys=True)) +    keyboard_keymap.write_text(json.dumps(keymap_data, cls=KeymapJSONEncoder, sort_keys=True))      return kb_name diff --git a/lib/python/qmk/json_encoders.py b/lib/python/qmk/json_encoders.py index e61c63aff3..1e90f6a288 100755 --- a/lib/python/qmk/json_encoders.py +++ b/lib/python/qmk/json_encoders.py @@ -27,39 +27,56 @@ class QMKJSONEncoder(json.JSONEncoder):          return float(obj) -    def encode_dict_single_line(self, obj): -        return "{" + ", ".join(f"{self.encode(key)}: {self.encode(element)}" for key, element in sorted(obj.items(), key=self.sort_layout)) + "}" +    def encode_dict(self, obj, path): +        """Encode a dict-like object. +        """ +        if obj: +            self.indentation_level += 1 + +            items = sorted(obj.items(), key=self.sort_dict) if self.sort_keys else obj.items() +            output = [self.indent_str + f"{json.dumps(key)}: {self.encode(value, path + [key])}" for key, value in items] -    def encode_list(self, obj, key=None): +            self.indentation_level -= 1 + +            return "{\n" + ",\n".join(output) + "\n" + self.indent_str + "}" +        else: +            return "{}" + +    def encode_dict_single_line(self, obj, path): +        """Encode a dict-like object onto a single line. +        """ +        return "{" + ", ".join(f"{json.dumps(key)}: {self.encode(value, path + [key])}" for key, value in sorted(obj.items(), key=self.sort_layout)) + "}" + +    def encode_list(self, obj, path):          """Encode a list-like object.          """          if self.primitives_only(obj): -            return "[" + ", ".join(self.encode(element) for element in obj) + "]" +            return "[" + ", ".join(self.encode(value, path + [index]) for index, value in enumerate(obj)) + "]"          else:              self.indentation_level += 1 -            if key in ('layout', 'rotary'): -                # These are part of a layout or led/encoder config, put them on a single line. -                output = [self.indent_str + self.encode_dict_single_line(element) for element in obj] +            if path[-1] in ('layout', 'rotary'): +                # These are part of a LED layout or encoder config, put them on a single line +                output = [self.indent_str + self.encode_dict_single_line(value, path + [index]) for index, value in enumerate(obj)]              else: -                output = [self.indent_str + self.encode(element) for element in obj] +                output = [self.indent_str + self.encode(value, path + [index]) for index, value in enumerate(obj)]              self.indentation_level -= 1              return "[\n" + ",\n".join(output) + "\n" + self.indent_str + "]" -    def encode(self, obj, key=None): -        """Encode keymap.json objects for QMK. +    def encode(self, obj, path=[]): +        """Encode JSON objects for QMK.          """          if isinstance(obj, Decimal):              return self.encode_decimal(obj)          elif isinstance(obj, (list, tuple)): -            return self.encode_list(obj, key) +            return self.encode_list(obj, path)          elif isinstance(obj, dict): -            return self.encode_dict(obj, key) +            return self.encode_dict(obj, path)          else:              return super().encode(obj) @@ -80,19 +97,10 @@ class QMKJSONEncoder(json.JSONEncoder):  class InfoJSONEncoder(QMKJSONEncoder):      """Custom encoder to make info.json's a little nicer to work with.      """ -    def encode_dict(self, obj, key): -        """Encode info.json dictionaries. +    def sort_layout(self, item): +        """Sorts the hashes in a nice way.          """ -        if obj: -            self.indentation_level += 1 -            output = [self.indent_str + f"{json.dumps(k)}: {self.encode(v, k)}" for k, v in sorted(obj.items(), key=self.sort_dict)] -            self.indentation_level -= 1 -            return "{\n" + ",\n".join(output) + "\n" + self.indent_str + "}" -        else: -            return "{}" - -    def sort_layout(self, key): -        key = key[0] +        key = item[0]          if key == 'label':              return '00label' @@ -117,14 +125,14 @@ class InfoJSONEncoder(QMKJSONEncoder):          return key -    def sort_dict(self, key): +    def sort_dict(self, item):          """Forces layout to the back of the sort order.          """ -        key = key[0] +        key = item[0]          if self.indentation_level == 1:              if key == 'manufacturer': -                return '10keyboard_name' +                return '10manufacturer'              elif key == 'keyboard_name':                  return '11keyboard_name' @@ -150,19 +158,7 @@ class InfoJSONEncoder(QMKJSONEncoder):  class KeymapJSONEncoder(QMKJSONEncoder):      """Custom encoder to make keymap.json's a little nicer to work with.      """ -    def encode_dict(self, obj, key): -        """Encode dictionary objects for keymap.json. -        """ -        if obj: -            self.indentation_level += 1 -            output = [self.indent_str + f"{json.dumps(k)}: {self.encode(v, k)}" for k, v in sorted(obj.items(), key=self.sort_dict)] -            self.indentation_level -= 1 -            return "{\n" + ",\n".join(output) + "\n" + self.indent_str + "}" - -        else: -            return "{}" - -    def encode_list(self, obj, k=None): +    def encode_list(self, obj, path):          """Encode a list-like object.          """          if self.indentation_level == 2: @@ -196,10 +192,10 @@ class KeymapJSONEncoder(QMKJSONEncoder):              return "[\n" + ",\n".join(output) + "\n" + self.indent_str + "]" -    def sort_dict(self, key): +    def sort_dict(self, item):          """Sorts the hashes in a nice way.          """ -        key = key[0] +        key = item[0]          if self.indentation_level == 1:              if key == 'version': | 
