summaryrefslogtreecommitdiff
path: root/lib/python/qmk/cli/doctor/check.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/python/qmk/cli/doctor/check.py')
-rw-r--r--lib/python/qmk/cli/doctor/check.py74
1 files changed, 60 insertions, 14 deletions
diff --git a/lib/python/qmk/cli/doctor/check.py b/lib/python/qmk/cli/doctor/check.py
index 51b0f0c80a..8a13cb0832 100644
--- a/lib/python/qmk/cli/doctor/check.py
+++ b/lib/python/qmk/cli/doctor/check.py
@@ -1,7 +1,6 @@
1"""Check for specific programs. 1"""Check for specific programs.
2""" 2"""
3from enum import Enum 3from enum import Enum
4import re
5import shutil 4import shutil
6from subprocess import DEVNULL, TimeoutExpired 5from subprocess import DEVNULL, TimeoutExpired
7from tempfile import TemporaryDirectory 6from tempfile import TemporaryDirectory
@@ -9,6 +8,7 @@ from pathlib import Path
9 8
10from milc import cli 9from milc import cli
11from qmk import submodules 10from qmk import submodules
11from qmk.commands import find_make
12 12
13 13
14class CheckStatus(Enum): 14class CheckStatus(Enum):
@@ -17,7 +17,13 @@ class CheckStatus(Enum):
17 ERROR = 3 17 ERROR = 3
18 18
19 19
20WHICH_MAKE = Path(find_make()).name
21
20ESSENTIAL_BINARIES = { 22ESSENTIAL_BINARIES = {
23 WHICH_MAKE: {},
24 'git': {},
25 'dos2unix': {},
26 'diff': {},
21 'dfu-programmer': {}, 27 'dfu-programmer': {},
22 'avrdude': {}, 28 'avrdude': {},
23 'dfu-util': {}, 29 'dfu-util': {},
@@ -30,14 +36,39 @@ ESSENTIAL_BINARIES = {
30} 36}
31 37
32 38
33def _parse_gcc_version(version): 39def _check_make_version():
34 m = re.match(r"(\d+)(?:\.(\d+))?(?:\.(\d+))?", version) 40 last_line = ESSENTIAL_BINARIES[WHICH_MAKE]['output'].split('\n')[0]
41 version_number = last_line.split()[2]
42 cli.log.info('Found %s version %s', WHICH_MAKE, version_number)
35 43
36 return { 44 return CheckStatus.OK
37 'major': int(m.group(1)), 45
38 'minor': int(m.group(2)) if m.group(2) else 0, 46
39 'patch': int(m.group(3)) if m.group(3) else 0, 47def _check_git_version():
40 } 48 last_line = ESSENTIAL_BINARIES['git']['output'].split('\n')[0]
49 version_number = last_line.split()[2]
50 cli.log.info('Found git version %s', version_number)
51
52 return CheckStatus.OK
53
54
55def _check_dos2unix_version():
56 last_line = ESSENTIAL_BINARIES['dos2unix']['output'].split('\n')[0]
57 version_number = last_line.split()[1]
58 cli.log.info('Found dos2unix version %s', version_number)
59
60 return CheckStatus.OK
61
62
63def _check_diff_version():
64 last_line = ESSENTIAL_BINARIES['diff']['output'].split('\n')[0]
65 if 'Apple diff' in last_line:
66 version_number = last_line
67 else:
68 version_number = last_line.split()[3]
69 cli.log.info('Found diff version %s', version_number)
70
71 return CheckStatus.OK
41 72
42 73
43def _check_arm_gcc_version(): 74def _check_arm_gcc_version():
@@ -148,16 +179,24 @@ def check_binaries():
148 """Iterates through ESSENTIAL_BINARIES and tests them. 179 """Iterates through ESSENTIAL_BINARIES and tests them.
149 """ 180 """
150 ok = CheckStatus.OK 181 ok = CheckStatus.OK
182 missing_from_path = []
151 183
152 for binary in sorted(ESSENTIAL_BINARIES): 184 for binary in sorted(ESSENTIAL_BINARIES):
153 try: 185 try:
154 if not is_executable(binary): 186 if not is_in_path(binary):
187 ok = CheckStatus.ERROR
188 missing_from_path.append(binary)
189 elif not is_executable(binary):
155 ok = CheckStatus.ERROR 190 ok = CheckStatus.ERROR
156 except TimeoutExpired: 191 except TimeoutExpired:
157 cli.log.debug('Timeout checking %s', binary) 192 cli.log.debug('Timeout checking %s', binary)
158 if ok != CheckStatus.ERROR: 193 if ok != CheckStatus.ERROR:
159 ok = CheckStatus.WARNING 194 ok = CheckStatus.WARNING
160 195
196 if missing_from_path:
197 location_noun = 'its location' if len(missing_from_path) == 1 else 'their locations'
198 cli.log.error('{fg_red}' + ', '.join(missing_from_path) + f' may need to be installed, or {location_noun} added to your path.')
199
161 return ok 200 return ok
162 201
163 202
@@ -165,6 +204,10 @@ def check_binary_versions():
165 """Check the versions of ESSENTIAL_BINARIES 204 """Check the versions of ESSENTIAL_BINARIES
166 """ 205 """
167 checks = { 206 checks = {
207 WHICH_MAKE: _check_make_version,
208 'git': _check_git_version,
209 'dos2unix': _check_dos2unix_version,
210 'diff': _check_diff_version,
168 'arm-none-eabi-gcc': _check_arm_gcc_version, 211 'arm-none-eabi-gcc': _check_arm_gcc_version,
169 'avr-gcc': _check_avr_gcc_version, 212 'avr-gcc': _check_avr_gcc_version,
170 'avrdude': _check_avrdude_version, 213 'avrdude': _check_avrdude_version,
@@ -196,15 +239,18 @@ def check_submodules():
196 return CheckStatus.OK 239 return CheckStatus.OK
197 240
198 241
199def is_executable(command): 242def is_in_path(command):
200 """Returns True if command exists and can be executed. 243 """Returns True if command is found in the path.
201 """ 244 """
202 # Make sure the command is in the path. 245 if shutil.which(command) is None:
203 res = shutil.which(command)
204 if res is None:
205 cli.log.error("{fg_red}Can't find %s in your path.", command) 246 cli.log.error("{fg_red}Can't find %s in your path.", command)
206 return False 247 return False
248 return True
249
207 250
251def is_executable(command):
252 """Returns True if command can be executed.
253 """
208 # Make sure the command can be executed 254 # Make sure the command can be executed
209 version_arg = ESSENTIAL_BINARIES[command].get('version_arg', '--version') 255 version_arg = ESSENTIAL_BINARIES[command].get('version_arg', '--version')
210 check = cli.run([command, version_arg], combined_output=True, stdin=DEVNULL, timeout=5) 256 check = cli.run([command, version_arg], combined_output=True, stdin=DEVNULL, timeout=5)