mirror of
https://github.com/qmk/qmk_firmware
synced 2024-12-22 08:26:21 +00:00
qmk find
: expand operator support (#24468)
This commit is contained in:
parent
c7a04bd930
commit
65a8a5ff69
@ -153,20 +153,26 @@ qmk cd
|
|||||||
|
|
||||||
This command allows for searching through keyboard/keymap targets, filtering by specific criteria. `info.json` and `rules.mk` files contribute to the search data, as well as keymap configurations, and the results can be filtered using "dotty" syntax matching the overall `info.json` file format.
|
This command allows for searching through keyboard/keymap targets, filtering by specific criteria. `info.json` and `rules.mk` files contribute to the search data, as well as keymap configurations, and the results can be filtered using "dotty" syntax matching the overall `info.json` file format.
|
||||||
|
|
||||||
For example, one could search for all keyboards using STM32F411:
|
For example, one could search for all keyboards powered by the STM32F411 microcontroller:
|
||||||
|
|
||||||
```
|
```
|
||||||
qmk find -f 'processor=STM32F411'
|
qmk find -f 'processor==STM32F411'
|
||||||
```
|
```
|
||||||
|
|
||||||
...and one can further constrain the list to keyboards using STM32F411 as well as rgb_matrix support:
|
The list can be further constrained by passing additional filter expressions:
|
||||||
|
|
||||||
```
|
```
|
||||||
qmk find -f 'processor=STM32F411' -f 'features.rgb_matrix=true'
|
qmk find -f 'processor==STM32F411' -f 'features.rgb_matrix==true'
|
||||||
```
|
```
|
||||||
|
|
||||||
The following filter expressions are also supported:
|
The following filter expressions are supported:
|
||||||
|
|
||||||
|
- `key == value`: Match targets where `key` is equal to `value`. May include wildcards such as `*` and `?`.
|
||||||
|
- `key != value`: Match targets where `key` is not `value`. May include wildcards such as `*` and `?`.
|
||||||
|
- `key < value`: Match targets where `key` is a number less than `value`.
|
||||||
|
- `key > value`: Match targets where `key` is a number greater than `value`.
|
||||||
|
- `key <= value`: Match targets where `key` is a number less than or equal to `value`.
|
||||||
|
- `key >= value`: Match targets where `key` is a number greater than or equal to `value`.
|
||||||
- `exists(key)`: Match targets where `key` is present.
|
- `exists(key)`: Match targets where `key` is present.
|
||||||
- `absent(key)`: Match targets where `key` is not present.
|
- `absent(key)`: Match targets where `key` is not present.
|
||||||
- `contains(key, value)`: Match targets where `key` contains `value`. Can be used for strings, arrays and object keys.
|
- `contains(key, value)`: Match targets where `key` contains `value`. Can be used for strings, arrays and object keys.
|
||||||
@ -175,7 +181,7 @@ The following filter expressions are also supported:
|
|||||||
You can also list arbitrary values for each matched target with `--print`:
|
You can also list arbitrary values for each matched target with `--print`:
|
||||||
|
|
||||||
```
|
```
|
||||||
qmk find -f 'processor=STM32F411' -p 'keyboard_name' -p 'features.rgb_matrix'
|
qmk find -f 'processor==STM32F411' -p 'keyboard_name' -p 'features.rgb_matrix'
|
||||||
```
|
```
|
||||||
|
|
||||||
**Usage**:
|
**Usage**:
|
||||||
|
@ -239,11 +239,11 @@ def _filter_keymap_targets(target_list: List[KeyboardKeymapDesc], filters: List[
|
|||||||
valid_targets = parallel_map(_load_keymap_info, target_list)
|
valid_targets = parallel_map(_load_keymap_info, target_list)
|
||||||
|
|
||||||
function_re = re.compile(r'^(?P<function>[a-zA-Z]+)\((?P<key>[a-zA-Z0-9_\.]+)(,\s*(?P<value>[^#]+))?\)$')
|
function_re = re.compile(r'^(?P<function>[a-zA-Z]+)\((?P<key>[a-zA-Z0-9_\.]+)(,\s*(?P<value>[^#]+))?\)$')
|
||||||
equals_re = re.compile(r'^(?P<key>[a-zA-Z0-9_\.]+)\s*=\s*(?P<value>[^#]+)$')
|
comparison_re = re.compile(r'^(?P<key>[a-zA-Z0-9_\.]+)\s*(?P<op>[\<\>\!=]=|\<|\>)\s*(?P<value>[^#]+)$')
|
||||||
|
|
||||||
for filter_expr in filters:
|
for filter_expr in filters:
|
||||||
function_match = function_re.match(filter_expr)
|
function_match = function_re.match(filter_expr)
|
||||||
equals_match = equals_re.match(filter_expr)
|
comparison_match = comparison_re.match(filter_expr)
|
||||||
|
|
||||||
if function_match is not None:
|
if function_match is not None:
|
||||||
func_name = function_match.group('function').lower()
|
func_name = function_match.group('function').lower()
|
||||||
@ -259,23 +259,43 @@ def _filter_keymap_targets(target_list: List[KeyboardKeymapDesc], filters: List[
|
|||||||
value_str = f", {{fg_cyan}}{value}{{fg_reset}}" if value is not None else ""
|
value_str = f", {{fg_cyan}}{value}{{fg_reset}}" if value is not None else ""
|
||||||
cli.log.info(f'Filtering on condition: {{fg_green}}{func_name}{{fg_reset}}({{fg_cyan}}{key}{{fg_reset}}{value_str})...')
|
cli.log.info(f'Filtering on condition: {{fg_green}}{func_name}{{fg_reset}}({{fg_cyan}}{key}{{fg_reset}}{value_str})...')
|
||||||
|
|
||||||
elif equals_match is not None:
|
elif comparison_match is not None:
|
||||||
key = equals_match.group('key')
|
key = comparison_match.group('key')
|
||||||
value = equals_match.group('value')
|
op = comparison_match.group('op')
|
||||||
cli.log.info(f'Filtering on condition: {{fg_cyan}}{key}{{fg_reset}} == {{fg_cyan}}{value}{{fg_reset}}...')
|
value = comparison_match.group('value')
|
||||||
|
cli.log.info(f'Filtering on condition: {{fg_cyan}}{key}{{fg_reset}} {op} {{fg_cyan}}{value}{{fg_reset}}...')
|
||||||
|
|
||||||
def _make_filter(k, v):
|
def _make_filter(k, o, v):
|
||||||
expr = fnmatch.translate(v)
|
expr = fnmatch.translate(v)
|
||||||
rule = re.compile(f'^{expr}$', re.IGNORECASE)
|
rule = re.compile(f'^{expr}$', re.IGNORECASE)
|
||||||
|
|
||||||
def f(e: KeyboardKeymapDesc):
|
def f(e: KeyboardKeymapDesc):
|
||||||
lhs = e.dotty.get(k)
|
lhs = e.dotty.get(k)
|
||||||
lhs = str(False if lhs is None else lhs)
|
rhs = v
|
||||||
return rule.search(lhs) is not None
|
|
||||||
|
if o in ['<', '>', '<=', '>=']:
|
||||||
|
lhs = int(False if lhs is None else lhs)
|
||||||
|
rhs = int(rhs)
|
||||||
|
|
||||||
|
if o == '<':
|
||||||
|
return lhs < rhs
|
||||||
|
elif o == '>':
|
||||||
|
return lhs > rhs
|
||||||
|
elif o == '<=':
|
||||||
|
return lhs <= rhs
|
||||||
|
elif o == '>=':
|
||||||
|
return lhs >= rhs
|
||||||
|
else:
|
||||||
|
lhs = str(False if lhs is None else lhs)
|
||||||
|
|
||||||
|
if o == '!=':
|
||||||
|
return rule.search(lhs) is None
|
||||||
|
elif o == '==':
|
||||||
|
return rule.search(lhs) is not None
|
||||||
|
|
||||||
return f
|
return f
|
||||||
|
|
||||||
valid_targets = filter(_make_filter(key, value), valid_targets)
|
valid_targets = filter(_make_filter(key, op, value), valid_targets)
|
||||||
else:
|
else:
|
||||||
cli.log.warning(f'Unrecognized filter expression: {filter_expr}')
|
cli.log.warning(f'Unrecognized filter expression: {filter_expr}')
|
||||||
continue
|
continue
|
||||||
|
@ -390,7 +390,7 @@ def test_find_contains():
|
|||||||
def test_find_multiple_conditions():
|
def test_find_multiple_conditions():
|
||||||
# this is intended to match at least 'crkbd/rev1'
|
# this is intended to match at least 'crkbd/rev1'
|
||||||
result = check_subcommand(
|
result = check_subcommand(
|
||||||
'find', '-f', 'exists(rgb_matrix.split_count)', '-f', 'contains(matrix_pins.cols, B1)', '-f', 'length(matrix_pins.cols, 6)', '-f', 'absent(eeprom.driver)', '-f', 'ws2812.pin=D3', '-p', 'rgb_matrix.split_count', '-p', 'matrix_pins.cols', '-p',
|
'find', '-f', 'exists(rgb_matrix.split_count)', '-f', 'contains(matrix_pins.cols, B1)', '-f', 'length(matrix_pins.cols, 6)', '-f', 'absent(eeprom.driver)', '-f', 'ws2812.pin == D3', '-p', 'rgb_matrix.split_count', '-p', 'matrix_pins.cols', '-p',
|
||||||
'eeprom.driver', '-p', 'ws2812.pin'
|
'eeprom.driver', '-p', 'ws2812.pin'
|
||||||
)
|
)
|
||||||
check_returncode(result)
|
check_returncode(result)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user