at master 3.3 kB view raw
1"""Helpful decorators that subcommands can use. 2""" 3import functools 4from time import monotonic 5 6from milc import cli 7 8from qmk.keyboard import find_keyboard_from_dir, keyboard_folder 9from qmk.keymap import find_keymap_from_dir 10 11 12def _get_subcommand_name(): 13 """Handle missing cli.subcommand_name on older versions of milc 14 """ 15 try: 16 return cli.subcommand_name 17 except AttributeError: 18 return cli._subcommand.__name__ 19 20 21def automagic_keyboard(func): 22 """Sets `cli.config.<subcommand>.keyboard` based on environment. 23 24 This will rewrite cli.config.<subcommand>.keyboard if the user did not pass `--keyboard` and the directory they are currently in is a keyboard or keymap directory. 25 """ 26 @functools.wraps(func) 27 def wrapper(*args, **kwargs): 28 cmd = _get_subcommand_name() 29 30 # TODO: Workaround for if config file contains "old" keyboard name 31 # Potential long-term fix needs to be within global cli or milc 32 if cli.config_source[cmd]['keyboard'] == 'config_file': 33 cli.config[cmd]['keyboard'] = keyboard_folder(cli.config[cmd]['keyboard']) 34 35 # Ensure that `--keyboard` was not passed and CWD is under `qmk_firmware/keyboards` 36 if cli.config_source[cmd]['keyboard'] != 'argument': 37 keyboard = find_keyboard_from_dir() 38 39 if keyboard: 40 cli.config[cmd]['keyboard'] = keyboard 41 cli.config_source[cmd]['keyboard'] = 'keyboard_directory' 42 43 return func(*args, **kwargs) 44 45 return wrapper 46 47 48def automagic_keymap(func): 49 """Sets `cli.config.<subcommand>.keymap` based on environment. 50 51 This will rewrite cli.config.<subcommand>.keymap if the user did not pass `--keymap` and the directory they are currently in is a keymap, layout, or user directory. 52 """ 53 @functools.wraps(func) 54 def wrapper(*args, **kwargs): 55 cmd = _get_subcommand_name() 56 57 # Ensure that `--keymap` was not passed and that we're under `qmk_firmware` 58 if cli.config_source[cmd]['keymap'] != 'argument': 59 keymap_name, keymap_type = find_keymap_from_dir() 60 61 if keymap_name: 62 cli.config[cmd]['keymap'] = keymap_name 63 cli.config_source[cmd]['keymap'] = keymap_type 64 65 return func(*args, **kwargs) 66 67 return wrapper 68 69 70def lru_cache(timeout=10, maxsize=128, typed=False): 71 """Least Recently Used Cache- cache the result of a function. 72 73 Args: 74 75 timeout 76 How many seconds to cache results for. 77 78 maxsize 79 The maximum size of the cache in bytes 80 81 typed 82 When `True` argument types will be taken into consideration, for example `3` and `3.0` will be treated as different keys. 83 """ 84 def wrapper_cache(func): 85 func = functools.lru_cache(maxsize=maxsize, typed=typed)(func) 86 func.expiration = monotonic() + timeout 87 88 @functools.wraps(func) 89 def wrapped_func(*args, **kwargs): 90 if monotonic() >= func.expiration: 91 func.expiration = monotonic() + timeout 92 93 func.cache_clear() 94 95 return func(*args, **kwargs) 96 97 wrapped_func.cache_info = func.cache_info 98 wrapped_func.cache_clear = func.cache_clear 99 100 return wrapped_func 101 102 return wrapper_cache