You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

84 lines
2.8 KiB

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