docopt_command.py 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  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, command, 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. if not hasattr(self, command):
  26. raise NoSuchCommand(command, self)
  27. handler = getattr(self, command)
  28. docstring = getdoc(handler)
  29. if docstring is None:
  30. raise NoSuchCommand(command, self)
  31. command_options = docopt_full_help(docstring, options['ARGS'], options_first=True)
  32. return (options, command, handler, command_options)
  33. class NoSuchCommand(Exception):
  34. def __init__(self, command, supercommand):
  35. super(NoSuchCommand, self).__init__("No such command: %s" % command)
  36. self.command = command
  37. self.supercommand = supercommand