144 lines · 4.5 KB · Python
RawDownload
"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, 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, 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 docstrings.has_key(name):                        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:"            names = docstrings.keys()            names.sort()            for name in names:                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()