~ruther/qmk_firmware

36e47cb3aaa6380764ab23e2b0308bf689156aa7 — QMK Bot 3 years ago 3c7c9bd + fbfd531
Merge remote-tracking branch 'origin/master' into develop
M data/schemas/keymap.jsonschema => data/schemas/keymap.jsonschema +6 -1
@@ 53,5 53,10 @@
            "type": "string",
            "description": "asdf"
        }
    }
    },
    "required": [
        "keyboard",
        "layout",
        "layers"
    ]
}

M lib/python/qmk/cli/json2c.py => lib/python/qmk/cli/json2c.py +3 -10
@@ 1,12 1,11 @@
"""Generate a keymap.c from a configurator export.
"""
import json

from argcomplete.completers import FilesCompleter
from milc import cli

import qmk.keymap
import qmk.path
from qmk.commands import parse_configurator_json


@cli.argument('-o', '--output', arg_only=True, type=qmk.path.normpath, help='File to write to')


@@ 19,14 18,8 @@ def json2c(cli):
    This command uses the `qmk.keymap` module to generate a keymap.c from a configurator export. The generated keymap is written to stdout, or to a file if -o is provided.
    """

    try:
        # Parse the configurator from json file (or stdin)
        user_keymap = json.load(cli.args.filename)

    except json.decoder.JSONDecodeError as ex:
        cli.log.error('The JSON input does not appear to be valid.')
        cli.log.error(ex)
        return False
    # Parse the configurator from json file (or stdin)
    user_keymap = parse_configurator_json(cli.args.filename)

    # Environment processing
    if cli.args.output and cli.args.output.name == '-':

M lib/python/qmk/commands.py => lib/python/qmk/commands.py +15 -4
@@ 1,6 1,5 @@
"""Helper functions for commands.
"""
import json
import os
import sys
import shutil


@@ 9,10 8,11 @@ from subprocess import DEVNULL
from time import strftime

from milc import cli
import jsonschema

import qmk.keymap
from qmk.constants import QMK_FIRMWARE, KEYBOARD_OUTPUT_PREFIX
from qmk.json_schema import json_load
from qmk.json_schema import json_load, validate

time_fmt = '%Y-%m-%d-%H:%M:%S'



@@ 185,6 185,10 @@ def compile_configurator_json(user_keymap, bootloader=None, parallel=1, **env_va

        A command to run to compile and flash the C file.
    """
    # In case the user passes a keymap.json from a keymap directory directly to the CLI.
    # e.g.: qmk compile - < keyboards/clueboard/california/keymaps/default/keymap.json
    user_keymap["keymap"] = user_keymap.get("keymap", "default_json")

    # Write the keymap.c file
    keyboard_filesafe = user_keymap['keyboard'].replace('/', '_')
    target = f'{keyboard_filesafe}_{user_keymap["keymap"]}'


@@ 248,8 252,15 @@ def compile_configurator_json(user_keymap, bootloader=None, parallel=1, **env_va
def parse_configurator_json(configurator_file):
    """Open and parse a configurator json export
    """
    # FIXME(skullydazed/anyone): Add validation here
    user_keymap = json.load(configurator_file)
    user_keymap = json_load(configurator_file)
    # Validate against the jsonschema
    try:
        validate(user_keymap, 'qmk.keymap.v1')

    except jsonschema.ValidationError as e:
        cli.log.error(f'Invalid JSON keymap: {configurator_file} : {e.message}')
        exit(1)

    orig_keyboard = user_keymap['keyboard']
    aliases = json_load(Path('data/mappings/keyboard_aliases.json'))


M lib/python/qmk/json_schema.py => lib/python/qmk/json_schema.py +6 -2
@@ 16,7 16,11 @@ def json_load(json_file):
    Note: file must be a Path object.
    """
    try:
        return hjson.load(json_file.open(encoding='utf-8'))
        # Get the IO Stream for Path objects
        # Not necessary if the data is provided via stdin
        if isinstance(json_file, Path):
            json_file = json_file.open(encoding='utf-8')
        return hjson.load(json_file)

    except (json.decoder.JSONDecodeError, hjson.HjsonDecodeError) as e:
        cli.log.error('Invalid JSON encountered attempting to load {fg_cyan}%s{fg_reset}:\n\t{fg_red}%s', json_file, e)


@@ 62,7 66,7 @@ def create_validator(schema):
    """Creates a validator for the given schema id.
    """
    schema_store = compile_schema_store()
    resolver = jsonschema.RefResolver.from_schema(schema_store['qmk.keyboard.v1'], store=schema_store)
    resolver = jsonschema.RefResolver.from_schema(schema_store[schema], store=schema_store)

    return jsonschema.Draft7Validator(schema_store[schema], resolver=resolver).validate


M lib/python/qmk/path.py => lib/python/qmk/path.py +5 -1
@@ 70,9 70,13 @@ def normpath(path):


class FileType(argparse.FileType):
    def __init__(self, encoding='UTF-8'):
        # Use UTF8 by default for stdin
        return super().__init__(encoding=encoding)

    def __call__(self, string):
        """normalize and check exists
            otherwise magic strings like '-' for stdin resolve to bad paths
        """
        norm = normpath(string)
        return super().__call__(norm if norm.exists() else string)
        return norm if norm.exists() else super().__call__(string)

M lib/python/qmk/tests/test_cli_commands.py => lib/python/qmk/tests/test_cli_commands.py +12 -0
@@ 156,6 156,18 @@ def test_json2c_stdin():
    assert result.stdout == '#include QMK_KEYBOARD_H\nconst uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {\t[0] = LAYOUT_ortho_1x1(KC_A)};\n\n'


def test_json2c_wrong_json():
    result = check_subcommand('json2c', 'keyboards/handwired/pytest/info.json')
    check_returncode(result, [1])
    assert 'Invalid JSON keymap' in result.stdout


def test_json2c_no_json():
    result = check_subcommand('json2c', 'keyboards/handwired/pytest/pytest.h')
    check_returncode(result, [1])
    assert 'Invalid JSON encountered' in result.stdout


def test_info():
    result = check_subcommand('info', '-kb', 'handwired/pytest/basic')
    check_returncode(result)