diff options
| author | Zach White <[email protected]> | 2021-02-27 12:00:50 -0800 | 
|---|---|---|
| committer | GitHub <[email protected]> | 2021-02-27 12:00:50 -0800 | 
| commit | 1581ea48dcd48d0d3f42cc09b388c468aedec45d (patch) | |
| tree | 2d028036a4bf80c2e47b952931544f95ba2174e9 /lib/python | |
| parent | 23ed6c4ec0bfb27612da8a7b78d1b484acc23f3f (diff) | |
| download | qmk_firmware-1581ea48dcd48d0d3f42cc09b388c468aedec45d.tar.gz qmk_firmware-1581ea48dcd48d0d3f42cc09b388c468aedec45d.zip | |
Fix develop (#12039)
Fixes file encoding errors on Windows, and layouts not correctly merging into info.json.
* force utf8 encoding
* correctly merge layouts and layout aliases
* show what aliases point to
Diffstat (limited to 'lib/python')
| -rw-r--r-- | lib/python/qmk/c_parse.py | 11 | ||||
| -rw-r--r-- | lib/python/qmk/cli/chibios/confmigrate.py | 8 | ||||
| -rwxr-xr-x | lib/python/qmk/cli/generate/layouts.py | 4 | ||||
| -rwxr-xr-x | lib/python/qmk/cli/info.py | 7 | ||||
| -rwxr-xr-x | lib/python/qmk/cli/kle2json.py | 2 | ||||
| -rw-r--r-- | lib/python/qmk/info.py | 44 | ||||
| -rw-r--r-- | lib/python/qmk/keymap.py | 6 | ||||
| -rw-r--r-- | lib/python/qmk/os_helpers/linux/__init__.py | 2 | ||||
| -rw-r--r-- | lib/python/qmk/tests/test_cli_commands.py | 2 | 
9 files changed, 56 insertions, 30 deletions
| diff --git a/lib/python/qmk/c_parse.py b/lib/python/qmk/c_parse.py index 89dd278b7e..d4f39c8839 100644 --- a/lib/python/qmk/c_parse.py +++ b/lib/python/qmk/c_parse.py @@ -46,7 +46,7 @@ def find_layouts(file):      parsed_layouts = {}      # Search the file for LAYOUT macros and aliases -    file_contents = file.read_text() +    file_contents = file.read_text(encoding='utf-8')      file_contents = comment_remover(file_contents)      file_contents = file_contents.replace('\\\n', '') @@ -87,12 +87,7 @@ def find_layouts(file):              except ValueError:                  continue -    # Populate our aliases -    for alias, text in aliases.items(): -        if text in parsed_layouts and 'KEYMAP' not in alias: -            parsed_layouts[alias] = parsed_layouts[text] - -    return parsed_layouts +    return parsed_layouts, aliases  def parse_config_h_file(config_h_file, config_h=None): @@ -104,7 +99,7 @@ def parse_config_h_file(config_h_file, config_h=None):      config_h_file = Path(config_h_file)      if config_h_file.exists(): -        config_h_text = config_h_file.read_text() +        config_h_text = config_h_file.read_text(encoding='utf-8')          config_h_text = config_h_text.replace('\\\n', '')          config_h_text = strip_multiline_comment(config_h_text) diff --git a/lib/python/qmk/cli/chibios/confmigrate.py b/lib/python/qmk/cli/chibios/confmigrate.py index 3e348b2b07..89995931a4 100644 --- a/lib/python/qmk/cli/chibios/confmigrate.py +++ b/lib/python/qmk/cli/chibios/confmigrate.py @@ -40,7 +40,7 @@ file_header = """\  def collect_defines(filepath): -    with open(filepath, 'r') as f: +    with open(filepath, 'r', encoding='utf-8') as f:          content = f.read()          define_search = re.compile(r'(?m)^#\s*define\s+(?:.*\\\r?\n)*.*$', re.MULTILINE)          value_search = re.compile(r'^#\s*define\s+(?P<name>[a-zA-Z0-9_]+(\([^\)]*\))?)\s*(?P<value>.*)', re.DOTALL) @@ -146,17 +146,17 @@ def chibios_confmigrate(cli):          if cli.args.input.name == "chconf.h" and ("CHCONF_H" in input_defs["dict"] or "_CHCONF_H_" in input_defs["dict"] or cli.args.force):              migrate_chconf_h(to_override, outfile=sys.stdout)              if cli.args.overwrite: -                with open(cli.args.input, "w") as out_file: +                with open(cli.args.input, "w", encoding='utf-8') as out_file:                      migrate_chconf_h(to_override, outfile=out_file)          elif cli.args.input.name == "halconf.h" and ("HALCONF_H" in input_defs["dict"] or "_HALCONF_H_" in input_defs["dict"] or cli.args.force):              migrate_halconf_h(to_override, outfile=sys.stdout)              if cli.args.overwrite: -                with open(cli.args.input, "w") as out_file: +                with open(cli.args.input, "w", encoding='utf-8') as out_file:                      migrate_halconf_h(to_override, outfile=out_file)          elif cli.args.input.name == "mcuconf.h" and ("MCUCONF_H" in input_defs["dict"] or "_MCUCONF_H_" in input_defs["dict"] or cli.args.force):              migrate_mcuconf_h(to_override, outfile=sys.stdout)              if cli.args.overwrite: -                with open(cli.args.input, "w") as out_file: +                with open(cli.args.input, "w", encoding='utf-8') as out_file:                      migrate_mcuconf_h(to_override, outfile=out_file) diff --git a/lib/python/qmk/cli/generate/layouts.py b/lib/python/qmk/cli/generate/layouts.py index b7baae0651..15b289522e 100755 --- a/lib/python/qmk/cli/generate/layouts.py +++ b/lib/python/qmk/cli/generate/layouts.py @@ -82,6 +82,10 @@ def generate_layouts(cli):          layouts_h_lines.append(rows)          layouts_h_lines.append('}') +    for alias, target in kb_info_json.get('layout_aliases', {}).items(): +        layouts_h_lines.append('') +        layouts_h_lines.append('#define %s %s' % (alias, target)) +      # Show the results      layouts_h = '\n'.join(layouts_h_lines) + '\n' diff --git a/lib/python/qmk/cli/info.py b/lib/python/qmk/cli/info.py index 87d7253d4b..a7ce8abf03 100755 --- a/lib/python/qmk/cli/info.py +++ b/lib/python/qmk/cli/info.py @@ -29,7 +29,7 @@ def show_keymap(kb_info_json, title_caps=True):          else:              cli.echo('{fg_blue}keymap_%s{fg_reset}:', cli.config.info.keymap) -        keymap_data = json.load(keymap_path.open()) +        keymap_data = json.load(keymap_path.open(encoding='utf-8'))          layout_name = keymap_data['layout']          for layer_num, layer in enumerate(keymap_data['layers']): @@ -57,7 +57,7 @@ def show_matrix(kb_info_json, title_caps=True):          # Build our label list          labels = []          for key in layout['layout']: -            if key['matrix']: +            if 'matrix' in key:                  row = ROW_LETTERS[key['matrix'][0]]                  col = COL_LETTERS[key['matrix'][1]] @@ -91,6 +91,9 @@ def print_friendly_output(kb_info_json):          cli.echo('{fg_blue}Size{fg_reset}: %s x %s' % (kb_info_json['width'], kb_info_json['height']))      cli.echo('{fg_blue}Processor{fg_reset}: %s', kb_info_json.get('processor', 'Unknown'))      cli.echo('{fg_blue}Bootloader{fg_reset}: %s', kb_info_json.get('bootloader', 'Unknown')) +    if 'layout_aliases' in kb_info_json: +        aliases = [f'{key}={value}' for key, value in kb_info_json['layout_aliases'].items()] +        cli.echo('{fg_blue}Layout aliases:{fg_reset} %s' % (', '.join(aliases),))      if cli.config.info.layouts:          show_layouts(kb_info_json, True) diff --git a/lib/python/qmk/cli/kle2json.py b/lib/python/qmk/cli/kle2json.py index 66d504bfc2..3bb7443582 100755 --- a/lib/python/qmk/cli/kle2json.py +++ b/lib/python/qmk/cli/kle2json.py @@ -27,7 +27,7 @@ def kle2json(cli):          cli.log.error('File {fg_cyan}%s{style_reset_all} was not found.', file_path)          return False      out_path = file_path.parent -    raw_code = file_path.open().read() +    raw_code = file_path.read_text(encoding='utf-8')      # Check if info.json exists, allow overwrite with force      if Path(out_path, "info.json").exists() and not cli.args.force:          cli.log.error('File {fg_cyan}%s/info.json{style_reset_all} already exists, use -f or --force to overwrite.', out_path) diff --git a/lib/python/qmk/info.py b/lib/python/qmk/info.py index 2accaba9e4..cf5dc6640b 100644 --- a/lib/python/qmk/info.py +++ b/lib/python/qmk/info.py @@ -45,7 +45,12 @@ def info_json(keyboard):          info_data['keymaps'][keymap.name] = {'url': f'https://raw.githubusercontent.com/qmk/qmk_firmware/master/{keymap}/keymap.json'}      # Populate layout data -    for layout_name, layout_json in _find_all_layouts(info_data, keyboard).items(): +    layouts, aliases = _find_all_layouts(info_data, keyboard) + +    if aliases: +        info_data['layout_aliases'] = aliases + +    for layout_name, layout_json in layouts.items():          if not layout_name.startswith('LAYOUT_kc'):              layout_json['c_macro'] = True              info_data['layouts'][layout_name] = layout_json @@ -92,7 +97,7 @@ def _json_load(json_file):      Note: file must be a Path object.      """      try: -        return hjson.load(json_file.open()) +        return hjson.load(json_file.open(encoding='utf-8'))      except json.decoder.JSONDecodeError as e:          cli.log.error('Invalid JSON encountered attempting to load {fg_cyan}%s{fg_reset}:\n\t{fg_red}%s', json_file, e) @@ -415,21 +420,28 @@ def _merge_layouts(info_data, new_info_data):  def _search_keyboard_h(path):      current_path = Path('keyboards/') +    aliases = {}      layouts = {} +      for directory in path.parts:          current_path = current_path / directory          keyboard_h = '%s.h' % (directory,)          keyboard_h_path = current_path / keyboard_h          if keyboard_h_path.exists(): -            layouts.update(find_layouts(keyboard_h_path)) +            new_layouts, new_aliases = find_layouts(keyboard_h_path) +            layouts.update(new_layouts) + +            for alias, alias_text in new_aliases.items(): +                if alias_text in layouts: +                    aliases[alias] = alias_text -    return layouts +    return layouts, aliases  def _find_all_layouts(info_data, keyboard):      """Looks for layout macros associated with this keyboard.      """ -    layouts = _search_keyboard_h(Path(keyboard)) +    layouts, aliases = _search_keyboard_h(Path(keyboard))      if not layouts:          # If we don't find any layouts from info.json or keyboard.h we widen our search. This is error prone which is why we want to encourage people to follow the standard above. @@ -437,11 +449,15 @@ def _find_all_layouts(info_data, keyboard):          for file in glob('keyboards/%s/*.h' % keyboard):              if file.endswith('.h'): -                these_layouts = find_layouts(file) +                these_layouts, these_aliases = find_layouts(file) +                  if these_layouts:                      layouts.update(these_layouts) -    return layouts +                if these_aliases: +                    aliases.update(these_aliases) + +    return layouts, aliases  def _log_error(info_data, message): @@ -540,11 +556,19 @@ def merge_info_jsons(keyboard, info_data):              cli.log.error('\t%s: %s', json_path, e.message)              continue -        # Mark the layouts as coming from json -        for layout in new_info_data.get('layouts', {}).values(): -            layout['c_macro'] = False +        # Merge layout data in +        for layout_name, layout in new_info_data.get('layouts', {}).items(): +            if layout_name in info_data['layouts']: +                for new_key, existing_key in zip(layout['layout'], info_data['layouts'][layout_name]['layout']): +                    existing_key.update(new_key) +            else: +                layout['c_macro'] = False +                info_data['layouts'][layout_name] = layout          # Update info_data with the new data +        if 'layouts' in new_info_data: +            del (new_info_data['layouts']) +          deep_update(info_data, new_info_data)      return info_data diff --git a/lib/python/qmk/keymap.py b/lib/python/qmk/keymap.py index 266532f503..d8495c38bc 100644 --- a/lib/python/qmk/keymap.py +++ b/lib/python/qmk/keymap.py @@ -42,7 +42,7 @@ def template_json(keyboard):      template_file = Path('keyboards/%s/templates/keymap.json' % keyboard)      template = {'keyboard': keyboard}      if template_file.exists(): -        template.update(json.loads(template_file.read_text())) +        template.update(json.load(template_file.open(encoding='utf-8')))      return template @@ -58,7 +58,7 @@ def template_c(keyboard):      """      template_file = Path('keyboards/%s/templates/keymap.c' % keyboard)      if template_file.exists(): -        template = template_file.read_text() +        template = template_file.read_text(encoding='utf-8')      else:          template = DEFAULT_KEYMAP_C @@ -469,7 +469,7 @@ def parse_keymap_c(keymap_file, use_cpp=True):          if use_cpp:              keymap_file = _c_preprocess(keymap_file)          else: -            keymap_file = keymap_file.read_text() +            keymap_file = keymap_file.read_text(encoding='utf-8')      keymap = dict()      keymap['layers'] = _get_layers(keymap_file) diff --git a/lib/python/qmk/os_helpers/linux/__init__.py b/lib/python/qmk/os_helpers/linux/__init__.py index a04ac4f8a9..9e73964e47 100644 --- a/lib/python/qmk/os_helpers/linux/__init__.py +++ b/lib/python/qmk/os_helpers/linux/__init__.py @@ -95,7 +95,7 @@ def check_udev_rules():          # Collect all rules from the config files          for rule_file in udev_rules: -            for line in rule_file.read_text().split('\n'): +            for line in rule_file.read_text(encoding='utf-8').split('\n'):                  line = line.strip()                  if not line.startswith("#") and len(line):                      current_rules.add(line) diff --git a/lib/python/qmk/tests/test_cli_commands.py b/lib/python/qmk/tests/test_cli_commands.py index 3efeddb85e..82c42a20e8 100644 --- a/lib/python/qmk/tests/test_cli_commands.py +++ b/lib/python/qmk/tests/test_cli_commands.py @@ -16,7 +16,7 @@ def check_subcommand(command, *args):  def check_subcommand_stdin(file_to_read, command, *args):      """Pipe content of a file to a command and return output.      """ -    with open(file_to_read) as my_file: +    with open(file_to_read, encoding='utf-8') as my_file:          cmd = ['bin/qmk', command, *args]          result = run(cmd, stdin=my_file, stdout=PIPE, stderr=STDOUT, universal_newlines=True)      return result | 
