Add flake8 to our test suite and fix all errors (#7379)
* Add flake8 to our test suite and fix all errors * Add some documentation
This commit is contained in:
		@@ -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
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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():
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,6 @@
 | 
			
		||||
"""
 | 
			
		||||
import json
 | 
			
		||||
import os
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
from milc import cli
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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')
 | 
			
		||||
 
 | 
			
		||||
@@ -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]
 | 
			
		||||
    paths = [path for path in glob.iglob(KB_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))
 | 
			
		||||
 | 
			
		||||
    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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user