docopt_command.py 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. import sys
  2. from inspect import getdoc
  3. from docopt import docopt, DocoptExit
  4. def docopt_full_help(docstring, *args, **kwargs):
  5. try:
  6. return docopt(docstring, *args, **kwargs)
  7. except DocoptExit:
  8. raise SystemExit(docstring)
  9. class DocoptCommand(object):
  10. def docopt_options(self):
  11. return {'options_first': True}
  12. def sys_dispatch(self):
  13. self.dispatch(sys.argv[1:], None)
  14. def dispatch(self, argv, global_options):
  15. self.perform_command(*self.parse(argv, global_options))
  16. def perform_command(self, options, command, handler, command_options):
  17. handler(command_options)
  18. def parse(self, argv, global_options):
  19. options = docopt_full_help(getdoc(self), argv, **self.docopt_options())
  20. command = options['COMMAND']
  21. if command is None:
  22. raise SystemExit(getdoc(self))
  23. if not hasattr(self, command):
  24. raise NoSuchCommand(command, self)
  25. handler = getattr(self, command)
  26. docstring = getdoc(handler)
  27. if docstring is None:
  28. raise NoSuchCommand(command, self)
  29. command_options = docopt_full_help(docstring, options['ARGS'], options_first=True)
  30. return (options, command, handler, command_options)
  31. class NoSuchCommand(Exception):
  32. def __init__(self, command, supercommand):
  33. super(NoSuchCommand, self).__init__("No such command: %s" % command)
  34. self.command = command
  35. self.supercommand = supercommand