aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZach White <skullydazed@gmail.com>2021-05-10 12:16:04 -0700
committerZach White <skullydazed@gmail.com>2021-05-10 12:16:04 -0700
commit0e7c66e8917ee470d8a3d3904bd8b55c75c8a0b4 (patch)
treee53a16e0631ac22b68a66bd219d0ff3c107b36ee
parent911b45ce3bcc2cf4c7e12ccf8df7da9621173e32 (diff)
parentbc38c38f8c25dcbe759bc4d9d707a0069b3c6c59 (diff)
downloadqmk_firmware-0e7c66e8917ee470d8a3d3904bd8b55c75c8a0b4.tar.gz
qmk_firmware-0e7c66e8917ee470d8a3d3904bd8b55c75c8a0b4.zip
Merge remote-tracking branch 'origin/master' into develop
Conflicts: bin/qmk lib/python/qmk/cli/__init__.py Merge conflicts fixed by skullydazed.
-rwxr-xr-xbin/qmk46
-rw-r--r--lib/python/qmk/cli/__init__.py149
2 files changed, 124 insertions, 71 deletions
diff --git a/bin/qmk b/bin/qmk
index 4b5fd5bbc..a6e8ce08d 100755
--- a/bin/qmk
+++ b/bin/qmk
@@ -3,7 +3,6 @@
3""" 3"""
4import os 4import os
5import sys 5import sys
6from importlib.util import find_spec
7from pathlib import Path 6from pathlib import Path
8 7
9# Add the QMK python libs to our path 8# Add the QMK python libs to our path
@@ -12,54 +11,9 @@ qmk_dir = script_dir.parent
12python_lib_dir = Path(qmk_dir / 'lib' / 'python').resolve() 11python_lib_dir = Path(qmk_dir / 'lib' / 'python').resolve()
13sys.path.append(str(python_lib_dir)) 12sys.path.append(str(python_lib_dir))
14 13
15
16def _check_modules(requirements):
17 """ Check if the modules in the given requirements.txt are available.
18 """
19 with Path(qmk_dir / requirements).open() as fd:
20 for line in fd.readlines():
21 line = line.strip().replace('<', '=').replace('>', '=')
22
23 if len(line) == 0 or line[0] == '#' or line.startswith('-r'):
24 continue
25
26 if '#' in line:
27 line = line.split('#')[0]
28
29 module = dict()
30 module['name'] = line.split('=')[0] if '=' in line else line
31 module['import'] = module['name'].replace('-', '_')
32
33 # Not every module is importable by its own name.
34 if module['name'] == "pep8-naming":
35 module['import'] = "pep8ext_naming"
36 elif module['name'] == 'pyusb':
37 module['import'] = 'usb.core'
38
39 if not find_spec(module['import']):
40 print('Could not find module %s!' % module['name'])
41 print('Please run `python3 -m pip install -r %s` to install required python dependencies.' % (qmk_dir / requirements,))
42 if developer:
43 print('You can also turn off developer mode: qmk config user.developer=None')
44 print()
45 exit(255)
46
47
48developer = False
49# Make sure our modules have been setup
50_check_modules('requirements.txt')
51
52# Setup the CLI 14# Setup the CLI
53import milc # noqa 15import milc # noqa
54 16
55# For developers additional modules are needed
56if milc.cli.config.user.developer:
57 # Do not run the check for 'config',
58 # so users can turn off developer mode
59 if len(sys.argv) == 1 or (len(sys.argv) > 1 and 'config' != sys.argv[1]):
60 developer = True
61 _check_modules('requirements-dev.txt')
62
63milc.EMOJI_LOGLEVELS['INFO'] = '{fg_blue}Ψ{style_reset_all}' 17milc.EMOJI_LOGLEVELS['INFO'] = '{fg_blue}Ψ{style_reset_all}'
64 18
65 19
diff --git a/lib/python/qmk/cli/__init__.py b/lib/python/qmk/cli/__init__.py
index e7a5d5cd8..1fe065720 100644
--- a/lib/python/qmk/cli/__init__.py
+++ b/lib/python/qmk/cli/__init__.py
@@ -2,34 +2,81 @@
2 2
3We list each subcommand here explicitly because all the reliable ways of searching for modules are slow and delay startup. 3We list each subcommand here explicitly because all the reliable ways of searching for modules are slow and delay startup.
4""" 4"""
5import os
6import shlex
5import sys 7import sys
8from importlib.util import find_spec
9from pathlib import Path
10from subprocess import run
6 11
7from milc import cli, __VERSION__ 12from milc import cli, __VERSION__
13from milc.questions import yesno
8 14
9from . import c2json
10from . import cformat
11from . import chibios
12from . import clean
13from . import compile
14from . import config
15from . import console
16from . import docs
17from . import doctor
18from . import fileformat
19from . import flash
20from . import format
21from . import generate
22from . import hello
23from . import info
24from . import json2c
25from . import lint
26from . import list
27from . import kle2json
28from . import multibuild
29from . import new
30from . import pyformat
31from . import pytest
32 15
16def _run_cmd(*command):
17 """Run a command in a subshell.
18 """
19 if 'windows' in cli.platform.lower():
20 safecmd = map(shlex.quote, command)
21 safecmd = ' '.join(safecmd)
22 command = [os.environ['SHELL'], '-c', safecmd]
23
24 return run(command)
25
26
27def _find_broken_requirements(requirements):
28 """ Check if the modules in the given requirements.txt are available.
29
30 Args:
31
32 requirements
33 The path to a requirements.txt file
34
35 Returns a list of modules that couldn't be imported
36 """
37 with Path(requirements).open() as fd:
38 broken_modules = []
39
40 for line in fd.readlines():
41 line = line.strip().replace('<', '=').replace('>', '=')
42
43 if len(line) == 0 or line[0] == '#' or line.startswith('-r'):
44 continue
45
46 if '#' in line:
47 line = line.split('#')[0]
48
49 module_name = line.split('=')[0] if '=' in line else line
50 module_import = module_name.replace('-', '_')
51
52 # Not every module is importable by its own name.
53 if module_name == "pep8-naming":
54 module_import = "pep8ext_naming"
55 elif module_name == 'pyusb':
56 module_import = 'usb.core'
57
58 if not find_spec(module_import):
59 broken_modules.append(module_name)
60
61 return broken_modules
62
63
64def _broken_module_imports(requirements):
65 """Make sure we can import all the python modules.
66 """
67 broken_modules = _find_broken_requirements(requirements)
68
69 for module in broken_modules:
70 print('Could not find module %s!' % module)
71
72 if broken_modules:
73 return True
74
75 return False
76
77
78# Make sure our python is new enough
79#
33# Supported version information 80# Supported version information
34# 81#
35# Based on the OSes we support these are the minimum python version available by default. 82# Based on the OSes we support these are the minimum python version available by default.
@@ -55,9 +102,61 @@ if sys.version_info[0] != 3 or sys.version_info[1] < 7:
55milc_version = __VERSION__.split('.') 102milc_version = __VERSION__.split('.')
56 103
57if int(milc_version[0]) < 2 and int(milc_version[1]) < 3: 104if int(milc_version[0]) < 2 and int(milc_version[1]) < 3:
58 from pathlib import Path
59
60 requirements = Path('requirements.txt').resolve() 105 requirements = Path('requirements.txt').resolve()
61 106
62 print(f'Your MILC library is too old! Please upgrade: python3 -m pip install -U -r {str(requirements)}') 107 print(f'Your MILC library is too old! Please upgrade: python3 -m pip install -U -r {str(requirements)}')
63 exit(127) 108 exit(127)
109
110# Check to make sure we have all our dependencies
111msg_install = 'Please run `python3 -m pip install -r %s` to install required python dependencies.'
112
113if _broken_module_imports('requirements.txt'):
114 if yesno('Would you like to install the required Python modules?'):
115 _run_cmd(sys.executable, '-m', 'pip', 'install', '-r', 'requirements.txt')
116 else:
117 print()
118 print(msg_install % (str(Path('requirements.txt').resolve()),))
119 print()
120 exit(1)
121
122if cli.config.user.developer:
123 args = sys.argv[1:]
124 while args and args[0][0] == '-':
125 del args[0]
126 if not args or args[0] != 'config':
127 if _broken_module_imports('requirements-dev.txt'):
128 if yesno('Would you like to install the required developer Python modules?'):
129 _run_cmd(sys.executable, '-m', 'pip', 'install', '-r', 'requirements-dev.txt')
130 elif yesno('Would you like to disable developer mode?'):
131 _run_cmd(sys.argv[0], 'config', 'user.developer=None')
132 else:
133 print()
134 print(msg_install % (str(Path('requirements-dev.txt').resolve()),))
135 print('You can also turn off developer mode: qmk config user.developer=None')
136 print()
137 exit(1)
138
139# Import our subcommands
140from . import c2json # noqa
141from . import cformat # noqa
142from . import chibios # noqa
143from . import clean # noqa
144from . import compile # noqa
145from . import config # noqa
146from . import console # noqa
147from . import docs # noqa
148from . import doctor # noqa
149from . import fileformat # noqa
150from . import flash # noqa
151from . import format # noqa
152from . import generate # noqa
153from . import hello # noqa
154from . import info # noqa
155from . import json2c # noqa
156from . import lint # noqa
157from . import list # noqa
158from . import kle2json # noqa
159from . import multibuild # noqa
160from . import new # noqa
161from . import pyformat # noqa
162from . import pytest # noqa