From fe42ab3534e7156156c75c8e05dd49ce2e69ef1e Mon Sep 17 00:00:00 2001 From: Zach White Date: Fri, 26 Mar 2021 10:28:36 -0700 Subject: [PATCH] General improvements * refactor to make the code clearer in some places * don't call bin/qmk anymore * ask the user if they want to install python modules when they're missing --- qmk_cli/git.py | 2 +- qmk_cli/helpers.py | 20 +++++++++- qmk_cli/script_qmk.py | 71 ++++++++++++++++++++------------- qmk_cli/subcommands/__init__.py | 4 +- qmk_cli/subcommands/setup.py | 17 ++++---- setup.py | 6 +-- 6 files changed, 76 insertions(+), 44 deletions(-) diff --git a/qmk_cli/git.py b/qmk_cli/git.py index c222ef9..984c500 100644 --- a/qmk_cli/git.py +++ b/qmk_cli/git.py @@ -16,7 +16,7 @@ def git_clone(url, destination, branch): '--recurse-submodules', '--branch=' + branch, url, - destination, + str(destination), ] cli.log.debug('Git clone command: %s', git_clone) diff --git a/qmk_cli/helpers.py b/qmk_cli/helpers.py index 3b53c5a..a16642c 100644 --- a/qmk_cli/helpers.py +++ b/qmk_cli/helpers.py @@ -8,6 +8,25 @@ from pathlib import Path from milc import cli +def broken_module_imports(): + """Make sure we can import all the python modules. + """ + broken_modules = find_broken_requirements('requirements.txt') + broken_dev_modules = find_broken_requirements('requirements-dev.txt') if cli.config.user.developer else [] + to_return = [False, False] + + if broken_modules: + to_return[0] = True + + if broken_dev_modules: + to_return[1] = True + + for module in broken_modules + broken_dev_modules: + print('Could not find module %s!' % module) + + return to_return + + def find_broken_requirements(requirements): """ Check if the modules in the given requirements.txt are available. @@ -64,7 +83,6 @@ def find_qmk_firmware(): return Path.home() / 'qmk_firmware' - def in_qmk_firmware(): """Returns the path to the qmk_firmware we are currently in, or None if we are not inside qmk_firmware. """ diff --git a/qmk_cli/script_qmk.py b/qmk_cli/script_qmk.py index e60fdc0..2166986 100644 --- a/qmk_cli/script_qmk.py +++ b/qmk_cli/script_qmk.py @@ -4,6 +4,7 @@ This program can be run from anywhere, with or without a qmk_firmware repository. If a qmk_firmware repository can be located we will use that to augment our available subcommands. """ import os +import shlex import subprocess import sys from platform import platform @@ -11,8 +12,9 @@ from traceback import print_exc import milc import milc.subcommand.config # noqa +from milc.questions import yesno -from .helpers import find_broken_requirements, find_qmk_firmware, in_qmk_firmware +from .helpers import broken_module_imports, find_qmk_firmware milc.EMOJI_LOGLEVELS['INFO'] = '{fg_blue}Ψ{style_reset_all}' @@ -24,14 +26,25 @@ def qmk_main(cli): cli.print_help() +def run_cmd(*command): + """Run a command in a subshell. + """ + if 'windows' in milc.cli.platform.lower(): + safecmd = map(shlex.quote, command) + safecmd = ' '.join(safecmd) + command = [os.environ['SHELL'], '-c', safecmd] + + return subprocess.run(command) + + # Python setuptools entrypoint def main(): """Setup the environment before dispatching to the entrypoint. """ # Warn if they use an outdated python version - if sys.version_info < (3, 6): + if sys.version_info < (3, 7): print('Warning: Your Python version is out of date! Some subcommands may not work!') - print('Please upgrade to Python 3.6 or later.') + print('Please upgrade to Python 3.7 or later.') if 'windows' in platform().lower(): msystem = os.environ.get('MSYSTEM', '') @@ -57,39 +70,41 @@ def main(): os.chdir(str(qmk_firmware)) # Check to make sure we have all the requirements - broken_modules = find_broken_requirements('requirements.txt') - broken_dev_modules = find_broken_requirements('requirements-dev.txt') if milc.cli.config.user.developer else [] + broken_modules, broken_dev_modules = broken_module_imports() + msg_install = 'Please run `python3 -m pip install -r %s` to install required python dependencies.' - if broken_modules or broken_dev_modules: - for module in broken_modules + broken_dev_modules: - print('Could not find module %s!' % module) - - msg_install = 'Please run `python3 -m pip install -r %s` to install required python dependencies.' - if broken_modules: + if broken_modules: + if yesno('Would you like to install the required Python modules?'): + run_cmd(sys.executable, '-m', 'pip', 'install', '-r', 'requirements.txt') + else: print() - print(msg_install % (qmk_firmware / 'requirements.txt',)) - - if broken_dev_modules: + print(msg_install % (os.environ['QMK_HOME'] + '/requirements.txt',)) print() - print(msg_install % (qmk_firmware / 'requirements-dev.txt',)) + exit(1) + + if broken_dev_modules: + if yesno('Would you like to install the required developer Python modules?'): + run_cmd(sys.executable, '-m', 'pip', 'install', '-r', 'requirements.txt') + else: + print() + print(msg_install % (os.environ['QMK_HOME'] + '/requirements-dev.txt',)) print('You can also turn off developer mode: qmk config user.developer=None') + print() + exit(1) - print() + # Environment looks good, include the qmk_firmware subcommands + sys.path.append(str(qmk_firmware / 'lib/python')) - else: - # Environment looks good, include the qmk_firmware subcommands - sys.path.append(str(qmk_firmware / 'lib/python')) + try: + import qmk.cli # noqa - try: - import qmk.cli + 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)) - 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('Error: %s: %s', (e.__class__.__name__, e)) - print_exc() - sys.exit(1) + print('Error: %s: %s', (e.__class__.__name__, e)) + print_exc() + sys.exit(1) # Call the entrypoint return_code = milc.cli() diff --git a/qmk_cli/subcommands/__init__.py b/qmk_cli/subcommands/__init__.py index 9a1b610..3b50b61 100644 --- a/qmk_cli/subcommands/__init__.py +++ b/qmk_cli/subcommands/__init__.py @@ -2,5 +2,5 @@ We list each subcommand here explicitly because all the reliable ways of searching for modules are slow and delay startup. """ -from . import clone -from . import setup +from . import clone # noqa +from . import setup # noqa diff --git a/qmk_cli/subcommands/setup.py b/qmk_cli/subcommands/setup.py index b342804..34ce7bf 100644 --- a/qmk_cli/subcommands/setup.py +++ b/qmk_cli/subcommands/setup.py @@ -74,18 +74,17 @@ def setup(cli): exit(1) # Offer to set `user.qmk_home` for them. - if cli.args.home != Path(os.environ['QMK_HOME']) and yesno(home_prompt): + if str(cli.args.home) != os.environ['QMK_HOME'] and yesno(home_prompt): cli.config['user']['qmk_home'] = str(cli.args.home.absolute()) cli.write_config_option('user', 'qmk_home') - # Run `qmk_firmware/bin/qmk doctor` to check the rest of the environment out - qmk_bin = cli.args.home / 'bin/qmk' - doctor_cmd = [sys.executable, qmk_bin.as_posix(), 'doctor'] - - if cli.args.yes: - doctor_cmd.append('--yes') + # Run `qmk doctor` to check the rest of the environment out + doctor_command = [sys.executable, sys.argv[0], 'doctor'] if cli.args.no: - doctor_cmd.append('--no') + doctor_command.append('--no') - subprocess.run(doctor_cmd) + if cli.args.yes: + doctor_command.append('--yes') + + cli.run(doctor_command, capture_output=False) diff --git a/setup.py b/setup.py index 3835554..ab3235e 100644 --- a/setup.py +++ b/setup.py @@ -7,12 +7,12 @@ metadata = setup_cfg['metadata'] if __name__ == "__main__": with open('README.md', encoding='utf-8') as readme_file: - long_description=readme_file.read() + long_description = readme_file.read() setup( name=metadata['dist-name'], description='A program to help users work with QMK Firmware.', entry_points={ - 'console_scripts': ['%s = %s' % l for l in setup_cfg['entry_points'].items()], + 'console_scripts': ['%s = %s' % i for i in setup_cfg['entry_points'].items()], }, license='MIT License', url=metadata['home-page'], @@ -24,7 +24,7 @@ if __name__ == "__main__": long_description=long_description, long_description_content_type="text/markdown", packages=find_packages(), - py_modules = ['milc'], + py_modules=['milc'], classifiers=[ 'Development Status :: 3 - Alpha', 'Environment :: Console',