diff options
Diffstat (limited to 'lib/python/qmk/keyboard.py')
-rw-r--r-- | lib/python/qmk/keyboard.py | 80 |
1 files changed, 73 insertions, 7 deletions
diff --git a/lib/python/qmk/keyboard.py b/lib/python/qmk/keyboard.py index a4c2873757..06c9df874f 100644 --- a/lib/python/qmk/keyboard.py +++ b/lib/python/qmk/keyboard.py @@ -6,7 +6,9 @@ from pathlib import Path import os from glob import glob +import qmk.path from qmk.c_parse import parse_config_h_file +from qmk.json_schema import json_load from qmk.makefile import parse_rules_mk_file BOX_DRAWING_CHARACTERS = { @@ -31,12 +33,71 @@ BOX_DRAWING_CHARACTERS = { base_path = os.path.join(os.getcwd(), "keyboards") + os.path.sep +def find_keyboard_from_dir(): + """Returns a keyboard name based on the user's current directory. + """ + relative_cwd = qmk.path.under_qmk_firmware() + + if relative_cwd and len(relative_cwd.parts) > 1 and relative_cwd.parts[0] == 'keyboards': + # Attempt to extract the keyboard name from the current directory + current_path = Path('/'.join(relative_cwd.parts[1:])) + + if 'keymaps' in current_path.parts: + # Strip current_path of anything after `keymaps` + keymap_index = len(current_path.parts) - current_path.parts.index('keymaps') - 1 + current_path = current_path.parents[keymap_index] + + if qmk.path.is_keyboard(current_path): + return str(current_path) + + +def find_readme(keyboard): + """Returns the readme for this keyboard. + """ + cur_dir = qmk.path.keyboard(keyboard) + keyboards_dir = Path('keyboards') + while not (cur_dir / 'readme.md').exists(): + if cur_dir == keyboards_dir: + return None + cur_dir = cur_dir.parent + + return cur_dir / 'readme.md' + + +def keyboard_folder(keyboard): + """Returns the actual keyboard folder. + + This checks aliases and DEFAULT_FOLDER to resolve the actual path for a keyboard. + """ + aliases = json_load(Path('data/mappings/keyboard_aliases.json')) + + if keyboard in aliases: + keyboard = aliases[keyboard].get('target', keyboard) + + rules_mk_file = Path(base_path, keyboard, 'rules.mk') + + if rules_mk_file.exists(): + rules_mk = parse_rules_mk_file(rules_mk_file) + keyboard = rules_mk.get('DEFAULT_FOLDER', keyboard) + + if not qmk.path.is_keyboard(keyboard): + raise ValueError(f'Invalid keyboard: {keyboard}') + + return keyboard + + def _find_name(path): """Determine the keyboard name by stripping off the base_path and rules.mk. """ return path.replace(base_path, "").replace(os.path.sep + "rules.mk", "") +def keyboard_completer(prefix, action, parser, parsed_args): + """Returns a list of keyboards for tab completion. + """ + return list_keyboards() + + def list_keyboards(): """Returns a list of all keyboards. """ @@ -44,7 +105,16 @@ def list_keyboards(): kb_wildcard = os.path.join(base_path, "**", "rules.mk") paths = [path for path in glob(kb_wildcard, recursive=True) if 'keymaps' not in path] - return sorted(map(_find_name, paths)) + return sorted(set(map(resolve_keyboard, map(_find_name, paths)))) + + +def resolve_keyboard(keyboard): + cur_dir = Path('keyboards') + rules = parse_rules_mk_file(cur_dir / keyboard / 'rules.mk') + while 'DEFAULT_FOLDER' in rules and keyboard != rules['DEFAULT_FOLDER']: + keyboard = rules['DEFAULT_FOLDER'] + rules = parse_rules_mk_file(cur_dir / keyboard / 'rules.mk') + return keyboard def config_h(keyboard): @@ -58,8 +128,7 @@ def config_h(keyboard): """ config = {} cur_dir = Path('keyboards') - rules = rules_mk(keyboard) - keyboard = Path(rules['DEFAULT_FOLDER'] if 'DEFAULT_FOLDER' in rules else keyboard) + keyboard = Path(resolve_keyboard(keyboard)) for dir in keyboard.parts: cur_dir = cur_dir / dir @@ -77,13 +146,10 @@ def rules_mk(keyboard): Returns: a dictionary representing the content of the entire rules.mk tree for a keyboard """ - keyboard = Path(keyboard) cur_dir = Path('keyboards') + keyboard = Path(resolve_keyboard(keyboard)) rules = parse_rules_mk_file(cur_dir / keyboard / 'rules.mk') - if 'DEFAULT_FOLDER' in rules: - keyboard = Path(rules['DEFAULT_FOLDER']) - for i, dir in enumerate(keyboard.parts): cur_dir = cur_dir / dir rules = parse_rules_mk_file(cur_dir / 'rules.mk', rules) |