-
-
Save szaydel/4060444 to your computer and use it in GitHub Desktop.
Using pyCLI to create some commands and subcommands.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Using pyCLI to create some commands and subcommands. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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