docopt_command.py 1.7 KB

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