"Framework for command line interfaces like CVS.  See class CmdFrameWork."


class CommandFrameWork:

    """Framework class for command line interfaces like CVS.

    The general command line structure is

            command [flags] subcommand [subflags] [argument] ...

    There's a class variable GlobalFlags which specifies the
    global flags options.  Subcommands are defined by defining
    methods named do_<subcommand>.  Flags for the subcommand are
    defined by defining class or instance variables named
    flags_<subcommand>.  If there's no command, method default()
    is called.  The __doc__ strings for the do_ methods are used
    for the usage message, printed after the general usage message
    which is the class variable UsageMessage.  The class variable
    PostUsageMessage is printed after all the do_ methods' __doc__
    strings.  The method's return value can be a suggested exit
    status.  [XXX Need to rewrite this to clarify it.]

    Common usage is to derive a class, instantiate it, and then call its
    run() method; by default this takes its arguments from sys.argv[1:].
    """

    UsageMessage = \
      "usage: (name)s [flags] subcommand [subflags] [argument] ..."

    PostUsageMessage = None

    GlobalFlags = ''

    def __init__(self):
        """Constructor, present for completeness."""
        pass

    def run(self, args = None):
        """Process flags, subcommand and options, then run it."""
        import getopt, sys
        if args is None: args = sys.argv[1:]
        try:
            opts, args = getopt.getopt(args, self.GlobalFlags)
        except getopt.error as msg:
            return self.usage(msg)
        self.options(opts)
        if not args:
            self.ready()
            return self.default()
        else:
            cmd = args[0]
            mname = 'do_' + cmd
            fname = 'flags_' + cmd
            try:
                method = getattr(self, mname)
            except AttributeError:
                return self.usage("command %r unknown" % (cmd,))
            try:
                flags = getattr(self, fname)
            except AttributeError:
                flags = ''
            try:
                opts, args = getopt.getopt(args[1:], flags)
            except getopt.error as msg:
                return self.usage(
                        "subcommand %s: " % cmd + str(msg))
            self.ready()
            return method(opts, args)

    def options(self, opts):
        """Process the options retrieved by getopt.
        Override this if you have any options."""
        if opts:
            print("-"*40)
            print("Options:")
            for o, a in opts:
                print('option', o, 'value', repr(a))
            print("-"*40)

    def ready(self):
        """Called just before calling the subcommand."""
        pass

    def usage(self, msg = None):
        """Print usage message.  Return suitable exit code (2)."""
        if msg: print(msg)
        print(self.UsageMessage % {'name': self.__class__.__name__})
        docstrings = {}
        c = self.__class__
        while 1:
            for name in dir(c):
                if name[:3] == 'do_':
                    if name in docstrings:
                        continue
                    try:
                        doc = getattr(c, name).__doc__
                    except:
                        doc = None
                    if doc:
                        docstrings[name] = doc
            if not c.__bases__:
                break
            c = c.__bases__[0]
        if docstrings:
            print("where subcommand can be:")
            for name in sorted(docstrings.keys()):
                print(docstrings[name])
        if self.PostUsageMessage:
            print(self.PostUsageMessage)
        return 2

    def default(self):
        """Default method, called when no subcommand is given.
        You should always override this."""
        print("Nobody expects the Spanish Inquisition!")


def test():
    """Test script -- called when this module is run as a script."""
    import sys
    class Hello(CommandFrameWork):
        def do_hello(self, opts, args):
            "hello -- print 'hello world', needs no arguments"
            print("Hello, world")
    x = Hello()
    tests = [
            [],
            ['hello'],
            ['spam'],
            ['-x'],
            ['hello', '-x'],
            None,
            ]
    for t in tests:
        print('-'*10, t, '-'*10)
        sts = x.run(t)
        print("Exit status:", repr(sts))


if __name__ == '__main__':
    test()
