mirror of
https://github.com/openstenoproject/qmk
synced 2024-11-10 02:30:07 +00:00
Move the module checking and updating to lib/python (#12416)
* move the module checking and updating to lib/python * make flake8 happy * Update lib/python/qmk/cli/__init__.py Co-authored-by: Erovia <Erovia@users.noreply.github.com> * prompt the user to disable developer mode * pyformat * flake8 Co-authored-by: Erovia <Erovia@users.noreply.github.com>
This commit is contained in:
parent
a3e7f3e7c5
commit
bc38c38f8c
2 changed files with 121 additions and 68 deletions
44
bin/qmk
44
bin/qmk
|
@ -3,7 +3,6 @@
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from importlib.util import find_spec
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
# Add the QMK python libs to our path
|
# Add the QMK python libs to our path
|
||||||
|
@ -12,52 +11,9 @@ qmk_dir = script_dir.parent
|
||||||
python_lib_dir = Path(qmk_dir / 'lib' / 'python').resolve()
|
python_lib_dir = Path(qmk_dir / 'lib' / 'python').resolve()
|
||||||
sys.path.append(str(python_lib_dir))
|
sys.path.append(str(python_lib_dir))
|
||||||
|
|
||||||
|
|
||||||
def _check_modules(requirements):
|
|
||||||
""" Check if the modules in the given requirements.txt are available.
|
|
||||||
"""
|
|
||||||
with Path(qmk_dir / requirements).open() as fd:
|
|
||||||
for line in fd.readlines():
|
|
||||||
line = line.strip().replace('<', '=').replace('>', '=')
|
|
||||||
|
|
||||||
if len(line) == 0 or line[0] == '#' or line.startswith('-r'):
|
|
||||||
continue
|
|
||||||
|
|
||||||
if '#' in line:
|
|
||||||
line = line.split('#')[0]
|
|
||||||
|
|
||||||
module = dict()
|
|
||||||
module['name'] = line.split('=')[0] if '=' in line else line
|
|
||||||
module['import'] = module['name'].replace('-', '_')
|
|
||||||
|
|
||||||
# Not every module is importable by its own name.
|
|
||||||
if module['name'] == "pep8-naming":
|
|
||||||
module['import'] = "pep8ext_naming"
|
|
||||||
|
|
||||||
if not find_spec(module['import']):
|
|
||||||
print('Could not find module %s!' % module['name'])
|
|
||||||
print('Please run `python3 -m pip install -r %s` to install required python dependencies.' % (qmk_dir / requirements,))
|
|
||||||
if developer:
|
|
||||||
print('You can also turn off developer mode: qmk config user.developer=None')
|
|
||||||
print()
|
|
||||||
exit(255)
|
|
||||||
|
|
||||||
|
|
||||||
developer = False
|
|
||||||
# Make sure our modules have been setup
|
|
||||||
_check_modules('requirements.txt')
|
|
||||||
|
|
||||||
# Setup the CLI
|
# Setup the CLI
|
||||||
import milc # noqa
|
import milc # noqa
|
||||||
|
|
||||||
# For developers additional modules are needed
|
|
||||||
if milc.cli.config.user.developer:
|
|
||||||
# Do not run the check for 'config',
|
|
||||||
# so users can turn off developer mode
|
|
||||||
if len(sys.argv) == 1 or (len(sys.argv) > 1 and 'config' != sys.argv[1]):
|
|
||||||
developer = True
|
|
||||||
_check_modules('requirements-dev.txt')
|
|
||||||
|
|
||||||
milc.EMOJI_LOGLEVELS['INFO'] = '{fg_blue}Ψ{style_reset_all}'
|
milc.EMOJI_LOGLEVELS['INFO'] = '{fg_blue}Ψ{style_reset_all}'
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,33 +2,79 @@
|
||||||
|
|
||||||
We list each subcommand here explicitly because all the reliable ways of searching for modules are slow and delay startup.
|
We list each subcommand here explicitly because all the reliable ways of searching for modules are slow and delay startup.
|
||||||
"""
|
"""
|
||||||
|
import os
|
||||||
|
import shlex
|
||||||
import sys
|
import sys
|
||||||
|
from importlib.util import find_spec
|
||||||
|
from pathlib import Path
|
||||||
|
from subprocess import run
|
||||||
|
|
||||||
from milc import cli, __VERSION__
|
from milc import cli, __VERSION__
|
||||||
|
from milc.questions import yesno
|
||||||
|
|
||||||
from . import c2json
|
|
||||||
from . import cformat
|
|
||||||
from . import chibios
|
|
||||||
from . import clean
|
|
||||||
from . import compile
|
|
||||||
from . import config
|
|
||||||
from . import docs
|
|
||||||
from . import doctor
|
|
||||||
from . import fileformat
|
|
||||||
from . import flash
|
|
||||||
from . import format
|
|
||||||
from . import generate
|
|
||||||
from . import hello
|
|
||||||
from . import info
|
|
||||||
from . import json2c
|
|
||||||
from . import lint
|
|
||||||
from . import list
|
|
||||||
from . import kle2json
|
|
||||||
from . import multibuild
|
|
||||||
from . import new
|
|
||||||
from . import pyformat
|
|
||||||
from . import pytest
|
|
||||||
|
|
||||||
|
def _run_cmd(*command):
|
||||||
|
"""Run a command in a subshell.
|
||||||
|
"""
|
||||||
|
if 'windows' in cli.platform.lower():
|
||||||
|
safecmd = map(shlex.quote, command)
|
||||||
|
safecmd = ' '.join(safecmd)
|
||||||
|
command = [os.environ['SHELL'], '-c', safecmd]
|
||||||
|
|
||||||
|
return run(command)
|
||||||
|
|
||||||
|
|
||||||
|
def _find_broken_requirements(requirements):
|
||||||
|
""" Check if the modules in the given requirements.txt are available.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
|
||||||
|
requirements
|
||||||
|
The path to a requirements.txt file
|
||||||
|
|
||||||
|
Returns a list of modules that couldn't be imported
|
||||||
|
"""
|
||||||
|
with Path(requirements).open() as fd:
|
||||||
|
broken_modules = []
|
||||||
|
|
||||||
|
for line in fd.readlines():
|
||||||
|
line = line.strip().replace('<', '=').replace('>', '=')
|
||||||
|
|
||||||
|
if len(line) == 0 or line[0] == '#' or line.startswith('-r'):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if '#' in line:
|
||||||
|
line = line.split('#')[0]
|
||||||
|
|
||||||
|
module_name = line.split('=')[0] if '=' in line else line
|
||||||
|
module_import = module_name.replace('-', '_')
|
||||||
|
|
||||||
|
# Not every module is importable by its own name.
|
||||||
|
if module_name == "pep8-naming":
|
||||||
|
module_import = "pep8ext_naming"
|
||||||
|
|
||||||
|
if not find_spec(module_import):
|
||||||
|
broken_modules.append(module_name)
|
||||||
|
|
||||||
|
return broken_modules
|
||||||
|
|
||||||
|
|
||||||
|
def _broken_module_imports(requirements):
|
||||||
|
"""Make sure we can import all the python modules.
|
||||||
|
"""
|
||||||
|
broken_modules = _find_broken_requirements(requirements)
|
||||||
|
|
||||||
|
for module in broken_modules:
|
||||||
|
print('Could not find module %s!' % module)
|
||||||
|
|
||||||
|
if broken_modules:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
# Make sure our python is new enough
|
||||||
|
#
|
||||||
# Supported version information
|
# Supported version information
|
||||||
#
|
#
|
||||||
# Based on the OSes we support these are the minimum python version available by default.
|
# Based on the OSes we support these are the minimum python version available by default.
|
||||||
|
@ -54,9 +100,60 @@ if sys.version_info[0] != 3 or sys.version_info[1] < 7:
|
||||||
milc_version = __VERSION__.split('.')
|
milc_version = __VERSION__.split('.')
|
||||||
|
|
||||||
if int(milc_version[0]) < 2 and int(milc_version[1]) < 3:
|
if int(milc_version[0]) < 2 and int(milc_version[1]) < 3:
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
requirements = Path('requirements.txt').resolve()
|
requirements = Path('requirements.txt').resolve()
|
||||||
|
|
||||||
print(f'Your MILC library is too old! Please upgrade: python3 -m pip install -U -r {str(requirements)}')
|
print(f'Your MILC library is too old! Please upgrade: python3 -m pip install -U -r {str(requirements)}')
|
||||||
exit(127)
|
exit(127)
|
||||||
|
|
||||||
|
# Check to make sure we have all our dependencies
|
||||||
|
msg_install = 'Please run `python3 -m pip install -r %s` to install required python dependencies.'
|
||||||
|
|
||||||
|
if _broken_module_imports('requirements.txt'):
|
||||||
|
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 % (str(Path('requirements.txt').resolve()),))
|
||||||
|
print()
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
if cli.config.user.developer:
|
||||||
|
args = sys.argv[1:]
|
||||||
|
while args and args[0][0] == '-':
|
||||||
|
del args[0]
|
||||||
|
if not args or args[0] != 'config':
|
||||||
|
if _broken_module_imports('requirements-dev.txt'):
|
||||||
|
if yesno('Would you like to install the required developer Python modules?'):
|
||||||
|
_run_cmd(sys.executable, '-m', 'pip', 'install', '-r', 'requirements-dev.txt')
|
||||||
|
elif yesno('Would you like to disable developer mode?'):
|
||||||
|
_run_cmd(sys.argv[0], 'config', 'user.developer=None')
|
||||||
|
else:
|
||||||
|
print()
|
||||||
|
print(msg_install % (str(Path('requirements-dev.txt').resolve()),))
|
||||||
|
print('You can also turn off developer mode: qmk config user.developer=None')
|
||||||
|
print()
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
# Import our subcommands
|
||||||
|
from . import c2json # noqa
|
||||||
|
from . import cformat # noqa
|
||||||
|
from . import chibios # noqa
|
||||||
|
from . import clean # noqa
|
||||||
|
from . import compile # noqa
|
||||||
|
from . import config # noqa
|
||||||
|
from . import docs # noqa
|
||||||
|
from . import doctor # noqa
|
||||||
|
from . import fileformat # noqa
|
||||||
|
from . import flash # noqa
|
||||||
|
from . import format # noqa
|
||||||
|
from . import generate # noqa
|
||||||
|
from . import hello # noqa
|
||||||
|
from . import info # noqa
|
||||||
|
from . import json2c # noqa
|
||||||
|
from . import lint # noqa
|
||||||
|
from . import list # noqa
|
||||||
|
from . import kle2json # noqa
|
||||||
|
from . import multibuild # noqa
|
||||||
|
from . import new # noqa
|
||||||
|
from . import pyformat # noqa
|
||||||
|
from . import pytest # noqa
|
||||||
|
|
Loading…
Reference in a new issue