Merge remote-tracking branch 'origin/master' into develop
This commit is contained in:
commit
36e47cb3aa
6 changed files with 47 additions and 18 deletions
|
@ -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 = parse_configurator_json(cli.args.filename)
|
||||||
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
|
|
||||||
|
|
||||||
# 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)
|
||||||
|
|
Loading…
Reference in a new issue