Merge remote-tracking branch 'origin/master' into develop
This commit is contained in:
		@@ -53,5 +53,10 @@
 | 
				
			|||||||
            "type": "string",
 | 
					            "type": "string",
 | 
				
			||||||
            "description": "asdf"
 | 
					            "description": "asdf"
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    },
 | 
				
			||||||
 | 
					    "required": [
 | 
				
			||||||
 | 
					        "keyboard",
 | 
				
			||||||
 | 
					        "layout",
 | 
				
			||||||
 | 
					        "layers"
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,12 +1,11 @@
 | 
				
			|||||||
"""Generate a keymap.c from a configurator export.
 | 
					"""Generate a keymap.c from a configurator export.
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
import json
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from argcomplete.completers import FilesCompleter
 | 
					from argcomplete.completers import FilesCompleter
 | 
				
			||||||
from milc import cli
 | 
					from milc import cli
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import qmk.keymap
 | 
					import qmk.keymap
 | 
				
			||||||
import qmk.path
 | 
					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')
 | 
					@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.
 | 
					    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)
 | 
					    # Parse the configurator from json file (or stdin)
 | 
				
			||||||
        user_keymap = json.load(cli.args.filename)
 | 
					    user_keymap = parse_configurator_json(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
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Environment processing
 | 
					    # Environment processing
 | 
				
			||||||
    if cli.args.output and cli.args.output.name == '-':
 | 
					    if cli.args.output and cli.args.output.name == '-':
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,5 @@
 | 
				
			|||||||
"""Helper functions for commands.
 | 
					"""Helper functions for commands.
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
import json
 | 
					 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
import shutil
 | 
					import shutil
 | 
				
			||||||
@@ -9,10 +8,11 @@ from subprocess import DEVNULL
 | 
				
			|||||||
from time import strftime
 | 
					from time import strftime
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from milc import cli
 | 
					from milc import cli
 | 
				
			||||||
 | 
					import jsonschema
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import qmk.keymap
 | 
					import qmk.keymap
 | 
				
			||||||
from qmk.constants import QMK_FIRMWARE, KEYBOARD_OUTPUT_PREFIX
 | 
					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'
 | 
					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.
 | 
					        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
 | 
					    # Write the keymap.c file
 | 
				
			||||||
    keyboard_filesafe = user_keymap['keyboard'].replace('/', '_')
 | 
					    keyboard_filesafe = user_keymap['keyboard'].replace('/', '_')
 | 
				
			||||||
    target = f'{keyboard_filesafe}_{user_keymap["keymap"]}'
 | 
					    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):
 | 
					def parse_configurator_json(configurator_file):
 | 
				
			||||||
    """Open and parse a configurator json export
 | 
					    """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']
 | 
					    orig_keyboard = user_keymap['keyboard']
 | 
				
			||||||
    aliases = json_load(Path('data/mappings/keyboard_aliases.json'))
 | 
					    aliases = json_load(Path('data/mappings/keyboard_aliases.json'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,11 @@ def json_load(json_file):
 | 
				
			|||||||
    Note: file must be a Path object.
 | 
					    Note: file must be a Path object.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    try:
 | 
					    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:
 | 
					    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)
 | 
					        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.
 | 
					    """Creates a validator for the given schema id.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    schema_store = compile_schema_store()
 | 
					    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
 | 
					    return jsonschema.Draft7Validator(schema_store[schema], resolver=resolver).validate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -70,9 +70,13 @@ def normpath(path):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class FileType(argparse.FileType):
 | 
					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):
 | 
					    def __call__(self, string):
 | 
				
			||||||
        """normalize and check exists
 | 
					        """normalize and check exists
 | 
				
			||||||
            otherwise magic strings like '-' for stdin resolve to bad paths
 | 
					            otherwise magic strings like '-' for stdin resolve to bad paths
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        norm = normpath(string)
 | 
					        norm = normpath(string)
 | 
				
			||||||
        return super().__call__(norm if norm.exists() else string)
 | 
					        return norm if norm.exists() else super().__call__(string)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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'
 | 
					    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():
 | 
					def test_info():
 | 
				
			||||||
    result = check_subcommand('info', '-kb', 'handwired/pytest/basic')
 | 
					    result = check_subcommand('info', '-kb', 'handwired/pytest/basic')
 | 
				
			||||||
    check_returncode(result)
 | 
					    check_returncode(result)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user