commands.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. """Helper functions for commands.
  2. """
  3. import os
  4. import sys
  5. import shutil
  6. from pathlib import Path
  7. from milc import cli
  8. import jsonschema
  9. from qmk.constants import QMK_USERSPACE, HAS_QMK_USERSPACE
  10. from qmk.json_schema import json_load, validate
  11. from qmk.keyboard import keyboard_alias_definitions
  12. from qmk.util import maybe_exit
  13. def find_make():
  14. """Returns the correct make command for this environment.
  15. """
  16. make_cmd = os.environ.get('MAKE')
  17. if not make_cmd:
  18. make_cmd = 'gmake' if shutil.which('gmake') else 'make'
  19. return make_cmd
  20. def get_make_parallel_args(parallel=1):
  21. """Returns the arguments for running the specified number of parallel jobs.
  22. """
  23. parallel_args = []
  24. if int(parallel) <= 0:
  25. # 0 or -1 means -j without argument (unlimited jobs)
  26. parallel_args.append('--jobs')
  27. elif int(parallel) > 1:
  28. parallel_args.append('--jobs=' + str(parallel))
  29. if int(parallel) != 1:
  30. # If more than 1 job is used, synchronize parallel output by target
  31. parallel_args.append('--output-sync=target')
  32. return parallel_args
  33. def parse_configurator_json(configurator_file):
  34. """Open and parse a configurator json export
  35. """
  36. user_keymap = json_load(configurator_file)
  37. # Validate against the jsonschema
  38. try:
  39. validate(user_keymap, 'qmk.keymap.v1')
  40. except jsonschema.ValidationError as e:
  41. cli.log.error(f'Invalid JSON keymap: {configurator_file} : {e.message}')
  42. maybe_exit(1)
  43. keyboard = user_keymap['keyboard']
  44. aliases = keyboard_alias_definitions()
  45. while keyboard in aliases:
  46. last_keyboard = keyboard
  47. keyboard = aliases[keyboard].get('target', keyboard)
  48. if keyboard == last_keyboard:
  49. break
  50. user_keymap['keyboard'] = keyboard
  51. return user_keymap
  52. def build_environment(args):
  53. """Common processing for cli.args.env
  54. """
  55. envs = {}
  56. for env in args:
  57. if '=' in env:
  58. key, value = env.split('=', 1)
  59. envs[key] = value
  60. else:
  61. cli.log.warning('Invalid environment variable: %s', env)
  62. if HAS_QMK_USERSPACE:
  63. envs['QMK_USERSPACE'] = Path(QMK_USERSPACE).resolve()
  64. return envs
  65. def in_virtualenv():
  66. """Check if running inside a virtualenv.
  67. Based on https://stackoverflow.com/a/1883251
  68. """
  69. active_prefix = getattr(sys, "base_prefix", None) or getattr(sys, "real_prefix", None) or sys.prefix
  70. return active_prefix != sys.prefix
  71. def dump_lines(output_file, lines, quiet=True):
  72. """Handle dumping to stdout or file
  73. Creates parent folders if required
  74. """
  75. generated = '\n'.join(lines) + '\n'
  76. if output_file and output_file.name != '-':
  77. output_file.parent.mkdir(parents=True, exist_ok=True)
  78. if output_file.exists():
  79. output_file.replace(output_file.parent / (output_file.name + '.bak'))
  80. output_file.write_text(generated, encoding='utf-8')
  81. if not quiet:
  82. cli.log.info(f'Wrote {output_file.name} to {output_file}.')
  83. else:
  84. print(generated)