diff --git a/lib/python/qmk/cli/doctor/__init__.py b/lib/python/qmk/cli/doctor/__init__.py new file mode 100755 index 00000000000..75a7e7d1963 --- /dev/null +++ b/lib/python/qmk/cli/doctor/__init__.py @@ -0,0 +1,5 @@ +"""QMK Doctor + +Check out the user's QMK environment and make sure it's ready to compile. +""" +from .main import doctor \ No newline at end of file diff --git a/lib/python/qmk/os_helpers/__init__.py b/lib/python/qmk/cli/doctor/check.py similarity index 91% rename from lib/python/qmk/os_helpers/__init__.py rename to lib/python/qmk/cli/doctor/check.py index 3e98db3c32e..a0bbb281688 100644 --- a/lib/python/qmk/os_helpers/__init__.py +++ b/lib/python/qmk/cli/doctor/check.py @@ -1,4 +1,4 @@ -"""OS-agnostic helper functions +"""Check for specific programs. """ from enum import Enum import re @@ -30,7 +30,7 @@ ESSENTIAL_BINARIES = { } -def parse_gcc_version(version): +def _parse_gcc_version(version): m = re.match(r"(\d+)(?:\.(\d+))?(?:\.(\d+))?", version) return { @@ -40,7 +40,7 @@ def parse_gcc_version(version): } -def check_arm_gcc_version(): +def _check_arm_gcc_version(): """Returns True if the arm-none-eabi-gcc version is not known to cause problems. """ if 'output' in ESSENTIAL_BINARIES['arm-none-eabi-gcc']: @@ -50,7 +50,7 @@ def check_arm_gcc_version(): return CheckStatus.OK # Right now all known arm versions are ok -def check_avr_gcc_version(): +def _check_avr_gcc_version(): """Returns True if the avr-gcc version is not known to cause problems. """ rc = CheckStatus.ERROR @@ -60,7 +60,7 @@ def check_avr_gcc_version(): cli.log.info('Found avr-gcc version %s', version_number) rc = CheckStatus.OK - parsed_version = parse_gcc_version(version_number) + parsed_version = _parse_gcc_version(version_number) if parsed_version['major'] > 8: cli.log.warning('{fg_yellow}We do not recommend avr-gcc newer than 8. Downgrading to 8.x is recommended.') rc = CheckStatus.WARNING @@ -68,7 +68,7 @@ def check_avr_gcc_version(): return rc -def check_avrdude_version(): +def _check_avrdude_version(): if 'output' in ESSENTIAL_BINARIES['avrdude']: last_line = ESSENTIAL_BINARIES['avrdude']['output'].split('\n')[-2] version_number = last_line.split()[2][:-1] @@ -77,7 +77,7 @@ def check_avrdude_version(): return CheckStatus.OK -def check_dfu_util_version(): +def _check_dfu_util_version(): if 'output' in ESSENTIAL_BINARIES['dfu-util']: first_line = ESSENTIAL_BINARIES['dfu-util']['output'].split('\n')[0] version_number = first_line.split()[1] @@ -86,7 +86,7 @@ def check_dfu_util_version(): return CheckStatus.OK -def check_dfu_programmer_version(): +def _check_dfu_programmer_version(): if 'output' in ESSENTIAL_BINARIES['dfu-programmer']: first_line = ESSENTIAL_BINARIES['dfu-programmer']['output'].split('\n')[0] version_number = first_line.split()[1] @@ -111,7 +111,7 @@ def check_binary_versions(): """Check the versions of ESSENTIAL_BINARIES """ versions = [] - for check in (check_arm_gcc_version, check_avr_gcc_version, check_avrdude_version, check_dfu_util_version, check_dfu_programmer_version): + for check in (_check_arm_gcc_version, _check_avr_gcc_version, _check_avrdude_version, _check_dfu_util_version, _check_dfu_programmer_version): versions.append(check()) return versions diff --git a/lib/python/qmk/os_helpers/linux/__init__.py b/lib/python/qmk/cli/doctor/linux.py similarity index 89% rename from lib/python/qmk/os_helpers/linux/__init__.py rename to lib/python/qmk/cli/doctor/linux.py index 008654ab0fc..c0b77216a19 100644 --- a/lib/python/qmk/os_helpers/linux/__init__.py +++ b/lib/python/qmk/cli/doctor/linux.py @@ -1,11 +1,13 @@ """OS-specific functions for: Linux """ -from pathlib import Path +import platform import shutil +from pathlib import Path from milc import cli + from qmk.constants import QMK_FIRMWARE -from qmk.os_helpers import CheckStatus +from .check import CheckStatus def _udev_rule(vid, pid=None, *args): @@ -138,3 +140,23 @@ def check_modem_manager(): """(TODO): Add check for non-systemd systems """ return False + + +def os_test_linux(): + """Run the Linux specific tests. + """ + # Don't bother with udev on WSL, for now + if 'microsoft' in platform.uname().release.lower(): + cli.log.info("Detected {fg_cyan}Linux (WSL){fg_reset}.") + + # https://github.com/microsoft/WSL/issues/4197 + if QMK_FIRMWARE.as_posix().startswith("/mnt"): + cli.log.warning("I/O performance on /mnt may be extremely slow.") + return CheckStatus.WARNING + + return CheckStatus.OK + else: + cli.log.info("Detected {fg_cyan}Linux{fg_reset}.") + from .linux import check_udev_rules + + return check_udev_rules() diff --git a/lib/python/qmk/cli/doctor/macos.py b/lib/python/qmk/cli/doctor/macos.py new file mode 100644 index 00000000000..00fb272858b --- /dev/null +++ b/lib/python/qmk/cli/doctor/macos.py @@ -0,0 +1,13 @@ +import platform + +from milc import cli + +from .check import CheckStatus + + +def os_test_macos(): + """Run the Mac specific tests. + """ + cli.log.info("Detected {fg_cyan}macOS %s{fg_reset}.", platform.mac_ver()[0]) + + return CheckStatus.OK diff --git a/lib/python/qmk/cli/doctor.py b/lib/python/qmk/cli/doctor/main.py similarity index 74% rename from lib/python/qmk/cli/doctor.py rename to lib/python/qmk/cli/doctor/main.py index 9e105706207..45b0203b6e8 100755 --- a/lib/python/qmk/cli/doctor.py +++ b/lib/python/qmk/cli/doctor/main.py @@ -7,9 +7,10 @@ from subprocess import DEVNULL from milc import cli from milc.questions import yesno + from qmk import submodules from qmk.constants import QMK_FIRMWARE -from qmk.os_helpers import CheckStatus, check_binaries, check_binary_versions, check_submodules, check_git_repo +from .check import CheckStatus, check_binaries, check_binary_versions, check_submodules, check_git_repo def os_tests(): @@ -18,53 +19,19 @@ def os_tests(): platform_id = platform.platform().lower() if 'darwin' in platform_id or 'macos' in platform_id: + from .macos import os_test_macos return os_test_macos() elif 'linux' in platform_id: + from .linux import os_test_linux return os_test_linux() elif 'windows' in platform_id: + from .windows import os_test_windows return os_test_windows() else: cli.log.warning('Unsupported OS detected: %s', platform_id) return CheckStatus.WARNING -def os_test_linux(): - """Run the Linux specific tests. - """ - # Don't bother with udev on WSL, for now - if 'microsoft' in platform.uname().release.lower(): - cli.log.info("Detected {fg_cyan}Linux (WSL){fg_reset}.") - - # https://github.com/microsoft/WSL/issues/4197 - if QMK_FIRMWARE.as_posix().startswith("/mnt"): - cli.log.warning("I/O performance on /mnt may be extremely slow.") - return CheckStatus.WARNING - - return CheckStatus.OK - else: - cli.log.info("Detected {fg_cyan}Linux{fg_reset}.") - from qmk.os_helpers.linux import check_udev_rules - - return check_udev_rules() - - -def os_test_macos(): - """Run the Mac specific tests. - """ - cli.log.info("Detected {fg_cyan}macOS %s{fg_reset}.", platform.mac_ver()[0]) - - return CheckStatus.OK - - -def os_test_windows(): - """Run the Windows specific tests. - """ - win32_ver = platform.win32_ver() - cli.log.info("Detected {fg_cyan}Windows %s (%s){fg_reset}.", win32_ver[0], win32_ver[1]) - - return CheckStatus.OK - - @cli.argument('-y', '--yes', action='store_true', arg_only=True, help='Answer yes to all questions.') @cli.argument('-n', '--no', action='store_true', arg_only=True, help='Answer no to all questions.') @cli.subcommand('Basic QMK environment checks') diff --git a/lib/python/qmk/cli/doctor/windows.py b/lib/python/qmk/cli/doctor/windows.py new file mode 100644 index 00000000000..381ab36fde9 --- /dev/null +++ b/lib/python/qmk/cli/doctor/windows.py @@ -0,0 +1,14 @@ +import platform + +from milc import cli + +from .check import CheckStatus + + +def os_test_windows(): + """Run the Windows specific tests. + """ + win32_ver = platform.win32_ver() + cli.log.info("Detected {fg_cyan}Windows %s (%s){fg_reset}.", win32_ver[0], win32_ver[1]) + + return CheckStatus.OK