def test_boolean_true(self): """ Passing in --option results in option being true """ simple = caparg.command( '', caparg.command('eat', alot=caparg.option(type=bool))) self.assertTrue(simple.parse(['eat', '--alot'])['alot'])
def test_no_command(self): """ If no subcommand is given, ParseError is raised """ simple = caparg.command('', caparg.command('eat')) with self.assertRaises(caparg.ParseError): simple.parse(['drink'])
def test_boolean_false(self): """ Not passing in --option results in option being false """ simple = caparg.command( '', caparg.command('eat', alot=caparg.option(type=bool))) self.assertFalse(simple.parse(['eat'])['alot'])
def test_optional(self): """ Not passing in an optional argument causes nothing to be in the return """ simple = caparg.command( '', caparg.command('eat', what=caparg.option(type=str))) parsed = dict(simple.parse(['eat'])) self.assertEqual(list(parsed.pop('__caparg_subcommand__')), ['eat']) self.assertEqual(parsed, {})
def test_evolution(self): """ You can evolve a command to a different name """ eat = caparg.command('eat') drink = eat.rename('drink') simple = caparg.command('', drink) parsed = dict(simple.parse(['drink'])) self.assertEqual(list(parsed.pop('__caparg_subcommand__')), ['drink']) self.assertEqual(parsed, {})
def test_simple(self): """ Parsing a subcommand with one positional returns subcommand and positional """ simple = caparg.command( '', caparg.command('drink', caparg.positional('what', type=str))) parsed = dict(simple.parse(['drink', 'something'])) self.assertEqual(parsed.pop('what'), 'something') self.assertEqual(list(parsed.pop('__caparg_subcommand__')), ['drink']) self.assertEqual(parsed, {})
def test_inherit(self): """ Subcommands inherit options from parents and grandparents """ simple = caparg.command('', caparg.options(where=caparg.option(type=str)), caparg.command('eat', caparg.command('lunch'))) parsed = dict(simple.parse(['eat', 'lunch', '--where', 'cafe'])) self.assertEqual(list(parsed.pop('__caparg_subcommand__')), ['eat', 'lunch']) self.assertEqual(parsed.pop('where'), 'cafe') self.assertEqual(parsed, {})
def run(self, args, override_dependencies=pyrsistent.m()): """ Run a command """ collection = self.get_commands() subcommands = [ thing.extra.parser.rename(name) for name, thing in collection.items() ] command = caparg.command('', *subcommands) parsed = command.parse(args) subcommand = ' '.join(parsed['__caparg_subcommand__']) func = collection[subcommand].original extra = collection[subcommand].extra graph = self.mkgraph(extra.dependencies) graph.update(override_dependencies) if not extra.regular: return func(parsed, graph) args = { dependency: graph[dependency] for dependency in extra.dependencies } args.update(parsed) del args['__caparg_subcommand__'] return func(**args)
class ExtraData(object): """ Metadata about commands """ parser = attr.ib(default=caparg.command('')) dependencies = attr.ib(default=pyrsistent.v()) aliases = attr.ib(default=pyrsistent.v()) regular = attr.ib(default=False)
Return a function to display things on the terminal. """ return print @COMMANDS.dependency(name='output') def dummy_output(_dependencies, _possible_dependencies): """ Literally do nothing. This is designed for being overridden. """ @COMMANDS.command(dependencies=['foo', 'output'], parser=ca.command('', ca.positional('lili', type=str)), regular=True) def regular_command(foo, lili, output): """ Use regular arguments Output results """ output(foo, lili) @COMMANDS.command(dependencies=['foo', 'print'], aliases=['view'], parser=ca.command('', ca.positional('lala', type=str))) def show(args, dependencies): """
return os.environ @COMMANDS.dependency(dependencies=['environment', 'current_directory']) def secret_filename(dependencies, _maybedeps): """ The filename to put the encrypted secrets in. """ if 'VOYNICH_FILE' in dependencies['environment']: return dependencies['environment']['VOYNICH_FILE'] return os.path.join(dependencies['current_directory'], 'voynich.json') @COMMANDS.command(dependencies=['secret_filename'], parser=ca.command('', key_file=ca.option(type=str, required=True))) def create(args, dependencies): """ Create a new secrets file (and save the private key). """ sys.stdout.write("writing key to {} and public data to {}\n".format( args.key_file, dependencies['secret_filename'])) @COMMANDS.command(dependencies=['secret_filename'], parser=ca.command('', name=ca.option(type=str, required=True), value=ca.option(type=str, required=True))) def encrypt(args, dependencies):
""" Demonstration of middlefield plugins """ from __future__ import print_function import typing from caparg import command, option import middlefield @middlefield.COMMANDS.command(parser=command('', what=option(type=typing.List[str], have_default=True)), dependencies=['echo_printer']) def echo(args, dependencies): """ Print out arguments """ dependencies['echo_printer'](*args['what']) @middlefield.COMMANDS.dependency() def echo_printer(_dependencies, _maybe_dependencies): """ Define what printing means """ return print
@contextlib.contextmanager def tmpdir(): """ Context manager creating a temporary directory """ ret = tempfile.mkdtemp() try: yield ret finally: shutil.rmtree(ret) @COMMANDS.command(parser=command('', requirements=option(type=typing.List[str], have_default=True), package=option(type=typing.List[str], have_default=True), shebang=option(type=str), output=option(type=str, required=True)), dependencies=['executor', 'pex_builder'], aliases=['self build']) def self_build(args, dependencies): """ Build middlefield, together with any plugins, into a Pex file """ package = list(args['package']) my_version = _version.__version__.short() package.append('middlefield=={}'.format(my_version)) requirements = list(args['requirements']) output = args['output'] xctor = dependencies['executor']
PARSER = command( '', # These are common options. # They will be inherited by all sub-commands. options( messages=option(type=str, required=True), config=option(type=str, required=True), ), # This is a subcommand, "add" # It takes a bewildering array of options! command('add', name=option(type=str, required=True), cmd=option(type=str, required=True), arg=option(type=typing.List[str], have_default=True), env=option(type=typing.Dict[str, str], have_default=True), uid=option(type=int), gid=option(type=int), extras=option(type=str)), # This is a subcommand, "remove" # It takes one option command('remove', name=option(type=str, required=True)), # This is a subcommand, "restart" # It takes one option command('restart', name=option(type=str, required=True)), # This is a subcommand, "restart-all" # It takes no options. command('restart-all'), # This is a subcommand, "remote". # It can be called directly... command( 'remote', options(verbose=option(type=bool)), # ...or with a sub-subcommand 'remove' command('remove', positional(name='name', type=str))), # It is also possible to put sub-sub-commands at the top-level. # In that case, they are separated with whitespace. command('remote add', positional(name='name', type=str), positional(name='url', type=str)))