at master 3.8 kB view raw
1"""Helper functions for commands. 2""" 3import os 4import sys 5import shutil 6from pathlib import Path 7 8from milc import cli 9import jsonschema 10 11from qmk.constants import QMK_USERSPACE, HAS_QMK_USERSPACE 12from qmk.json_schema import json_load, validate 13from qmk.keyboard import keyboard_alias_definitions 14from qmk.util import maybe_exit 15from qmk.path import unix_style_path 16 17 18def find_make(): 19 """Returns the correct make command for this environment. 20 """ 21 make_cmd = os.environ.get('MAKE') 22 23 if not make_cmd: 24 make_cmd = 'gmake' if shutil.which('gmake') else 'make' 25 26 return make_cmd 27 28 29def get_make_parallel_args(parallel=1): 30 """Returns the arguments for running the specified number of parallel jobs. 31 """ 32 parallel_args = [] 33 34 if int(parallel) <= 0: 35 # 0 or -1 means -j without argument (unlimited jobs) 36 parallel_args.append('--jobs') 37 elif int(parallel) > 1: 38 parallel_args.append('--jobs=' + str(parallel)) 39 40 if int(parallel) != 1: 41 # If more than 1 job is used, synchronize parallel output by target 42 parallel_args.append('--output-sync=target') 43 44 return parallel_args 45 46 47def parse_configurator_json(configurator_file): 48 """Open and parse a configurator json export 49 """ 50 user_keymap = json_load(configurator_file) 51 # Validate against the jsonschema 52 try: 53 validate(user_keymap, 'qmk.keymap.v1') 54 55 except jsonschema.ValidationError as e: 56 cli.log.error(f'Invalid JSON keymap: {configurator_file} : {e.message}') 57 maybe_exit(1) 58 59 keyboard = user_keymap.get('keyboard', None) 60 aliases = keyboard_alias_definitions() 61 62 while keyboard in aliases: 63 last_keyboard = keyboard 64 keyboard = aliases[keyboard].get('target', keyboard) 65 if keyboard == last_keyboard: 66 break 67 68 user_keymap['keyboard'] = keyboard 69 return user_keymap 70 71 72def parse_env_vars(args): 73 """Common processing for cli.args.env 74 """ 75 envs = {} 76 for env in args: 77 if '=' in env: 78 key, value = env.split('=', 1) 79 envs[key] = value 80 else: 81 cli.log.warning('Invalid environment variable: %s', env) 82 return envs 83 84 85def build_environment(args): 86 envs = parse_env_vars(args) 87 88 if HAS_QMK_USERSPACE: 89 envs['QMK_USERSPACE'] = unix_style_path(Path(QMK_USERSPACE).resolve()) 90 91 return envs 92 93 94def in_virtualenv(): 95 """Check if running inside a virtualenv. 96 Based on https://stackoverflow.com/a/1883251 97 """ 98 active_prefix = getattr(sys, "base_prefix", None) or getattr(sys, "real_prefix", None) or sys.prefix 99 return active_prefix != sys.prefix 100 101 102def dump_lines(output_file, lines, quiet=True, remove_repeated_newlines=False): 103 """Handle dumping to stdout or file 104 Creates parent folders if required 105 """ 106 generated = '\n'.join(lines) + '\n' 107 if remove_repeated_newlines: 108 while '\n\n\n' in generated: 109 generated = generated.replace('\n\n\n', '\n\n') 110 if output_file and output_file.name != '-': 111 output_file.parent.mkdir(parents=True, exist_ok=True) 112 if output_file.exists(): 113 with open(output_file, 'r', encoding='utf-8', newline='\n') as f: 114 existing = f.read() 115 if existing == generated: 116 if not quiet: 117 cli.log.info(f'No changes to {output_file.name}.') 118 return 119 output_file.replace(output_file.parent / (output_file.name + '.bak')) 120 with open(output_file, 'w', encoding='utf-8', newline='\n') as f: 121 f.write(generated) 122 # output_file.write_text(generated, encoding='utf-8', newline='\n') # `newline` needs Python 3.10 123 124 if not quiet: 125 cli.log.info(f'Wrote {output_file.name} to {output_file}.') 126 else: 127 print(generated)