2020-02-17 19:42:11 +00:00
|
|
|
"""Helper functions for commands.
|
2019-10-05 06:38:34 +00:00
|
|
|
"""
|
2020-03-29 12:29:44 +00:00
|
|
|
import os
|
2021-07-10 15:04:50 +00:00
|
|
|
import sys
|
2020-04-13 16:44:27 +00:00
|
|
|
import shutil
|
2022-03-18 17:03:54 +00:00
|
|
|
from itertools import islice
|
2023-11-27 20:53:43 +00:00
|
|
|
from pathlib import Path
|
2021-01-16 23:13:04 +00:00
|
|
|
|
|
|
|
from milc import cli
|
2022-02-28 20:02:39 +00:00
|
|
|
import jsonschema
|
2020-02-17 19:42:11 +00:00
|
|
|
|
2023-11-27 20:53:43 +00:00
|
|
|
from qmk.constants import QMK_USERSPACE, HAS_QMK_USERSPACE
|
2022-02-28 20:02:39 +00:00
|
|
|
from qmk.json_schema import json_load, validate
|
2023-11-22 00:14:34 +00:00
|
|
|
from qmk.keyboard import keyboard_alias_definitions
|
2021-01-16 23:13:04 +00:00
|
|
|
|
|
|
|
|
2023-11-15 05:24:54 +00:00
|
|
|
def find_make():
|
2021-01-16 23:13:04 +00:00
|
|
|
"""Returns the correct make command for this environment.
|
|
|
|
"""
|
|
|
|
make_cmd = os.environ.get('MAKE')
|
|
|
|
|
|
|
|
if not make_cmd:
|
|
|
|
make_cmd = 'gmake' if shutil.which('gmake') else 'make'
|
2019-10-05 06:38:34 +00:00
|
|
|
|
2021-01-16 23:13:04 +00:00
|
|
|
return make_cmd
|
2019-11-16 07:10:19 +00:00
|
|
|
|
2021-01-16 23:13:04 +00:00
|
|
|
|
2021-08-17 22:46:59 +00:00
|
|
|
def get_make_parallel_args(parallel=1):
|
|
|
|
"""Returns the arguments for running the specified number of parallel jobs.
|
|
|
|
"""
|
|
|
|
parallel_args = []
|
|
|
|
|
|
|
|
if int(parallel) <= 0:
|
|
|
|
# 0 or -1 means -j without argument (unlimited jobs)
|
|
|
|
parallel_args.append('--jobs')
|
2023-11-15 05:24:54 +00:00
|
|
|
elif int(parallel) > 1:
|
2021-08-17 22:46:59 +00:00
|
|
|
parallel_args.append('--jobs=' + str(parallel))
|
|
|
|
|
|
|
|
if int(parallel) != 1:
|
|
|
|
# If more than 1 job is used, synchronize parallel output by target
|
|
|
|
parallel_args.append('--output-sync=target')
|
|
|
|
|
|
|
|
return parallel_args
|
|
|
|
|
|
|
|
|
2020-02-17 19:42:11 +00:00
|
|
|
def parse_configurator_json(configurator_file):
|
|
|
|
"""Open and parse a configurator json export
|
|
|
|
"""
|
2022-02-28 20:02:39 +00:00
|
|
|
user_keymap = json_load(configurator_file)
|
|
|
|
# Validate against the jsonschema
|
|
|
|
try:
|
|
|
|
validate(user_keymap, 'qmk.keymap.v1')
|
|
|
|
|
|
|
|
except jsonschema.ValidationError as e:
|
|
|
|
cli.log.error(f'Invalid JSON keymap: {configurator_file} : {e.message}')
|
|
|
|
exit(1)
|
|
|
|
|
2023-10-05 23:34:23 +00:00
|
|
|
keyboard = user_keymap['keyboard']
|
2023-11-22 00:14:34 +00:00
|
|
|
aliases = keyboard_alias_definitions()
|
2021-03-24 16:26:38 +00:00
|
|
|
|
2023-10-05 23:34:23 +00:00
|
|
|
while keyboard in aliases:
|
|
|
|
last_keyboard = keyboard
|
|
|
|
keyboard = aliases[keyboard].get('target', keyboard)
|
|
|
|
if keyboard == last_keyboard:
|
|
|
|
break
|
2021-03-24 16:26:38 +00:00
|
|
|
|
2023-10-05 23:34:23 +00:00
|
|
|
user_keymap['keyboard'] = keyboard
|
2020-02-17 19:42:11 +00:00
|
|
|
return user_keymap
|
2021-07-10 15:04:50 +00:00
|
|
|
|
|
|
|
|
2022-10-20 13:35:27 +00:00
|
|
|
def build_environment(args):
|
|
|
|
"""Common processing for cli.args.env
|
|
|
|
"""
|
|
|
|
envs = {}
|
|
|
|
for env in args:
|
|
|
|
if '=' in env:
|
|
|
|
key, value = env.split('=', 1)
|
|
|
|
envs[key] = value
|
|
|
|
else:
|
|
|
|
cli.log.warning('Invalid environment variable: %s', env)
|
2023-11-27 20:53:43 +00:00
|
|
|
|
|
|
|
if HAS_QMK_USERSPACE:
|
|
|
|
envs['QMK_USERSPACE'] = Path(QMK_USERSPACE).resolve()
|
|
|
|
|
2022-10-20 13:35:27 +00:00
|
|
|
return envs
|
|
|
|
|
|
|
|
|
2021-07-10 15:04:50 +00:00
|
|
|
def in_virtualenv():
|
|
|
|
"""Check if running inside a virtualenv.
|
|
|
|
Based on https://stackoverflow.com/a/1883251
|
|
|
|
"""
|
|
|
|
active_prefix = getattr(sys, "base_prefix", None) or getattr(sys, "real_prefix", None) or sys.prefix
|
|
|
|
return active_prefix != sys.prefix
|
2022-03-15 17:59:12 +00:00
|
|
|
|
|
|
|
|
|
|
|
def get_chunks(it, size):
|
|
|
|
"""Break down a collection into smaller parts
|
|
|
|
"""
|
|
|
|
it = iter(it)
|
|
|
|
return iter(lambda: tuple(islice(it, size)), ())
|
|
|
|
|
|
|
|
|
2022-03-18 01:09:29 +00:00
|
|
|
def dump_lines(output_file, lines, quiet=True):
|
2022-03-15 17:59:12 +00:00
|
|
|
"""Handle dumping to stdout or file
|
|
|
|
Creates parent folders if required
|
|
|
|
"""
|
2022-03-18 01:09:29 +00:00
|
|
|
generated = '\n'.join(lines) + '\n'
|
|
|
|
if output_file and output_file.name != '-':
|
|
|
|
output_file.parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
if output_file.exists():
|
|
|
|
output_file.replace(output_file.parent / (output_file.name + '.bak'))
|
2022-03-18 01:15:23 +00:00
|
|
|
output_file.write_text(generated, encoding='utf-8')
|
2022-03-18 01:09:29 +00:00
|
|
|
|
|
|
|
if not quiet:
|
|
|
|
cli.log.info(f'Wrote {output_file.name} to {output_file}.')
|
|
|
|
else:
|
|
|
|
print(generated)
|