decorators.py 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. """Helpful decorators that subcommands can use.
  2. """
  3. import functools
  4. from time import monotonic
  5. from milc import cli
  6. from qmk.keyboard import find_keyboard_from_dir
  7. from qmk.keymap import find_keymap_from_dir
  8. def _get_subcommand_name():
  9. """Handle missing cli.subcommand_name on older versions of milc
  10. """
  11. try:
  12. return cli.subcommand_name
  13. except AttributeError:
  14. return cli._subcommand.__name__
  15. def automagic_keyboard(func):
  16. """Sets `cli.config.<subcommand>.keyboard` based on environment.
  17. 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.
  18. """
  19. @functools.wraps(func)
  20. def wrapper(*args, **kwargs):
  21. cmd = _get_subcommand_name()
  22. # Ensure that `--keyboard` was not passed and CWD is under `qmk_firmware/keyboards`
  23. if cli.config_source[cmd]['keyboard'] != 'argument':
  24. keyboard = find_keyboard_from_dir()
  25. if keyboard:
  26. cli.config[cmd]['keyboard'] = keyboard
  27. cli.config_source[cmd]['keyboard'] = 'keyboard_directory'
  28. return func(*args, **kwargs)
  29. return wrapper
  30. def automagic_keymap(func):
  31. """Sets `cli.config.<subcommand>.keymap` based on environment.
  32. 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.
  33. """
  34. @functools.wraps(func)
  35. def wrapper(*args, **kwargs):
  36. cmd = _get_subcommand_name()
  37. # Ensure that `--keymap` was not passed and that we're under `qmk_firmware`
  38. if cli.config_source[cmd]['keymap'] != 'argument':
  39. keymap_name, keymap_type = find_keymap_from_dir()
  40. if keymap_name:
  41. cli.config[cmd]['keymap'] = keymap_name
  42. cli.config_source[cmd]['keymap'] = keymap_type
  43. return func(*args, **kwargs)
  44. return wrapper
  45. def lru_cache(timeout=10, maxsize=128, typed=False):
  46. """Least Recently Used Cache- cache the result of a function.
  47. Args:
  48. timeout
  49. How many seconds to cache results for.
  50. maxsize
  51. The maximum size of the cache in bytes
  52. typed
  53. When `True` argument types will be taken into consideration, for example `3` and `3.0` will be treated as different keys.
  54. """
  55. def wrapper_cache(func):
  56. func = functools.lru_cache(maxsize=maxsize, typed=typed)(func)
  57. func.expiration = monotonic() + timeout
  58. @functools.wraps(func)
  59. def wrapped_func(*args, **kwargs):
  60. if monotonic() >= func.expiration:
  61. func.expiration = monotonic() + timeout
  62. func.cache_clear()
  63. return func(*args, **kwargs)
  64. wrapped_func.cache_info = func.cache_info
  65. wrapped_func.cache_clear = func.cache_clear
  66. return wrapped_func
  67. return wrapper_cache