commands.py 3.0 KB

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