Skip to content

Instantly share code, notes, and snippets.

@bewest
Created November 19, 2011 19:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bewest/1379221 to your computer and use it in GitHub Desktop.
Save bewest/1379221 to your computer and use it in GitHub Desktop.
cli-hello
Using pyCLI to create some commands and subcommands.
#!/usr/bin/python
from cli.log import LoggingApp
from pprint import pprint
"""
Very rough.
"""
class Subcommand(object):
name = ''
def __init__(self, handler):
self.session = handler
def options(self):
return [ ]
def setup(self, parser):
self.parser = parser
for args, kwds in self.options( ):
parser.add_argument(*args, **kwds)
def help(self):
return self.__doc__
def main(self, app):
pprint([self, app])
print self.name
class QuxApp(Subcommand):
"""Qux Does several special things"""
name = "qux"
class FuxApp(Subcommand):
"""Fux is accidently different."""
name = "fux"
class BuxApp(Subcommand):
"""Bux seems special, but it's a trick."""
name = "bux"
class BaxApp(Subcommand):
"""Bax seems special, bat it's a trick."""
name = "bax"
class FaxApp(Subcommand):
"""Fax is accidently different."""
name = "fax"
class QaxApp(Subcommand):
"""Qax Does several special things"""
name = "qax"
class Command(object):
"Fake help"
subcommands = { }
def __init__(self, name, subcommands=None):
self.subcommands = { }
self.name = name
if subcommands is not None:
for Flow in subcommands:
self.addFlow(Flow)
def __repr__(self):
return "%s:%s" % (self.name, type(self))
def subcommand_factory(self, Flow):
return Flow(self)
def addFlow(self, Flow):
flow = self.subcommand_factory(Flow)
self.subcommands[flow.name] = flow
def base(self, params):
pprint(self, params)
print "Without a subcommand!!"
def setup(self, parser):
n = self.name
self.parser = parser
pprint(['before', parser._positionals])
self.commands = parser.add_subparsers(dest='subcommand',
title="my commands title",
help=self.help( ),
prog="command")
pprint(['after', parser._positionals])
parser.set_defaults(run=self.base)
#p = self.commands.add_parser(None, help='basic help')
for flow in self.subcommands.values( ):
#flow = Flow( )
p = self.commands.add_parser(flow.name, help=flow.help())
flow.setup(p)
def help(self):
return self.__doc__
def main(self, app):
subcommand = self.subcommands[app.params.subcommand]
subcommand.main(self)
def get_commands():
devices = [ ]
a = Command('AAA', [ FuxApp, BuxApp ] )
b = Command('BBB', [ FaxApp, QaxApp, ] )
c = Command('CCC', [ FuxApp, BaxApp, QuxApp, BuxApp ] )
return [ a, b, c ]
class GlobalOptions(object):
def setup(self):
print "setting up global options"
class Application(LoggingApp, GlobalOptions):
"""Test Hello World
"""
name = "dispatcher"
commands = { }
def setup(self):
# just after wrapping argument during __call__
# !? or during __init__
super(Application, self).setup( )
GlobalOptions.setup(self)
self.add_param("bar", help="fake option", action='store_true')
self.subparsers = self.argparser.add_subparsers(dest='command', help='fake help on this command')
for dev in get_commands():
self.add_command( dev )
def pre_run(self):
# called just before main, updates params, parses args
super(Application, self).pre_run()
def add_command(self, command):
self.commands[command.name] = command
parser = self.subparsers.add_parser(command.name, help=command.help())
#parser.set_defaults(run=self.main)
command.setup(parser)
def main(self):
self.log.warn("hello world warn")
self.log.debug("hello world debug")
self.log.info("hello world info")
self.log.error("hello world error")
self.log.critical("hello world critical")
self.log.fatal("hello world fatal")
command = self.commands[self.params.command]
pprint(self.params)
command.main(self)
if __name__ == '__main__':
app = Application()
app.run( )
#####
# EOF
import sys
import commando
from pprint import pprint
__version__ = '0.0.1-dev'
class ParamGroup(commando.param):
__params__ = ( ('-d', '--debug'), dict(action='store_true' ) )
def __init__(self):
params = self.params( )
args, kwds = params[0], params[1]
self.values = commando.values._make( (args, kwds) )
def params(self):
return self.__params__
base_val = commando.values
class TaggedMemo(object):
subcommand = base_val._make(((), dict()))
commando = True
params = [ ]
def __init__(self, name=None):
default = base_val._make(((name, ), dict( )))
self.subcommand = getattr(self.main, 'subcommand', default)
self.params = [ ]
def __call__(self, app, params):
self.main(params)
def main(self, params):
print "I'm an unsubclassed Command"
pprint([self, params])
class DemoRecurse(TaggedMemo):
@commando.subcommand('far', help='demo far recurse')
def main(self, params):
print "used decorator on a subclass"
class FooBar(object):
@commando.subcommand('one', help="one")
def one(self, app, params):
print "one"
@commando.subcommand('two', help="two")
def two(self, app, params):
print "two"
#@commando.command(description="my command description")
@commando.subcommand('far', help='demo far recurse')
def main(self, app, params):
print "used decorator on a subclass"
class Root(object):
@commando.command(description="my command description")
@commando.param('-v', '--version', action='version',
version='%(prog)s ' + __version__)
@commando.param('-foo', dest='foo', action='store', type=str)
@commando.subcommand('init', help="main command")
@ParamGroup( )
def main(self, app, params):
pprint([self, params])
@commando.subcommand('foo', help="foo command")
def foo(self, app, params):
pprint([self, params])
foo.branch = True
foo.baz = FooBar( )
foo.branches = [ 'baz' ]
#bar = FooBar( )
#bar.branch = True
#branch = True
#branches = [ 'bar' ]
#bar.branch = True
#bar.branches = ['qux', 'faz']
#bar.qux = TaggedMemo('qux')
#bar.qux.commando = True
#bar.faz = DemoRecurse( )
#bar.faz.commando = True
class Application(Root, commando.WeirdApp):
__subcommands__ = [ FooBar( ), DemoRecurse('demo') ]
def __init__(self):
super(Application, self).__init__()
pass
def main( ):
#app = Application( )
#app.run( )
tree = commando.TreeApp(root=Root( ))
tree.run( )
if __name__ == '__main__':
main( )
#####
# EOF
#!/usr/bin/python
"""
Simple app using argparse.
How can I provide a bunch of subcommands, but make one of them a default?
"""
from pprint import pprint
import argparse
import logging
log = logging.getLogger(__name__)
class F(object):
def __init__(self, name):
self.name = name
def main(self, app, params):
pprint([ self.name, self, params ])
print "Hello, I'm %s." % self.name
class Simple(object):
"""
This is a very simple description.
We'll simulate it very long here.
Very long indeed.
"""
def __init__(self):
desc = type(self).__doc__
self.parser = argparse.ArgumentParser(description=desc)
self.parser.add_argument('-d', '--debug', action='store_true')
# dest, title, help, description
desc = """This is a long description on a simple command."""
self.setup_a(self.parser)
def setup_a(self, parser, name='lalala'):
desc = """This is a long description on a simple command."""
subparsers = parser.add_subparsers(title='Title Group A',
dest='command',
default='qux',
description = desc,
help='some help on group A')
for x in [ 'qux', 'fux', 'bux', 'lux' ]:
f = F(x)
kwds = dict( description = "long desc of %s" % x,
)
# default= 'qux')
p = subparsers.add_parser(x, **kwds)
p.set_defaults(run=f.main)
def parse(self, argv):
return self.parser.parse_args(argv)
def run(self, args=None):
if args is None:
import sys
args = self.parse(sys.argv[1:])
if hasattr(args, 'run'):
args.run(self, args)
else:
self.main(args)
def main(self, app, params):
log.warn("hello world warn")
log.debug("hello world debug")
log.info("hello world info")
log.error("hello world error")
log.critical("hello world critical")
log.fatal("hello world fatal")
pprint(params)
print "default"
if __name__ == '__main__':
app = Simple()
app.run( )
#####
# EOF
#!/usr/bin/python
import unittest
import argparse
from pprint import pprint
class F(object):
def __init__(self, name):
self.name = name
def main(self, app, params):
pprint([ self.name, self, params ])
print "Hello, I'm %s." % self.name
def get_simple_parser( ):
parser = argparse.ArgumentParser()
# flesh it out a bit with a no-op option
parser.add_argument('-d', '--debug', action='store_true')
return parser
class TestSubparserDefaultFun(unittest.TestCase):
def setUp(self):
self.parser = get_simple_parser( )
setup_a(self.parser)
def parse_missing_subcommand_args(self):
pprint(parser.parse_args(prep('')))
def donttest_required_subcommand_behavior(self):
self.parser.parse_args( )
def test_optional_subcommand_behavior(self):
self.parser.parse_args(prep(' '))
def setup_a(parser, name='lalala'):
desc = """This is a long description on a simple command."""
# goal, make qux the default
# default = 'qux'
kwds = dict( title='Title Group A',
dest='command',
description = desc,
prog= "my program",
# XXX: PATCH
default = 'qux',
help='some help on group A')
subparsers = parser.add_subparsers(**kwds)
for x in [ 'qux', 'fux', 'bux', 'lux' ]:
f = F(x)
kwds = dict( description = "long desc of %s" % x,
)
# default= 'qux')
p = subparsers.add_parser(x, **kwds)
p.set_defaults(run=f.main)
def prep(args):
return args.split( )
def main( ):
parser = get_simple_parser( )
#sub = parser.add_subparsers()
#sub.add_parser("info")
#parser.add_argument("paths", "+")
#pprint(parser.parse_args(["foo", "bar"]))
# add some subcommands
setup_a(parser)
#
pprint(parser.parse_args(prep('')))
pprint(parser.parse_args(prep('')))
if __name__ == '__main__':
unittest.main( )
#####
# EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment