summaryrefslogtreecommitdiff
path: root/lib/python/qmk/cli/doctor/main.py
diff options
context:
space:
mode:
authorNick Brassel <nick@tzarc.org>2025-11-28 00:36:49 +1100
committerGitHub <noreply@github.com>2025-11-28 00:36:49 +1100
commit9c2ca00074784dbee27b459d71cfc8e75f47b976 (patch)
treea59576289fd024bf35b0573db70eb8862ed44568 /lib/python/qmk/cli/doctor/main.py
parent594558ec7b9ac1963870447778426682065e0d20 (diff)
QMK CLI Environment bootstrapper (#25038)
Co-authored-by: Joel Challis <git@zvecr.com> Co-authored-by: Pascal Getreuer <getreuer@google.com>
Diffstat (limited to 'lib/python/qmk/cli/doctor/main.py')
-rwxr-xr-xlib/python/qmk/cli/doctor/main.py69
1 files changed, 59 insertions, 10 deletions
diff --git a/lib/python/qmk/cli/doctor/main.py b/lib/python/qmk/cli/doctor/main.py
index 391353ebbf..45667e8ce2 100755
--- a/lib/python/qmk/cli/doctor/main.py
+++ b/lib/python/qmk/cli/doctor/main.py
@@ -3,7 +3,6 @@
3Check out the user's QMK environment and make sure it's ready to compile. 3Check out the user's QMK environment and make sure it's ready to compile.
4""" 4"""
5import platform 5import platform
6from subprocess import DEVNULL
7 6
8from milc import cli 7from milc import cli
9from milc.questions import yesno 8from milc.questions import yesno
@@ -16,6 +15,60 @@ from qmk.commands import in_virtualenv
16from qmk.userspace import qmk_userspace_paths, qmk_userspace_validate, UserspaceValidationError 15from qmk.userspace import qmk_userspace_paths, qmk_userspace_validate, UserspaceValidationError
17 16
18 17
18def distrib_tests():
19 def _load_kvp_file(file):
20 """Load a simple key=value file into a dictionary
21 """
22 vars = {}
23 with open(file, 'r') as f:
24 for line in f:
25 if '=' in line:
26 key, value = line.split('=', 1)
27 vars[key.strip()] = value.strip()
28 return vars
29
30 def _parse_toolchain_release_file(file):
31 """Parse the QMK toolchain release info file
32 """
33 try:
34 vars = _load_kvp_file(file)
35 return f'{vars.get("TOOLCHAIN_HOST", "unknown")}:{vars.get("TOOLCHAIN_TARGET", "unknown")}:{vars.get("COMMIT_HASH", "unknown")}'
36 except Exception as e:
37 cli.log.warning('Error reading QMK toolchain release info file: %s', e)
38 return f'Unknown toolchain release info file: {file}'
39
40 def _parse_flashutils_release_file(file):
41 """Parse the QMK flashutils release info file
42 """
43 try:
44 vars = _load_kvp_file(file)
45 return f'{vars.get("FLASHUTILS_HOST", "unknown")}:{vars.get("COMMIT_HASH", "unknown")}'
46 except Exception as e:
47 cli.log.warning('Error reading QMK flashutils release info file: %s', e)
48 return f'Unknown flashutils release info file: {file}'
49
50 try:
51 from qmk.cli import QMK_DISTRIB_DIR
52 if (QMK_DISTRIB_DIR / 'etc').exists():
53 cli.log.info('Found QMK tools distribution directory: {fg_cyan}%s', QMK_DISTRIB_DIR)
54
55 toolchains = [_parse_toolchain_release_file(file) for file in (QMK_DISTRIB_DIR / 'etc').glob('toolchain_release_*')]
56 if len(toolchains) > 0:
57 cli.log.info('Found QMK toolchains: {fg_cyan}%s', ', '.join(toolchains))
58 else:
59 cli.log.warning('No QMK toolchains manifest found.')
60
61 flashutils = [_parse_flashutils_release_file(file) for file in (QMK_DISTRIB_DIR / 'etc').glob('flashutils_release_*')]
62 if len(flashutils) > 0:
63 cli.log.info('Found QMK flashutils: {fg_cyan}%s', ', '.join(flashutils))
64 else:
65 cli.log.warning('No QMK flashutils manifest found.')
66 except ImportError:
67 cli.log.info('QMK tools distribution not found.')
68
69 return CheckStatus.OK
70
71
19def os_tests(): 72def os_tests():
20 """Determine our OS and run platform specific tests 73 """Determine our OS and run platform specific tests
21 """ 74 """
@@ -124,10 +177,12 @@ def doctor(cli):
124 * [ ] Compile a trivial program with each compiler 177 * [ ] Compile a trivial program with each compiler
125 """ 178 """
126 cli.log.info('QMK Doctor is checking your environment.') 179 cli.log.info('QMK Doctor is checking your environment.')
180 cli.log.info('Python version: %s', platform.python_version())
127 cli.log.info('CLI version: %s', cli.version) 181 cli.log.info('CLI version: %s', cli.version)
128 cli.log.info('QMK home: {fg_cyan}%s', QMK_FIRMWARE) 182 cli.log.info('QMK home: {fg_cyan}%s', QMK_FIRMWARE)
129 183
130 status = os_status = os_tests() 184 status = os_status = os_tests()
185 distrib_tests()
131 186
132 userspace_tests(None) 187 userspace_tests(None)
133 188
@@ -141,12 +196,6 @@ def doctor(cli):
141 196
142 # Make sure the basic CLI tools we need are available and can be executed. 197 # Make sure the basic CLI tools we need are available and can be executed.
143 bin_ok = check_binaries() 198 bin_ok = check_binaries()
144
145 if bin_ok == CheckStatus.ERROR:
146 if yesno('Would you like to install dependencies?', default=True):
147 cli.run(['util/qmk_install.sh', '-y'], stdin=DEVNULL, capture_output=False)
148 bin_ok = check_binaries()
149
150 if bin_ok == CheckStatus.OK: 199 if bin_ok == CheckStatus.OK:
151 cli.log.info('All dependencies are installed.') 200 cli.log.info('All dependencies are installed.')
152 elif bin_ok == CheckStatus.WARNING: 201 elif bin_ok == CheckStatus.WARNING:
@@ -163,7 +212,6 @@ def doctor(cli):
163 212
164 # Check out the QMK submodules 213 # Check out the QMK submodules
165 sub_ok = check_submodules() 214 sub_ok = check_submodules()
166
167 if sub_ok == CheckStatus.OK: 215 if sub_ok == CheckStatus.OK:
168 cli.log.info('Submodules are up to date.') 216 cli.log.info('Submodules are up to date.')
169 else: 217 else:
@@ -186,6 +234,7 @@ def doctor(cli):
186 cli.log.info('{fg_yellow}QMK is ready to go, but minor problems were found') 234 cli.log.info('{fg_yellow}QMK is ready to go, but minor problems were found')
187 return 1 235 return 1
188 else: 236 else:
189 cli.log.info('{fg_red}Major problems detected, please fix these problems before proceeding.') 237 cli.log.info('{fg_red}Major problems detected, please fix these problems before proceeding.{fg_reset}')
190 cli.log.info('{fg_blue}Check out the FAQ (https://docs.qmk.fm/#/faq_build) or join the QMK Discord (https://discord.gg/qmk) for help.') 238 cli.log.info('{fg_blue}If you\'re missing dependencies, try following the instructions on: https://docs.qmk.fm/newbs_getting_started{fg_reset}')
239 cli.log.info('{fg_blue}Additionally, check out the FAQ (https://docs.qmk.fm/#/faq_build) or join the QMK Discord (https://discord.gg/qmk) for help.{fg_reset}')
191 return 2 240 return 2