diff --git a/qmk_cli/git.py b/qmk_cli/git.py index c12768d..2ce6ac2 100644 --- a/qmk_cli/git.py +++ b/qmk_cli/git.py @@ -4,10 +4,6 @@ from milc import cli -default_repo = 'qmk_firmware' -default_fork = 'qmk/' + default_repo -default_branch = 'master' - def git_clone(url, destination, branch): git_clone = [ @@ -18,7 +14,7 @@ def git_clone(url, destination, branch): url, str(destination), ] - cli.log.debug('Git clone command: %s', git_clone) + cli.log.debug(f'Git clone command: {git_clone}', ) try: with subprocess.Popen(git_clone, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, bufsize=1, universal_newlines=True, encoding='utf-8') as p: @@ -28,13 +24,12 @@ def git_clone(url, destination, branch): except Exception as e: git_cmd = ' '.join([s.replace(' ', r'\ ') for s in git_clone]) - cli.log.error("Could not run '%s': %s: %s", git_cmd, e.__class__.__name__, e) + cli.log.error(f'Could not run "{git_cmd}": {e.__class__}: {e}') return False - if p.returncode == 0: - cli.log.info('Successfully cloned %s to %s!', url, destination) - return True - - else: - cli.log.error('git clone exited %d', p.returncode) + if p.returncode != 0: + cli.log.error(f'git clone exited {p.returncode}') return False + + cli.log.info(f'Successfully cloned {url} to {destination}!') + return True diff --git a/qmk_cli/script_qmk.py b/qmk_cli/script_qmk.py index 39c17f5..52ebaab 100644 --- a/qmk_cli/script_qmk.py +++ b/qmk_cli/script_qmk.py @@ -96,9 +96,9 @@ def main(): except ImportError as e: if qmk_firmware.name != 'qmk_firmware': - print('Warning: %s does not end in "qmk_firmware". Do you need to set QMK_HOME to "%s/qmk_firmware"?' % (qmk_firmware, qmk_firmware)) + print(f'Warning: {qmk_firmware} does not end in "qmk_firmware". Do you need to set QMK_HOME to "{qmk_firmware}/qmk_firmware"?') - print('Error: %s: %s', (e.__class__.__name__, e)) + print(f'Error: {e.__class__}: {e}') print_exc() sys.exit(1) @@ -110,7 +110,7 @@ def main(): elif return_code is not True and isinstance(return_code, int): if return_code < 0 or return_code > 255: - milc.cli.log.error('Invalid return_code: %d', return_code) + milc.cli.log.error(f'Invalid return_code: {return_code}') exit(255) exit(return_code) diff --git a/qmk_cli/subcommands/clone.py b/qmk_cli/subcommands/clone.py index 4a8d1e6..fa7c686 100644 --- a/qmk_cli/subcommands/clone.py +++ b/qmk_cli/subcommands/clone.py @@ -13,16 +13,16 @@ @cli.argument('--baseurl', arg_only=True, default='https://github.com', help='The URL all git operations start from (Default: https://github.com)') -@cli.argument('-b', '--branch', arg_only=True, default=default_branch, help='The branch to clone. Default: %s' % default_branch) +@cli.argument('-b', '--branch', arg_only=True, default=default_branch, help=f'The branch to clone. Default: {default_branch}') @cli.argument('destination', arg_only=True, default=Path(os.environ['ORIG_CWD']) / default_repo, type=AbsPath, nargs='?', help='The directory to clone to. Default: (current directory)') -@cli.argument('fork', arg_only=True, default=default_fork, nargs='?', help='The qmk_firmware fork to clone. Default: %s' % default_fork) +@cli.argument('fork', arg_only=True, default=default_fork, nargs='?', help=f'The qmk_firmware fork to clone. Default: {default_fork}') @cli.subcommand('Clone a qmk_firmware fork.') def clone(cli): git_url = '/'.join((cli.args.baseurl, cli.args.fork)) # Exists (but not an empty dir) if cli.args.destination.exists() and any(cli.args.destination.iterdir()): - cli.log.error('Destination already exists: %s', cli.args.destination) + cli.log.error(f'Destination already exists: {cli.args.destination}') exit(1) return git_clone(git_url, cli.args.destination, cli.args.branch) diff --git a/qmk_cli/subcommands/console.py b/qmk_cli/subcommands/console.py index 07a3d10..6378ffe 100644 --- a/qmk_cli/subcommands/console.py +++ b/qmk_cli/subcommands/console.py @@ -57,6 +57,26 @@ } +def _get_next_color(): + """Cycles to the next available log color. + """ + color = LOG_COLOR['colors'][LOG_COLOR['next']] + LOG_COLOR['next'] = (LOG_COLOR['next'] + 1) % len(LOG_COLOR['colors']) + return color + + +def _gen_header(dev): + """Generate a consistent logging segment. + """ + return f'{dev["color"]}{dev["manufacturer_string"]} {dev["product_string"]}{{style_reset_all}} ({dev["color"]}{int2hex(dev["vendor_id"])}:{int2hex(dev["product_id"])}:{dev["index"]}{{style_reset_all}})' + + +def int2hex(number): + """Returns a string representation of the number as hex. + """ + return f'{number:04X}' + + def install_deps(): """Install the necessary dependencies for qmk console. """ @@ -69,9 +89,10 @@ def install_deps(): elif 'windows' in this_platform: command = ['pacboy', 'sync', '--needed', '--noconfirm', '--disable-download-timeout', 'hidapi:x'] else: - cli.log.error('Unsupported platform: %s', this_platform) + cli.log.error(f'Unsupported platform: {this_platform}') - if yesno("Would you like to run `%s` to install the necessary package?", ' '.join(command)): + cmd_str = ' '.join(command) + if yesno(f'Would you like to run "{cmd_str}" to install the necessary package?'): cli.run(command, capture_output=False) return True @@ -85,7 +106,7 @@ def import_usb_core(): return usb.core except ImportError as e: - cli.log.error('Could not import usb.core: %s', e) + cli.log.error(f'Could not import usb.core: {e}') if install_deps(): return import_usb_core() @@ -113,7 +134,7 @@ def import_hid(): return hid except ImportError as e: - cli.log.error('Could not import hid: %s', e) + cli.log.error(f'Could not import hid: {e}') if install_deps(): return import_hid() @@ -131,8 +152,7 @@ def __init__(self, hid_device, numeric): self.device = self.hid.Device(path=hid_device['path']) self.current_line = '' - cli.log.info('Console Connected: %(color)s%(manufacturer_string)s %(product_string)s{style_reset_all} (%(color)s%(vendor_id)04X:%(product_id)04X:%(index)d{style_reset_all})', hid_device) - + cli.log.info(f'Console Connected: {_gen_header(hid_device)}') def read(self, size, encoding='ascii', timeout=1): """Read size bytes from the device. """ @@ -152,12 +172,10 @@ def read_line(self): def run_forever(self): while True: try: - message = {**self.hid_device, 'text': self.read_line()} - identifier = (int2hex(message['vendor_id']), int2hex(message['product_id'])) if self.numeric else (message['manufacturer_string'], message['product_string']) - message['identifier'] = ':'.join(identifier) - message['ts'] = '{style_dim}{fg_green}%s{style_reset_all} ' % (strftime(cli.config.general.datetime_fmt),) if cli.args.timestamp else '' + text = self.read_line() + ts = f'{{style_dim}}{{fg_green}}{strftime(cli.config.general.datetime_fmt)}{{style_reset_all}}' if cli.args.timestamp else '' - cli.echo('%s', '%(ts)s%(color)s%(identifier)s:%(index)d{style_reset_all}: %(text)s' % message) + cli.echo(f'{ts}{_gen_header(self.hid_device)}: {text}') except self.hid.HIDException: break @@ -181,13 +199,12 @@ def run_forever(self): try: for device in list(live_devices): if not live_devices[device]['thread'].is_alive(): - cli.log.info('Console Disconnected: %(color)s%(manufacturer_string)s %(product_string)s{style_reset_all} (%(color)s%(vendor_id)04X:%(product_id)04X:%(index)d{style_reset_all})', live_devices[device]) + cli.log.info(f'Console Disconnected: {_gen_header(live_devices[device])}') del live_devices[device] for device in self.find_devices(): if device['path'] not in live_devices: - device['color'] = LOG_COLOR['colors'][LOG_COLOR['next']] - LOG_COLOR['next'] = (LOG_COLOR['next'] + 1) % len(LOG_COLOR['colors']) + device['color'] = _get_next_color() live_devices[device['path']] = device try: @@ -196,9 +213,7 @@ def run_forever(self): device['thread'].start() except Exception as e: - device['e'] = e - device['e_name'] = e.__class__.__name__ - cli.log.error("Could not connect to %(color)s%(manufacturer_string)s %(product_string)s{style_reset_all} (%(color)s%(vendor_id)04X:%(product_id)04X:%(index)d{style_reset_all}): %(e_name)s: %(e)s", device) + cli.log.error(f'Could not connect to {_gen_header(device)}: {e.__class__.__name__}: {e}') if cli.config.general.verbose: cli.log.exception(e) del live_devices[device['path']] @@ -209,7 +224,7 @@ def run_forever(self): live_bootloaders[device.address]._qmk_found = True else: name = KNOWN_BOOTLOADERS[(int2hex(device.idVendor), int2hex(device.idProduct))] - cli.log.info('Bootloader Connected: {style_bright}{fg_magenta}%s', name) + cli.log.info(f'Bootloader Connected: {{style_bright}}{{fg_magenta}}{name}') device._qmk_found = True live_bootloaders[device.address] = device @@ -218,7 +233,7 @@ def run_forever(self): live_bootloaders[device]._qmk_found = False else: name = KNOWN_BOOTLOADERS[(int2hex(live_bootloaders[device].idVendor), int2hex(live_bootloaders[device].idProduct))] - cli.log.info('Bootloader Disconnected: {style_bright}{fg_magenta}%s', name) + cli.log.info(f'Bootloader Disconnected: {{style_bright}}{{fg_magenta}}{name}') del live_bootloaders[device] sleep(.1) @@ -285,23 +300,17 @@ def find_devices(self): # Add index numbers device_index = {} for device in devices: - id = ':'.join((int2hex(device['vendor_id']), int2hex(device['product_id']))) + ident = ':'.join((int2hex(device['vendor_id']), int2hex(device['product_id']))) - if id not in device_index: - device_index[id] = 0 + if ident not in device_index: + device_index[ident] = 0 - device_index[id] += 1 - device['index'] = device_index[id] + device_index[ident] += 1 + device['index'] = device_index[ident] return devices -def int2hex(number): - """Returns a string representation of the number as hex. - """ - return "%04X" % number - - def list_devices(device_finder): """Show the user a nicely formatted list of devices. """ @@ -310,9 +319,8 @@ def list_devices(device_finder): if devices: cli.log.info('Available devices:') for dev in devices: - color = LOG_COLOR['colors'][LOG_COLOR['next']] - LOG_COLOR['next'] = (LOG_COLOR['next'] + 1) % len(LOG_COLOR['colors']) - cli.log.info("\t%s%s:%s:%d{style_reset_all}\t%s %s", color, int2hex(dev['vendor_id']), int2hex(dev['product_id']), dev['index'], dev['manufacturer_string'], dev['product_string']) + color = _get_next_color() + cli.log.info(f'\t{color}{int2hex(dev["vendor_id"])}:{int2hex(dev["product_id"])}:{dev["index"]}{{style_reset_all}}\t{dev["manufacturer_string"]} {dev["product_string"]}') if cli.args.bootloaders: bootloaders = device_finder.find_bootloaders() @@ -321,7 +329,8 @@ def list_devices(device_finder): cli.log.info('Available Bootloaders:') for dev in bootloaders: - cli.log.info("\t%s:%s\t%s", int2hex(dev.idVendor), int2hex(dev.idProduct), KNOWN_BOOTLOADERS[(int2hex(dev.idVendor), int2hex(dev.idProduct))]) + color = _get_next_color() + cli.log.info(f'\t{color}{int2hex(dev.idVendor)}:{int2hex(dev.idProduct)}{{style_reset_all}}\t{KNOWN_BOOTLOADERS[(int2hex(dev.idVendor), int2hex(dev.idProduct))]}') @cli.argument('--bootloaders', arg_only=True, default=True, action='store_boolean', help='displaying bootloaders.') @@ -348,17 +357,17 @@ def console(cli): vid, pid, index = device if not index.isdigit(): - cli.log.error('Device index must be a number! Got "%s" instead.', index) + cli.log.error(f'Device index must be a number! Got "{index}" instead.') exit(1) index = int(index) if index < 1: - cli.log.error('Device index must be greater than 0! Got %s', index) + cli.log.error(f'Device index must be greater than 0! Got "{index}".') exit(1) else: - cli.log.error('Invalid format for device, expected ":[:]" but got "%s".', cli.config.console.device) + cli.log.error(f'Invalid format for device, expected ":[:]" but got "{cli.config.console.device}".') cli.print_help() exit(1) diff --git a/qmk_cli/subcommands/env.py b/qmk_cli/subcommands/env.py index 0f3960a..8313159 100644 --- a/qmk_cli/subcommands/env.py +++ b/qmk_cli/subcommands/env.py @@ -10,14 +10,14 @@ @cli.argument('var', arg_only=True, default=None, nargs='?', help='Optional variable to query') @cli.subcommand('Prints environment information.') def env(cli): - home = os.environ.get('QMK_HOME', "") - userspace = os.environ.get('QMK_USERSPACE', "") + home = os.environ.get('QMK_HOME', '') + userspace = os.environ.get('QMK_USERSPACE', '') data = { 'QMK_HOME': home, - 'QMK_FIRMWARE': home if is_qmk_firmware(Path(home)) else "", - 'QMK_USERSPACE': userspace if is_qmk_userspace(Path(userspace)) else "", - 'QMK_DISTRIB_DIR': os.environ.get('QMK_DISTRIB_DIR', ""), - 'QMK_PATH_PREFIX': os.environ.get('QMK_PATH_PREFIX', "") + 'QMK_FIRMWARE': home if is_qmk_firmware(Path(home)) else '', + 'QMK_USERSPACE': userspace if is_qmk_userspace(Path(userspace)) else '', + 'QMK_DISTRIB_DIR': os.environ.get('QMK_DISTRIB_DIR', ''), + 'QMK_PATH_PREFIX': os.environ.get('QMK_PATH_PREFIX', '') } # Now munge the current cli config diff --git a/qmk_cli/subcommands/setup.py b/qmk_cli/subcommands/setup.py index 87d5dee..acdeb98 100644 --- a/qmk_cli/subcommands/setup.py +++ b/qmk_cli/subcommands/setup.py @@ -1,7 +1,6 @@ """Setup qmk_firmware on your computer. """ import os -import shlex import subprocess import sys from pathlib import Path @@ -36,13 +35,13 @@ def git_upstream(destination): for line in p.stdout: print(line, end='') - if p.returncode == 0: - cli.log.info('Added %s as remote upstream.', git_url) - return True - else: - cli.log.error('%s exited %d', ' '.join(git_cmd), p.returncode) + if p.returncode != 0: + cli.log.error(f'git remote exited {p.returncode}') return False + cli.log.info(f'Added {git_url} as remote upstream.') + return True + def git_clone_fork(fork, branch, force=False): if force: @@ -57,16 +56,16 @@ def git_clone_fork(fork, branch, force=False): @cli.argument('-n', '--no', arg_only=True, action='store_true', help='Answer no to all questions') @cli.argument('-y', '--yes', arg_only=True, action='store_true', help='Answer yes to all questions') -@cli.argument('--baseurl', arg_only=True, default=default_base, help='The URL all git operations start from. Default: %s' % default_base) -@cli.argument('-b', '--branch', arg_only=True, default=default_branch, help='The branch to clone. Default: %s' % default_branch) -@cli.argument('-H', '--home', arg_only=True, default=Path(os.environ['QMK_HOME']), type=AbsPath, help='The location for QMK Firmware. Default: %s' % os.environ['QMK_HOME']) -@cli.argument('fork', arg_only=True, default=default_fork, nargs='?', help='The qmk_firmware fork to clone. Default: %s' % default_fork) +@cli.argument('--baseurl', arg_only=True, default=default_base, help=f'The URL all git operations start from. Default: {default_base}') +@cli.argument('-b', '--branch', arg_only=True, default=default_branch, help=f'The branch to clone. Default: {default_branch}') +@cli.argument('-H', '--home', arg_only=True, default=Path(os.environ['QMK_HOME']), type=AbsPath, help=f'The location for QMK Firmware. Default: {os.environ["QMK_HOME"]}') +@cli.argument('fork', arg_only=True, default=default_fork, nargs='?', help=f'The qmk_firmware fork to clone. Default: {default_fork}') @cli.subcommand('Setup your computer for qmk_firmware.') def setup(cli): """Guide the user through setting up their QMK environment. """ - clone_prompt = 'Would you like to clone {fg_cyan}%s{fg_reset} to {fg_cyan}%s{fg_reset}?' % (cli.args.fork, shlex.quote(str(cli.args.home))) - home_prompt = 'Would you like to set {fg_cyan}%s{fg_reset} as your QMK home?' % (shlex.quote(str(cli.args.home)),) + clone_prompt = f'Would you like to clone {{fg_cyan}}{cli.args.fork}{{fg_reset}} to {{fg_cyan}}{cli.args.home}{{fg_reset}}?' + home_prompt = f'Would you like to set {{fg_cyan}}{cli.args.home}{{fg_reset}} as your QMK home?' # Sanity checks if cli.args.yes and cli.args.no: @@ -77,25 +76,25 @@ def setup(cli): # If it exists, ask the user what to do with it # If it doesn't exist, offer to check it out if is_qmk_firmware(cli.args.home): - cli.log.info('Found qmk_firmware at %s.', str(cli.args.home)) - found_prompt = "What do you want to do?" + cli.log.info(f'Found qmk_firmware at "{cli.args.home}".') + found_prompt = 'What do you want to do?' found_options = [ - f"Delete and reclone {cli.args.fork}", - "Delete and clone a different fork", - "Keep it and continue" + f'Delete and reclone {cli.args.fork}', + 'Delete and clone a different fork', + 'Keep it and continue' ] - delete_confirm = "WARNING: This will delete your current qmk_firmware directory. Proceed?" + delete_confirm = 'WARNING: This will delete your current qmk_firmware directory. Proceed?' found_action = choice(found_prompt, options=found_options, default=2) - if found_action == f"Delete and reclone {cli.args.fork}": + if found_action == f'Delete and reclone {cli.args.fork}': if not yesno(delete_confirm, default=False): exit(1) git_clone_fork(cli.args.fork, cli.args.branch, force=True) - elif found_action == "Delete and clone a different fork": - fork_name = question("Enter the name of the fork:", default=cli.args.fork) - branch_name = question("Enter the branch name to clone:", default=cli.args.branch) + elif found_action == 'Delete and clone a different fork': + fork_name = question('Enter the name of the fork:', default=cli.args.fork) + branch_name = question('Enter the branch name to clone:', default=cli.args.branch) if not yesno(delete_confirm, default=False): exit(1) @@ -107,9 +106,9 @@ def setup(cli): path_str = str(cli.args.home) if cli.args.home.name != 'qmk_firmware': - cli.log.warning('Warning: %s does not end in "qmk_firmware". Did you mean to use "--home %s/qmk_firmware"?' % (path_str, path_str)) + cli.log.warning(f'Warning: {path_str} does not end in "qmk_firmware". Did you mean to use "--home {path_str}/qmk_firmware"?') - cli.log.error("Path '%s' exists but is not a qmk_firmware clone!", path_str) + cli.log.error(f'Path "{path_str}" exists but is not a qmk_firmware clone!') exit(1) else: