diff options
-rwxr-xr-x | bin/qmk | 4 | ||||
-rw-r--r-- | lib/python/kle2xy.py | 2 | ||||
-rwxr-xr-x | lib/python/qmk/cli/compile.py | 3 | ||||
-rw-r--r-- | lib/python/qmk/cli/config.py | 94 | ||||
-rwxr-xr-x | lib/python/qmk/cli/doctor.py | 2 | ||||
-rw-r--r-- | lib/python/qmk/cli/flash.py | 10 | ||||
-rwxr-xr-x | lib/python/qmk/cli/json/keymap.py | 1 | ||||
-rwxr-xr-x | lib/python/qmk/cli/kle2json.py | 4 | ||||
-rw-r--r-- | lib/python/qmk/cli/list/keyboards.py | 26 | ||||
-rw-r--r-- | lib/python/qmk/cli/pytest.py | 16 | ||||
-rw-r--r-- | lib/python/qmk/keymap.py | 4 | ||||
-rw-r--r-- | lib/python/qmk/path.py | 1 | ||||
-rw-r--r-- | requirements.txt | 2 | ||||
-rw-r--r-- | setup.cfg | 9 |
14 files changed, 93 insertions, 85 deletions
@@ -41,7 +41,7 @@ else: os.environ['QMK_VERSION'] = 'nogit-' + strftime('%Y-%m-%d-%H:%M:%S') + '-dirty' # Setup the CLI -import milc +import milc # noqa milc.EMOJI_LOGLEVELS['INFO'] = '{fg_blue}Ψ{style_reset_all}' @@ -61,7 +61,7 @@ def main(): os.chdir(qmk_dir) # Import the subcommands - import qmk.cli + import qmk.cli # noqa # Execute return_code = milc.cli() diff --git a/lib/python/kle2xy.py b/lib/python/kle2xy.py index 9291443190..bff1d025b7 100644 --- a/lib/python/kle2xy.py +++ b/lib/python/kle2xy.py @@ -46,7 +46,7 @@ class KLE2xy(list): if 'name' in properties: self.name = properties['name'] - def parse_layout(self, layout): + def parse_layout(self, layout): # noqa FIXME(skullydazed): flake8 says this has a complexity of 25, it should be refactored. # Wrap this in a dictionary so hjson will parse KLE raw data layout = '{"layout": [' + layout + ']}' layout = hjson.loads(layout)['layout'] diff --git a/lib/python/qmk/cli/compile.py b/lib/python/qmk/cli/compile.py index 5c29800096..234ffb12ca 100755 --- a/lib/python/qmk/cli/compile.py +++ b/lib/python/qmk/cli/compile.py @@ -2,9 +2,6 @@ You can compile a keymap already in the repo or using a QMK Configurator export. """ -import json -import os -import sys import subprocess from argparse import FileType diff --git a/lib/python/qmk/cli/config.py b/lib/python/qmk/cli/config.py index c4ee20cba5..e17d8bb9ba 100644 --- a/lib/python/qmk/cli/config.py +++ b/lib/python/qmk/cli/config.py @@ -1,8 +1,5 @@ """Read and write configuration settings """ -import os -import subprocess - from milc import cli @@ -12,6 +9,54 @@ def print_config(section, key): cli.echo('%s.%s{fg_cyan}={fg_reset}%s', section, key, cli.config[section][key]) +def show_config(): + """Print the current configuration to stdout. + """ + for section in cli.config: + for key in cli.config[section]: + print_config(section, key) + + +def parse_config_token(config_token): + """Split a user-supplied configuration-token into its components. + """ + section = option = value = None + + if '=' in config_token and '.' not in config_token: + cli.log.error('Invalid configuration token, the key must be of the form <section>.<option>: %s', config_token) + return section, option, value + + # Separate the key (<section>.<option>) from the value + if '=' in config_token: + key, value = config_token.split('=') + else: + key = config_token + + # Extract the section and option from the key + if '.' in key: + section, option = key.split('.', 1) + else: + section = key + + return section, option, value + + +def set_config(section, option, value): + """Set a config key in the running config. + """ + log_string = '%s.%s{fg_cyan}:{fg_reset} %s {fg_cyan}->{fg_reset} %s' + if cli.args.read_only: + log_string += ' {fg_red}(change not written)' + + cli.echo(log_string, section, option, cli.config[section][option], value) + + if not cli.args.read_only: + if value == 'None': + del cli.config[section][option] + else: + cli.config[section][option] = value + + @cli.argument('-ro', '--read-only', arg_only=True, action='store_true', help='Operate in read-only mode.') @cli.argument('configs', nargs='*', arg_only=True, help='Configuration options to read or write.') @cli.subcommand("Read and write configuration settings.") @@ -33,12 +78,7 @@ def config(cli): No validation is done to ensure that the supplied section.key is actually used by qmk scripts. """ if not cli.args.configs: - # Walk the config tree - for section in cli.config: - for key in cli.config[section]: - print_config(section, key) - - return True + return show_config() # Process config_tokens save_config = False @@ -46,43 +86,23 @@ def config(cli): for argument in cli.args.configs: # Split on space in case they quoted multiple config tokens for config_token in argument.split(' '): - # Extract the section, config_key, and value to write from the supplied config_token. - if '=' in config_token: - key, value = config_token.split('=') - else: - key = config_token - value = None - - if '.' in key: - section, config_key = key.split('.', 1) - else: - section = key - config_key = None + section, option, value = parse_config_token(config_token) # Validation - if config_key and '.' in config_key: - cli.log.error('Config keys may not have more than one period! "%s" is not valid.', key) + if option and '.' in option: + cli.log.error('Config keys may not have more than one period! "%s" is not valid.', config_token) return False # Do what the user wants - if section and config_key and value: - # Write a config key - log_string = '%s.%s{fg_cyan}:{fg_reset} %s {fg_cyan}->{fg_reset} %s' - if cli.args.read_only: - log_string += ' {fg_red}(change not written)' - - cli.echo(log_string, section, config_key, cli.config[section][config_key], value) - + if section and option and value: + # Write a configuration option + set_config(section, option, value) if not cli.args.read_only: - if value == 'None': - del cli.config[section][config_key] - else: - cli.config[section][config_key] = value save_config = True - elif section and config_key: + elif section and option: # Display a single key - print_config(section, config_key) + print_config(section, option) elif section: # Display an entire section diff --git a/lib/python/qmk/cli/doctor.py b/lib/python/qmk/cli/doctor.py index c2723bfcbb..1010eafb33 100755 --- a/lib/python/qmk/cli/doctor.py +++ b/lib/python/qmk/cli/doctor.py @@ -2,11 +2,9 @@ Check up for QMK environment. """ -import os import platform import shutil import subprocess -from glob import glob from milc import cli diff --git a/lib/python/qmk/cli/flash.py b/lib/python/qmk/cli/flash.py index 37556aaafd..031cb94967 100644 --- a/lib/python/qmk/cli/flash.py +++ b/lib/python/qmk/cli/flash.py @@ -3,17 +3,11 @@ You can compile a keymap already in the repo or using a QMK Configurator export. A bootloader must be specified. """ -import os -import sys import subprocess -from argparse import FileType - -from milc import cli -from qmk.commands import create_make_command -from qmk.commands import parse_configurator_json -from qmk.commands import compile_configurator_json import qmk.path +from milc import cli +from qmk.commands import compile_configurator_json, create_make_command, parse_configurator_json def print_bootloader_help(): diff --git a/lib/python/qmk/cli/json/keymap.py b/lib/python/qmk/cli/json/keymap.py index 88ea357f1f..b3dfc2f9a4 100755 --- a/lib/python/qmk/cli/json/keymap.py +++ b/lib/python/qmk/cli/json/keymap.py @@ -2,7 +2,6 @@ """ import json import os -import sys from milc import cli diff --git a/lib/python/qmk/cli/kle2json.py b/lib/python/qmk/cli/kle2json.py index 5a4e97e3ab..00f63d3622 100755 --- a/lib/python/qmk/cli/kle2json.py +++ b/lib/python/qmk/cli/kle2json.py @@ -1,10 +1,8 @@ """Convert raw KLE to JSON - """ import json import os from pathlib import Path -from argparse import FileType from decimal import Decimal from collections import OrderedDict @@ -23,7 +21,7 @@ class CustomJSONEncoder(json.JSONEncoder): return float(obj) except TypeError: pass - return JSONEncoder.default(self, obj) + return json.JSONEncoder.default(self, obj) @cli.argument('filename', help='The KLE raw txt to convert') diff --git a/lib/python/qmk/cli/list/keyboards.py b/lib/python/qmk/cli/list/keyboards.py index 2a29ccb146..76e7760e84 100644 --- a/lib/python/qmk/cli/list/keyboards.py +++ b/lib/python/qmk/cli/list/keyboards.py @@ -1,27 +1,27 @@ """List the keyboards currently defined within QMK """ import os -import re import glob from milc import cli +BASE_PATH = os.path.join(os.getcwd(), "keyboards") + os.path.sep +KB_WILDCARD = os.path.join(BASE_PATH, "**", "rules.mk") + + +def find_name(path): + """Determine the keyboard name by stripping off the base_path and rules.mk. + """ + return path.replace(BASE_PATH, "").replace(os.path.sep + "rules.mk", "") + @cli.subcommand("List the keyboards currently defined within QMK") def list_keyboards(cli): """List the keyboards currently defined within QMK """ - - base_path = os.path.join(os.getcwd(), "keyboards") + os.path.sep - kb_path_wildcard = os.path.join(base_path, "**", "rules.mk") - # find everywhere we have rules.mk where keymaps isn't in the path - paths = [path for path in glob.iglob(kb_path_wildcard, recursive=True) if 'keymaps' not in path] - - # strip the keyboard directory path prefix and rules.mk suffix and alphabetize - find_name = lambda path: path.replace(base_path, "").replace(os.path.sep + "rules.mk", "") - names = sorted(map(find_name, paths)) + paths = [path for path in glob.iglob(KB_WILDCARD, recursive=True) if 'keymaps' not in path] - for name in names: - # We echo instead of cli.log.info to allow easier piping of this output - cli.echo(name) + # Extract the keyboard name from the path and print it + for keyboard_name in sorted(map(find_name, paths)): + print(keyboard_name) diff --git a/lib/python/qmk/cli/pytest.py b/lib/python/qmk/cli/pytest.py index 14613e1d96..09611d750f 100644 --- a/lib/python/qmk/cli/pytest.py +++ b/lib/python/qmk/cli/pytest.py @@ -2,19 +2,15 @@ QMK script to run unit and integration tests against our python code. """ -import sys +import subprocess + from milc import cli @cli.subcommand('QMK Python Unit Tests') def pytest(cli): - """Use nose2 to run unittests + """Run several linting/testing commands. """ - try: - import nose2 - - except ImportError: - cli.log.error('Could not import nose2! Please install it with {fg_cyan}pip3 install nose2') - return False - - nose2.discover(argv=['nose2', '-v']) + flake8 = subprocess.run(['flake8', 'lib/python', 'bin/qmk']) + nose2 = subprocess.run(['nose2', '-v']) + return flake8.returncode | nose2.returncode diff --git a/lib/python/qmk/keymap.py b/lib/python/qmk/keymap.py index 396b53a6f5..f4a2893f38 100644 --- a/lib/python/qmk/keymap.py +++ b/lib/python/qmk/keymap.py @@ -1,12 +1,8 @@ """Functions that help you work with QMK keymaps. """ -import json -import logging import os -from traceback import format_exc import qmk.path -from qmk.errors import NoSuchKeyboardError # The `keymap.c` template to use when a keyboard doesn't have its own DEFAULT_KEYMAP_C = """#include QMK_KEYBOARD_H diff --git a/lib/python/qmk/path.py b/lib/python/qmk/path.py index 2149625cc6..cf087265fb 100644 --- a/lib/python/qmk/path.py +++ b/lib/python/qmk/path.py @@ -2,7 +2,6 @@ """ import logging import os -from pkgutil import walk_packages from qmk.errors import NoSuchKeyboardError diff --git a/requirements.txt b/requirements.txt index aa6ee1ba32..033b688fc6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,3 +4,5 @@ appdirs argcomplete colorama hjson +nose2 +flake8 @@ -1,4 +1,13 @@ # Python settings for QMK +[flake8] +ignore = + # QMK is ok with long lines. + E501 +per_file_ignores = + **/__init__.py:F401 + +# Let's slowly crank this down +max_complexity=16 [yapf] # Align closing bracket with visual indentation. |