diff options
author | Nick Brassel <nick@tzarc.org> | 2023-03-17 07:35:49 +1100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-16 20:35:49 +0000 |
commit | 1b3f7fcf7d3d441623e065c0be7821c5c5d87c75 (patch) | |
tree | dd573ff4f6f86fac17f16b961f9d63107799f938 /lib/python/qmk/cli | |
parent | f3f634ef671fe276c713d96a23e64dbc5797dd09 (diff) |
Add `qmk find` command, reuse logic for `qmk mass-compile`. (#20139)
Diffstat (limited to 'lib/python/qmk/cli')
-rw-r--r-- | lib/python/qmk/cli/__init__.py | 1 | ||||
-rw-r--r-- | lib/python/qmk/cli/find.py | 23 | ||||
-rwxr-xr-x | lib/python/qmk/cli/mass_compile.py | 91 |
3 files changed, 26 insertions, 89 deletions
diff --git a/lib/python/qmk/cli/__init__.py b/lib/python/qmk/cli/__init__.py index 778eccada8..de7b0476a0 100644 --- a/lib/python/qmk/cli/__init__.py +++ b/lib/python/qmk/cli/__init__.py @@ -39,6 +39,7 @@ subcommands = [ 'qmk.cli.compile', 'qmk.cli.docs', 'qmk.cli.doctor', + 'qmk.cli.find', 'qmk.cli.flash', 'qmk.cli.format.c', 'qmk.cli.format.json', diff --git a/lib/python/qmk/cli/find.py b/lib/python/qmk/cli/find.py new file mode 100644 index 0000000000..b6f74380ab --- /dev/null +++ b/lib/python/qmk/cli/find.py @@ -0,0 +1,23 @@ +"""Command to search through all keyboards and keymaps for a given search criteria. +""" +from milc import cli +from qmk.search import search_keymap_targets + + +@cli.argument( + '-f', + '--filter', + arg_only=True, + action='append', + default=[], + help= # noqa: `format-python` and `pytest` don't agree here. + "Filter the list of keyboards based on the supplied value in rules.mk. Matches info.json structure, and accepts the formats 'features.rgblight=true' or 'exists(matrix_pins.direct)'. May be passed multiple times, all filters need to match. Value may include wildcards such as '*' and '?'." # noqa: `format-python` and `pytest` don't agree here. +) +@cli.argument('-km', '--keymap', type=str, default='default', help="The keymap name to build. Default is 'default'.") +@cli.subcommand('Find builds which match supplied search criteria.') +def find(cli): + """Search through all keyboards and keymaps for a given search criteria. + """ + targets = search_keymap_targets(cli.args.keymap, cli.args.filter) + for target in targets: + print(f'{target[0]}:{target[1]}') diff --git a/lib/python/qmk/cli/mass_compile.py b/lib/python/qmk/cli/mass_compile.py index 810350b954..941e6aa411 100755 --- a/lib/python/qmk/cli/mass_compile.py +++ b/lib/python/qmk/cli/mass_compile.py @@ -2,52 +2,14 @@ This will compile everything in parallel, for testing purposes. """ -import fnmatch -import logging -import multiprocessing import os -import re from pathlib import Path from subprocess import DEVNULL -from dotty_dict import dotty from milc import cli from qmk.constants import QMK_FIRMWARE from qmk.commands import _find_make, get_make_parallel_args -from qmk.info import keymap_json -import qmk.keyboard -import qmk.keymap - - -def _set_log_level(level): - cli.acquire_lock() - old = cli.log_level - cli.log_level = level - cli.log.setLevel(level) - logging.root.setLevel(level) - cli.release_lock() - return old - - -def _all_keymaps(keyboard): - old = _set_log_level(logging.CRITICAL) - keymaps = qmk.keymap.list_keymaps(keyboard) - _set_log_level(old) - return (keyboard, keymaps) - - -def _keymap_exists(keyboard, keymap): - old = _set_log_level(logging.CRITICAL) - ret = keyboard if qmk.keymap.locate_keymap(keyboard, keymap) is not None else None - _set_log_level(old) - return ret - - -def _load_keymap_info(keyboard, keymap): - old = _set_log_level(logging.CRITICAL) - ret = (keyboard, keymap, keymap_json(keyboard, keymap)) - _set_log_level(old) - return ret +from qmk.search import search_keymap_targets @cli.argument('-t', '--no-temp', arg_only=True, action='store_true', help="Remove temporary files during build.") @@ -75,56 +37,7 @@ def mass_compile(cli): builddir = Path(QMK_FIRMWARE) / '.build' makefile = builddir / 'parallel_kb_builds.mk' - targets = [] - - with multiprocessing.Pool() as pool: - cli.log.info(f'Retrieving list of keyboards with keymap "{cli.args.keymap}"...') - target_list = [] - if cli.args.keymap == 'all': - kb_to_kms = pool.map(_all_keymaps, qmk.keyboard.list_keyboards()) - for targets in kb_to_kms: - keyboard = targets[0] - keymaps = targets[1] - target_list.extend([(keyboard, keymap) for keymap in keymaps]) - else: - target_list = [(kb, cli.args.keymap) for kb in filter(lambda kb: kb is not None, pool.starmap(_keymap_exists, [(kb, cli.args.keymap) for kb in qmk.keyboard.list_keyboards()]))] - - if len(cli.args.filter) == 0: - targets = target_list - else: - cli.log.info('Parsing data for all matching keyboard/keymap combinations...') - valid_keymaps = [(e[0], e[1], dotty(e[2])) for e in pool.starmap(_load_keymap_info, target_list)] - - equals_re = re.compile(r'^(?P<key>[a-zA-Z0-9_\.]+)\s*=\s*(?P<value>[^#]+)$') - exists_re = re.compile(r'^exists\((?P<key>[a-zA-Z0-9_\.]+)\)$') - for filter_txt in cli.args.filter: - f = equals_re.match(filter_txt) - if f is not None: - key = f.group('key') - value = f.group('value') - cli.log.info(f'Filtering on condition ("{key}" == "{value}")...') - - def _make_filter(k, v): - expr = fnmatch.translate(v) - rule = re.compile(f'^{expr}$', re.IGNORECASE) - - def f(e): - lhs = e[2].get(k) - lhs = str(False if lhs is None else lhs) - return rule.search(lhs) is not None - - return f - - valid_keymaps = filter(_make_filter(key, value), valid_keymaps) - - f = exists_re.match(filter_txt) - if f is not None: - key = f.group('key') - cli.log.info(f'Filtering on condition (exists: "{key}")...') - valid_keymaps = filter(lambda e: e[2].get(key) is not None, valid_keymaps) - - targets = [(e[0], e[1]) for e in valid_keymaps] - + targets = search_keymap_targets(cli.args.keymap, cli.args.filter) if len(targets) == 0: return |