Add decorators for determining keyboard and keymap based on current directory (#8191)

* Use pathlib everywhere we can

* Improvements based on @erovia's feedback

* rework qmk compile and qmk flash to use pathlib

* style

* Remove the subcommand_name argument from find_keyboard_keymap()

* add experimental decorators

* Create decorators for finding keyboard and keymap based on current directory.

Decorators were inspired by @Erovia's brilliant work on the proof of concept.
This commit is contained in:
skullydazed 2020-03-13 15:47:04 -07:00 committed by GitHub
parent 5e98eaaaff
commit f81b0e35a6
Failed to generate hash of commit
8 changed files with 152 additions and 99 deletions

View file

@ -2,6 +2,8 @@
We list each subcommand here explicitly because all the reliable ways of searching for modules are slow and delay startup.
"""
from milc import cli
from . import cformat
from . import compile
from . import config
@ -16,3 +18,6 @@ from . import kle2json
from . import new
from . import pyformat
from . import pytest
if not hasattr(cli, 'config_source'):
cli.log.warning("Your QMK CLI is out of date. Please upgrade with `pip3 install --upgrade qmk` or by using your package manager.")

View file

@ -8,13 +8,17 @@ from argparse import FileType
from milc import cli
import qmk.path
from qmk.commands import compile_configurator_json, create_make_command, find_keyboard_keymap, parse_configurator_json
from qmk.decorators import automagic_keyboard, automagic_keymap
from qmk.commands import compile_configurator_json, create_make_command, parse_configurator_json
@cli.argument('filename', nargs='?', arg_only=True, type=FileType('r'), help='The configurator export to compile')
@cli.argument('-kb', '--keyboard', help='The keyboard to build a firmware for. Ignored when a configurator export is supplied.')
@cli.argument('-km', '--keymap', help='The keymap to build a firmware for. Ignored when a configurator export is supplied.')
@cli.argument('-n', '--dry-run', arg_only=True, action='store_true', help="Don't actually build, just show the make command to be run.")
@cli.subcommand('Compile a QMK Firmware.')
@automagic_keyboard
@automagic_keymap
def compile(cli):
"""Compile a QMK Firmware.
@ -22,8 +26,10 @@ def compile(cli):
If a keyboard and keymap are provided this command will build a firmware based on that.
"""
command = None
if cli.args.filename:
# If a configurator JSON was provided skip straight to compiling it
# If a configurator JSON was provided generate a keymap and compile it
# FIXME(skullydazed): add code to check and warn if the keymap already exists when compiling a json keymap.
user_keymap = parse_configurator_json(cli.args.filename)
keymap_path = qmk.path.keymap(user_keymap['keyboard'])
@ -32,16 +38,23 @@ def compile(cli):
cli.log.info('Wrote keymap to {fg_cyan}%s/%s/keymap.c', keymap_path, user_keymap['keymap'])
else:
# Perform the action the user specified
user_keyboard, user_keymap = find_keyboard_keymap()
if user_keyboard and user_keymap:
if cli.config.compile.keyboard and cli.config.compile.keymap:
# Generate the make command for a specific keyboard/keymap.
command = create_make_command(user_keyboard, user_keymap)
command = create_make_command(cli.config.compile.keyboard, cli.config.compile.keymap)
else:
cli.log.error('You must supply a configurator export, both `--keyboard` and `--keymap`, or be in a directory for a keyboard or keymap.')
cli.echo('usage: qmk compile [-h] [-b] [-kb KEYBOARD] [-km KEYMAP] [filename]')
return False
elif not cli.config.compile.keyboard:
cli.log.error('Could not determine keyboard!')
elif not cli.config.compile.keymap:
cli.log.error('Could not determine keymap!')
cli.log.info('Compiling keymap with {fg_cyan}%s\n\n', ' '.join(command))
subprocess.run(command)
# Compile the firmware, if we're able to
if command:
cli.log.info('Compiling keymap with {fg_cyan}%s', ' '.join(command))
if not cli.args.dry_run:
cli.echo('\n')
subprocess.run(command)
else:
cli.log.error('You must supply a configurator export, both `--keyboard` and `--keymap`, or be in a directory for a keyboard or keymap.')
cli.echo('usage: qmk compile [-h] [-b] [-kb KEYBOARD] [-km KEYMAP] [filename]')
return False

View file

@ -6,9 +6,11 @@ A bootloader must be specified.
import subprocess
from argparse import FileType
import qmk.path
from milc import cli
from qmk.commands import compile_configurator_json, create_make_command, find_keyboard_keymap, parse_configurator_json
import qmk.path
from qmk.decorators import automagic_keyboard, automagic_keymap
from qmk.commands import compile_configurator_json, create_make_command, parse_configurator_json
def print_bootloader_help():
@ -28,12 +30,15 @@ def print_bootloader_help():
cli.echo('For more info, visit https://docs.qmk.fm/#/flashing')
@cli.argument('-bl', '--bootloader', default='flash', help='The flash command, corresponding to qmk\'s make options of bootloaders.')
@cli.argument('filename', nargs='?', arg_only=True, type=FileType('r'), help='The configurator export JSON to compile.')
@cli.argument('-b', '--bootloaders', action='store_true', help='List the available bootloaders.')
@cli.argument('-bl', '--bootloader', default='flash', help='The flash command, corresponding to qmk\'s make options of bootloaders.')
@cli.argument('-km', '--keymap', help='The keymap to build a firmware for. Use this if you dont have a configurator file. Ignored when a configurator file is supplied.')
@cli.argument('-kb', '--keyboard', help='The keyboard to build a firmware for. Use this if you dont have a configurator file. Ignored when a configurator file is supplied.')
@cli.argument('-b', '--bootloaders', action='store_true', help='List the available bootloaders.')
@cli.argument('-n', '--dry-run', arg_only=True, action='store_true', help="Don't actually build, just show the make command to be run.")
@cli.subcommand('QMK Flash.')
@automagic_keyboard
@automagic_keymap
def flash(cli):
"""Compile and or flash QMK Firmware or keyboard/layout
@ -42,12 +47,13 @@ def flash(cli):
If no file is supplied, keymap and keyboard are expected.
If bootloader is omitted, the one according to the rules.mk will be used.
If bootloader is omitted the make system will use the configured bootloader for that keyboard.
"""
command = ''
if cli.args.bootloaders:
# Provide usage and list bootloaders
cli.echo('usage: qmk flash [-h] [-b] [-kb KEYBOARD] [-km KEYMAP] [-bl BOOTLOADER] [filename]')
cli.echo('usage: qmk flash [-h] [-b] [-n] [-kb KEYBOARD] [-km KEYMAP] [-bl BOOTLOADER] [filename]')
print_bootloader_help()
return False
@ -60,16 +66,23 @@ def flash(cli):
cli.log.info('Wrote keymap to {fg_cyan}%s/%s/keymap.c', keymap_path, user_keymap['keymap'])
else:
# Perform the action the user specified
user_keyboard, user_keymap = find_keyboard_keymap()
if user_keyboard and user_keymap:
if cli.config.flash.keyboard and cli.config.flash.keymap:
# Generate the make command for a specific keyboard/keymap.
command = create_make_command(user_keyboard, user_keymap, cli.args.bootloader)
command = create_make_command(cli.config.flash.keyboard, cli.config.flash.keymap, cli.args.bootloader)
else:
cli.log.error('You must supply a configurator export or both `--keyboard` and `--keymap`.')
cli.echo('usage: qmk flash [-h] [-b] [-kb KEYBOARD] [-km KEYMAP] [-bl BOOTLOADER] [filename]')
return False
elif not cli.config.flash.keyboard:
cli.log.error('Could not determine keyboard!')
elif not cli.config.flash.keymap:
cli.log.error('Could not determine keymap!')
cli.log.info('Flashing keymap with {fg_cyan}%s\n\n', ' '.join(command))
subprocess.run(command)
# Compile the firmware, if we're able to
if command:
cli.log.info('Compiling keymap with {fg_cyan}%s', ' '.join(command))
if not cli.args.dry_run:
cli.echo('\n')
subprocess.run(command)
else:
cli.log.error('You must supply a configurator export, both `--keyboard` and `--keymap`, or be in a directory for a keyboard or keymap.')
cli.echo('usage: qmk flash [-h] [-b] [-n] [-kb KEYBOARD] [-km KEYMAP] [-bl BOOTLOADER] [filename]')
return False

View file

@ -1,12 +1,15 @@
"""List the keymaps for a specific keyboard
"""
from milc import cli
import qmk.keymap
from qmk.decorators import automagic_keyboard
from qmk.errors import NoSuchKeyboardError
@cli.argument("-kb", "--keyboard", help="Specify keyboard name. Example: 1upkeyboards/1up60hse")
@cli.subcommand("List the keymaps for a specific keyboard")
@automagic_keyboard
def list_keymaps(cli):
"""List the keymaps for a specific keyboard
"""

View file

@ -4,12 +4,15 @@ import shutil
from pathlib import Path
import qmk.path
from qmk.decorators import automagic_keyboard, automagic_keymap
from milc import cli
@cli.argument('-kb', '--keyboard', help='Specify keyboard name. Example: 1upkeyboards/1up60hse')
@cli.argument('-km', '--keymap', help='Specify the name for the new keymap directory')
@cli.subcommand('Creates a new keymap for the keyboard of your choosing')
@automagic_keyboard
@automagic_keymap
def new_keymap(cli):
"""Creates a new keymap for the keyboard of your choosing.
"""