~ruther/qmk_firmware

58721a433b81790368386cf117347e5bd31fa961 — Joel Challis 1 year, 3 months ago 1522695
Move layout macro OOB checks to lint (#22610)

2 files changed, 28 insertions(+), 12 deletions(-)

M lib/python/qmk/cli/generate/keyboard_h.py
M lib/python/qmk/info.py
M lib/python/qmk/cli/generate/keyboard_h.py => lib/python/qmk/cli/generate/keyboard_h.py +2 -9
@@ 33,18 33,11 @@ def _generate_layouts(keyboard, kb_info_json):
        layout_keys = []
        layout_matrix = [['KC_NO'] * col_num for _ in range(row_num)]

        for index, key_data in enumerate(layout_data['layout']):
        for key_data in layout_data['layout']:
            row, col = key_data['matrix']
            identifier = f'k{ROW_LETTERS[row]}{COL_LETTERS[col]}'

            if row >= row_num or col >= col_num:
                key_name = key_data.get('label', identifier)
                if row >= row_num:
                    cli.log.error(f'{keyboard}/{layout_name}: Matrix row for key {index} ({key_name}) is {row} but must be less than {row_num}')

                if col >= col_num:
                    cli.log.error(f'{keyboard}/{layout_name}: Matrix column for key {index} ({key_name}) is {col} but must be less than {col_num}')

                cli.log.error(f'Skipping layouts due to {layout_name} containing invalid matrix values')
                return []

            layout_matrix[row][col] = identifier

M lib/python/qmk/info.py => lib/python/qmk/info.py +26 -3
@@ 7,7 7,7 @@ from dotty_dict import dotty

from milc import cli

from qmk.constants import CHIBIOS_PROCESSORS, LUFA_PROCESSORS, VUSB_PROCESSORS
from qmk.constants import COL_LETTERS, ROW_LETTERS, CHIBIOS_PROCESSORS, LUFA_PROCESSORS, VUSB_PROCESSORS
from qmk.c_parse import find_layouts, parse_config_h_file, find_led_config
from qmk.json_schema import deep_update, json_load, validate
from qmk.keyboard import config_h, rules_mk


@@ 78,9 78,11 @@ def _find_invalid_encoder_index(info_data):
    return ret


def _additional_validation(keyboard, info_data):
def _validate_layouts(keyboard, info_data):
    """Non schema checks
    """
    col_num = info_data.get('matrix_size', {}).get('cols', 0)
    row_num = info_data.get('matrix_size', {}).get('rows', 0)
    layouts = info_data.get('layouts', {})
    layout_aliases = info_data.get('layout_aliases', {})
    community_layouts = info_data.get('community_layouts', [])


@@ 90,6 92,16 @@ def _additional_validation(keyboard, info_data):
    if len(layouts) == 0 or all(not layout.get('json_layout', False) for layout in layouts.values()):
        _log_error(info_data, 'No LAYOUTs defined! Need at least one layout defined in info.json.')

    # Make sure all matrix values are in bounds
    for layout_name, layout_data in layouts.items():
        for index, key_data in enumerate(layout_data['layout']):
            row, col = key_data['matrix']
            key_name = key_data.get('label', f'k{ROW_LETTERS[row]}{COL_LETTERS[col]}')
            if row >= row_num:
                _log_error(info_data, f'{layout_name}: Matrix row for key {index} ({key_name}) is {row} but must be less than {row_num}')
            if col >= col_num:
                _log_error(info_data, f'{layout_name}: Matrix column for key {index} ({key_name}) is {col} but must be less than {col_num}')

    # Warn if physical positions are offset (at least one key should be at x=0, and at least one key at y=0)
    for layout_name, layout_data in layouts.items():
        offset_x = min([_get_key_left_position(k) for k in layout_data['layout']])


@@ 122,12 134,20 @@ def _additional_validation(keyboard, info_data):
        if layout_name not in layouts and layout_name not in layout_aliases:
            _log_error(info_data, 'Claims to support community layout %s but no %s() macro found' % (layout, layout_name))


def _validate_keycodes(keyboard, info_data):
    """Non schema checks
    """
    # keycodes with length > 7 must have short forms for visualisation purposes
    for decl in info_data.get('keycodes', []):
        if len(decl["key"]) > 7:
            if not decl.get("aliases", []):
                _log_error(info_data, f'Keycode {decl["key"]} has no short form alias')


def _validate_encoders(keyboard, info_data):
    """Non schema checks
    """
    # encoder IDs in layouts must be in range and not duplicated
    found = _find_invalid_encoder_index(info_data)
    for layout_name, encoder_index, reason in found:


@@ 141,7 161,10 @@ def _validate(keyboard, info_data):
    try:
        validate(info_data, 'qmk.api.keyboard.v1')

        _additional_validation(keyboard, info_data)
        # Additional validation
        _validate_layouts(keyboard, info_data)
        _validate_keycodes(keyboard, info_data)
        _validate_encoders(keyboard, info_data)

    except jsonschema.ValidationError as e:
        json_path = '.'.join([str(p) for p in e.absolute_path])

Do not follow this link