docopt_command.py 1.6 KB

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