diff options
author | Zach White <skullydazed@gmail.com> | 2021-05-10 12:16:04 -0700 |
---|---|---|
committer | Zach White <skullydazed@gmail.com> | 2021-05-10 12:16:04 -0700 |
commit | 0e7c66e8917ee470d8a3d3904bd8b55c75c8a0b4 (patch) | |
tree | e53a16e0631ac22b68a66bd219d0ff3c107b36ee | |
parent | 911b45ce3bcc2cf4c7e12ccf8df7da9621173e32 (diff) | |
parent | bc38c38f8c25dcbe759bc4d9d707a0069b3c6c59 (diff) | |
download | qmk_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-x | bin/qmk | 46 | ||||
-rw-r--r-- | lib/python/qmk/cli/__init__.py | 149 |
2 files changed, 124 insertions, 71 deletions
@@ -3,7 +3,6 @@ | |||
3 | """ | 3 | """ |
4 | import os | 4 | import os |
5 | import sys | 5 | import sys |
6 | from importlib.util import find_spec | ||
7 | from pathlib import Path | 6 | from 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 | |||
12 | python_lib_dir = Path(qmk_dir / 'lib' / 'python').resolve() | 11 | python_lib_dir = Path(qmk_dir / 'lib' / 'python').resolve() |
13 | sys.path.append(str(python_lib_dir)) | 12 | sys.path.append(str(python_lib_dir)) |
14 | 13 | ||
15 | |||
16 | def _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 | |||
48 | developer = False | ||
49 | # Make sure our modules have been setup | ||
50 | _check_modules('requirements.txt') | ||
51 | |||
52 | # Setup the CLI | 14 | # Setup the CLI |
53 | import milc # noqa | 15 | import milc # noqa |
54 | 16 | ||
55 | # For developers additional modules are needed | ||
56 | if 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 | |||
63 | milc.EMOJI_LOGLEVELS['INFO'] = '{fg_blue}Ψ{style_reset_all}' | 17 | milc.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 | ||
3 | We list each subcommand here explicitly because all the reliable ways of searching for modules are slow and delay startup. | 3 | We list each subcommand here explicitly because all the reliable ways of searching for modules are slow and delay startup. |
4 | """ | 4 | """ |
5 | import os | ||
6 | import shlex | ||
5 | import sys | 7 | import sys |
8 | from importlib.util import find_spec | ||
9 | from pathlib import Path | ||
10 | from subprocess import run | ||
6 | 11 | ||
7 | from milc import cli, __VERSION__ | 12 | from milc import cli, __VERSION__ |
13 | from milc.questions import yesno | ||
8 | 14 | ||
9 | from . import c2json | ||
10 | from . import cformat | ||
11 | from . import chibios | ||
12 | from . import clean | ||
13 | from . import compile | ||
14 | from . import config | ||
15 | from . import console | ||
16 | from . import docs | ||
17 | from . import doctor | ||
18 | from . import fileformat | ||
19 | from . import flash | ||
20 | from . import format | ||
21 | from . import generate | ||
22 | from . import hello | ||
23 | from . import info | ||
24 | from . import json2c | ||
25 | from . import lint | ||
26 | from . import list | ||
27 | from . import kle2json | ||
28 | from . import multibuild | ||
29 | from . import new | ||
30 | from . import pyformat | ||
31 | from . import pytest | ||
32 | 15 | ||
16 | def _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 | |||
27 | def _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 | |||
64 | def _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: | |||
55 | milc_version = __VERSION__.split('.') | 102 | milc_version = __VERSION__.split('.') |
56 | 103 | ||
57 | if int(milc_version[0]) < 2 and int(milc_version[1]) < 3: | 104 | if 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 | ||
111 | msg_install = 'Please run `python3 -m pip install -r %s` to install required python dependencies.' | ||
112 | |||
113 | if _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 | |||
122 | if 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 | ||
140 | from . import c2json # noqa | ||
141 | from . import cformat # noqa | ||
142 | from . import chibios # noqa | ||
143 | from . import clean # noqa | ||
144 | from . import compile # noqa | ||
145 | from . import config # noqa | ||
146 | from . import console # noqa | ||
147 | from . import docs # noqa | ||
148 | from . import doctor # noqa | ||
149 | from . import fileformat # noqa | ||
150 | from . import flash # noqa | ||
151 | from . import format # noqa | ||
152 | from . import generate # noqa | ||
153 | from . import hello # noqa | ||
154 | from . import info # noqa | ||
155 | from . import json2c # noqa | ||
156 | from . import lint # noqa | ||
157 | from . import list # noqa | ||
158 | from . import kle2json # noqa | ||
159 | from . import multibuild # noqa | ||
160 | from . import new # noqa | ||
161 | from . import pyformat # noqa | ||
162 | from . import pytest # noqa | ||