doctor.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. """QMK Doctor
  2. Check out the user's QMK environment and make sure it's ready to compile.
  3. """
  4. import platform
  5. from milc import cli
  6. from milc.questions import yesno
  7. from qmk import submodules
  8. from qmk.constants import QMK_FIRMWARE
  9. from qmk.commands import run
  10. from qmk.os_helpers import CheckStatus, check_binaries, check_binary_versions, check_submodules, check_git_repo
  11. def os_tests():
  12. """Determine our OS and run platform specific tests
  13. """
  14. platform_id = platform.platform().lower()
  15. if 'darwin' in platform_id or 'macos' in platform_id:
  16. return os_test_macos()
  17. elif 'linux' in platform_id:
  18. return os_test_linux()
  19. elif 'windows' in platform_id:
  20. return os_test_windows()
  21. else:
  22. cli.log.warning('Unsupported OS detected: %s', platform_id)
  23. return CheckStatus.WARNING
  24. def os_test_linux():
  25. """Run the Linux specific tests.
  26. """
  27. # Don't bother with udev on WSL, for now
  28. if 'microsoft' in platform.uname().release.lower():
  29. cli.log.info("Detected {fg_cyan}Linux (WSL){fg_reset}.")
  30. return CheckStatus.OK
  31. else:
  32. cli.log.info("Detected {fg_cyan}Linux{fg_reset}.")
  33. from qmk.os_helpers.linux import check_udev_rules
  34. return check_udev_rules()
  35. def os_test_macos():
  36. """Run the Mac specific tests.
  37. """
  38. cli.log.info("Detected {fg_cyan}macOS{fg_reset}.")
  39. return CheckStatus.OK
  40. def os_test_windows():
  41. """Run the Windows specific tests.
  42. """
  43. cli.log.info("Detected {fg_cyan}Windows{fg_reset}.")
  44. return CheckStatus.OK
  45. @cli.argument('-y', '--yes', action='store_true', arg_only=True, help='Answer yes to all questions.')
  46. @cli.argument('-n', '--no', action='store_true', arg_only=True, help='Answer no to all questions.')
  47. @cli.subcommand('Basic QMK environment checks')
  48. def doctor(cli):
  49. """Basic QMK environment checks.
  50. This is currently very simple, it just checks that all the expected binaries are on your system.
  51. TODO(unclaimed):
  52. * [ ] Compile a trivial program with each compiler
  53. """
  54. cli.log.info('QMK Doctor is checking your environment.')
  55. status = os_tests()
  56. cli.log.info('QMK home: {fg_cyan}%s', QMK_FIRMWARE)
  57. # Make sure our QMK home is a Git repo
  58. git_ok = check_git_repo()
  59. if git_ok == CheckStatus.WARNING:
  60. cli.log.warning("QMK home does not appear to be a Git repository! (no .git folder)")
  61. status = CheckStatus.WARNING
  62. # Make sure the basic CLI tools we need are available and can be executed.
  63. bin_ok = check_binaries()
  64. if not bin_ok:
  65. if yesno('Would you like to install dependencies?', default=True):
  66. run(['util/qmk_install.sh'])
  67. bin_ok = check_binaries()
  68. if bin_ok:
  69. cli.log.info('All dependencies are installed.')
  70. else:
  71. status = CheckStatus.ERROR
  72. # Make sure the tools are at the correct version
  73. ver_ok = check_binary_versions()
  74. if CheckStatus.ERROR in ver_ok:
  75. status = CheckStatus.ERROR
  76. elif CheckStatus.WARNING in ver_ok and status == CheckStatus.OK:
  77. status = CheckStatus.WARNING
  78. # Check out the QMK submodules
  79. sub_ok = check_submodules()
  80. if sub_ok == CheckStatus.OK:
  81. cli.log.info('Submodules are up to date.')
  82. else:
  83. if yesno('Would you like to clone the submodules?', default=True):
  84. submodules.update()
  85. sub_ok = check_submodules()
  86. if sub_ok == CheckStatus.ERROR:
  87. status = CheckStatus.ERROR
  88. elif sub_ok == CheckStatus.WARNING and status == CheckStatus.OK:
  89. status = CheckStatus.WARNING
  90. # Report a summary of our findings to the user
  91. if status == CheckStatus.OK:
  92. cli.log.info('{fg_green}QMK is ready to go')
  93. return 0
  94. elif status == CheckStatus.WARNING:
  95. cli.log.info('{fg_yellow}QMK is ready to go, but minor problems were found')
  96. return 1
  97. else:
  98. cli.log.info('{fg_red}Major problems detected, please fix these problems before proceeding.')
  99. cli.log.info('{fg_blue}Check out the FAQ (https://docs.qmk.fm/#/faq_build) or join the QMK Discord (https://discord.gg/Uq7gcHh) for help.')
  100. return 2