def test_cli_exapp1(self): def a_test_command_handler(_): return [{'a': 1, 'b': 1234}, {'a': 3, 'b': 4}] class MyCommandsLoader(CLICommandsLoader): def load_command_table(self, args): self.command_table['abc xyz'] = CLICommand( self.cli_ctx, 'abc xyz', a_test_command_handler) self.command_table['abc list'] = CLICommand( self.cli_ctx, 'abc list', a_test_command_handler) return OrderedDict(self.command_table) mycli = CLI(cli_name='exapp1', config_dir=os.path.expanduser(os.path.join('~', '.exapp1')), commands_loader_cls=MyCommandsLoader) expected_output = """[ { "a": 1, "b": 1234 }, { "a": 3, "b": 4 } ] """ mock_stdout = StringIO() exit_code = mycli.invoke(['abc', 'xyz'], out_file=mock_stdout) self.assertEqual(expected_output, mock_stdout.getvalue()) self.assertEqual(0, exit_code) mock_stdout = StringIO() mycli.invoke(['abc', 'list'], out_file=mock_stdout) self.assertEqual(expected_output, mock_stdout.getvalue()) self.assertEqual(0, exit_code) expected_output = """{ "a": 1, "b": 1234 } """ mock_stdout = StringIO() mycli.invoke(['abc', 'list', '--query', '[0]'], out_file=mock_stdout) self.assertEqual(expected_output, mock_stdout.getvalue()) self.assertEqual(0, exit_code) expected_output = "1\n" mock_stdout = StringIO() mycli.invoke(['abc', 'list', '--query', '[0].a'], out_file=mock_stdout) self.assertEqual(expected_output, mock_stdout.getvalue()) self.assertEqual(0, exit_code)
def cli(): """Create CLI environment""" return CLI(cli_name=SF_CLI_NAME, config_dir=SF_CLI_CONFIG_DIR, config_env_var_prefix=SF_CLI_ENV_VAR_PREFIX, commands_loader_cls=SFCommandLoader, help_cls=SFCommandHelp)
def invoke(self, args, initial_invocation_data=None, out_file=None): self.args = args self.register_event(event_name=EVENT_CLI_PRE_EXECUTE, handler=self.pre_execute) self.register_event(event_name=EVENT_CLI_POST_EXECUTE, handler=self.post_execute) return CLI.invoke(self, args, initial_invocation_data, out_file)
def invoke(self, args, initial_invocation_data=None, out_file=None): self.args = args self.register_event(event_name=EVENT_INVOKER_POST_PARSE_ARGS, handler=self.post_parse_args) self.register_event(event_name=EVENT_CLI_POST_EXECUTE, handler=self.post_execute) return CLI.invoke(self, args, initial_invocation_data, out_file)
def cli(): return CLI( cli_name=COMMAND_NAME, config_dir=COMMAND_SETTINGS_DIR, config_env_var_prefix=COMMAND_ENV_PREFIX, invocation_cls=EgorInvoker, commands_loader_cls=EgorCommandLoader, help_cls=EgorCommandHelp )
def main(): mycli = CLI(cli_name='upnp', commands_loader_cls=CommandsLoader) exit_code = mycli.invoke(sys.argv[1:])
results = stub.Apply(request) print(MessageToJson(results)) class CommandsLoader(CLICommandsLoader): def load_command_table(self, args): with CommandGroup(self, '', '__main__#{}') as g: g.command('serve', 'serve_command_handler', confirmation=False), g.command('analyze', 'analyze_command_handler', confirmation=False) return super(CommandsLoader, self).load_command_table(args) def load_arguments(self, command): with ArgumentsContext(self, 'serve') as ac: ac.argument('env_grpc_port', default=False, required=False) ac.argument('grpc_port', default=3001, type=int, required=False) with ArgumentsContext(self, 'analyze') as ac: ac.argument('env_grpc_port', default=False, required=False) ac.argument('grpc_port', default=3001, type=int, required=False) ac.argument('text', required=True) ac.argument('fields', nargs='*', required=True) super(CommandsLoader, self).load_arguments(command) presidio_cli = CLI(cli_name=cli_name, config_dir=os.path.join('~', '.{}'.format(cli_name)), config_env_var_prefix=cli_name, commands_loader_cls=CommandsLoader, help_cls=PresidioCLIHelp) exit_code = presidio_cli.invoke(sys.argv[1:]) sys.exit(exit_code)
|_| |___/ """ class CommandLoader(CLICommandsLoader): def load_command_table(self, args): with CommandGroup(self, "proxy", "aproxy.proxy#{}") as g: g.command("single", "start_single_proxy") g.command("start", "start_from_config") return super(CommandLoader, self).load_command_table(args) def load_arguments(self, command): with ArgumentsContext(self, "proxy single") as ac: ac.argument("local_port", type=int) ac.argument("remote_port", type=int) return super(CommandLoader, self).load_arguments(command) name = "aproxy" cli = CLI( cli_name=name, config_dir=os.path.expanduser(os.path.join("~", ".{}".format(name))), config_env_var_prefix=name, commands_loader_cls=CommandLoader, ) signal.signal(signal.SIGINT, signal_handler) exit_code = cli.invoke(sys.argv[1:]) sys.exit(exit_code)
def make_rst(self): INDENT = ' ' DOUBLEINDENT = INDENT * 2 # similar to what the Application object provides for in "az" cli_name = "vsts" vsts_cli = CLI(cli_name=cli_name, config_dir=os.path.join('~', '.{}'.format(cli_name)), config_env_var_prefix=cli_name, commands_loader_cls=VstsCommandsLoader, help_cls=VstsCLIHelp) help_files = get_help_files(vsts_cli) doc_source_map = _load_doc_source_map() for help_file in help_files: is_command = isinstance(help_file, CommandHelpFile) yield '.. cli{}:: {}'.format( 'command' if is_command else 'group', help_file.command if help_file.command else 'vsts') #it is top level group az if command is empty yield '' yield '{}:summary: {}'.format(INDENT, help_file.short_summary) yield '{}:description: {}'.format(INDENT, help_file.long_summary) if help_file.deprecate_info: yield '{}:deprecated: {}'.format( INDENT, help_file.deprecate_info._get_message( help_file.deprecate_info)) if not is_command: top_group_name = help_file.command.split( )[0] if help_file.command else 'vsts' yield '{}:docsource: {}'.format( INDENT, doc_source_map[top_group_name] if top_group_name in doc_source_map else '') else: top_command_name = help_file.command.split( )[0] if help_file.command else '' if top_command_name in doc_source_map: yield '{}:docsource: {}'.format( INDENT, doc_source_map[top_command_name]) yield '' if is_command and help_file.parameters: group_registry = ArgumentGroupRegistry([ p.group_name for p in help_file.parameters if p.group_name ]) for arg in sorted( help_file.parameters, key=lambda p: group_registry.get_group_priority( p.group_name) + str(not p.required) + p.name): yield '{}.. cliarg:: {}'.format(INDENT, arg.name) yield '' yield '{}:required: {}'.format(DOUBLEINDENT, arg.required) if arg.deprecate_info: yield '{}:deprecated: {}'.format( DOUBLEINDENT, arg.deprecate_info._get_message( arg.deprecate_info)) short_summary = arg.short_summary or '' possible_values_index = short_summary.find( ' Possible values include') short_summary = short_summary[ 0:possible_values_index if possible_values_index >= 0 else len(short_summary)] short_summary = short_summary.strip() yield '{}:summary: {}'.format(DOUBLEINDENT, short_summary) yield '{}:description: {}'.format(DOUBLEINDENT, arg.long_summary) if arg.choices: yield '{}:values: {}'.format( DOUBLEINDENT, ', '.join(sorted([str(x) for x in arg.choices]))) if arg.default and arg.default != argparse.SUPPRESS: try: if arg.default.startswith(USER_HOME): arg.default = arg.default.replace( USER_HOME, '~').replace('\\', '/') except Exception: pass try: arg.default = arg.default.replace("\\", "\\\\") except Exception: pass yield '{}:default: {}'.format(DOUBLEINDENT, arg.default) if arg.value_sources: yield '{}:source: {}'.format( DOUBLEINDENT, ', '.join(arg.value_sources)) yield '' yield '' if len(help_file.examples) > 0: for e in help_file.examples: yield '{}.. cliexample:: {}'.format(INDENT, e.name) yield '' yield DOUBLEINDENT + e.text.replace("\\", "\\\\") yield ''
import json import re import sys import os from knack import CLI from vsts.cli.vsts_cli_help import VstsCLIHelp from vsts.cli.vsts_commands_loader import VstsCommandsLoader # ignore the params passed in now so they aren't used by the cli sys.argv = sys.argv[:1] cli_name = "vsts" vstscli = CLI(cli_name=cli_name, config_dir=os.path.join('~', '.{}'.format(cli_name)), config_env_var_prefix=cli_name, commands_loader_cls=VstsCommandsLoader, help_cls=VstsCLIHelp) loader = vstscli.commands_loader_cls() loader.__init__(vstscli) cmd_table = loader.load_command_table([]) for command in loader.command_table: loader.load_arguments(command) vstsclihelp = vstscli.help_cls(cli_ctx=vstscli) global_parser = vstscli.parser_cls.create_global_parser(cli_ctx=vstscli) parser = vstscli.parser_cls(cli_ctx=vstscli, prog=vstscli.name, parents=[global_parser])
type=str, required=False) ac.argument("max_workers", default=10, type=int, required=False) with ArgumentsContext(self, "analyze") as ac: ac.argument("env_grpc_port", default=False, required=False) ac.argument("grpc_port", default=3001, type=int, required=False) ac.argument("text", required=True) ac.argument("fields", nargs="*", required=True) logger.info(f"cli commands: {command}") super(CommandsLoader, self).load_arguments(command) def get_config_dir(cli_name): basedir = os.environ.get("XDG_CONFIG_HOME", "~") if basedir == "~": cli_name = "." + cli_name basedir = os.path.expanduser(basedir) return os.path.join(basedir, cli_name) if __name__ == "__main__": presidio_cli = CLI( cli_name=CLI_NAME, config_dir=get_config_dir(CLI_NAME), config_env_var_prefix=CLI_NAME, commands_loader_cls=CommandsLoader, help_cls=PresidioCLIHelp, ) exit_code = presidio_cli.invoke(sys.argv[1:]) sys.exit(exit_code)
return str(o) parser = argparse.ArgumentParser(description='Command Table Parser') parser.add_argument('--commands', metavar='N', nargs='+', help='Filter by first level command (OR)') parser.add_argument('--params', metavar='N', nargs='+', help='Filter by parameters (OR)') args = parser.parse_args() cmd_set_names = args.commands param_names = args.params # ignore the params passed in now so they aren't used by the cli sys.argv = sys.argv[:1] cli_name = "vsts" vstscli = CLI(cli_name=cli_name, config_dir=os.path.join('~', '.{}'.format(cli_name)), config_env_var_prefix=cli_name, commands_loader_cls=VstsCommandsLoader, help_cls=VstsCLIHelp) loader = vstscli.commands_loader_cls() loader.__init__(vstscli) loader.load_command_table([]) for command in loader.command_table: loader.load_arguments(command) cmd_table = loader.load_command_table([]) cmd_list = [cmd_name for cmd_name in cmd_table.keys() if cmd_set_names is None or cmd_name.split()[0] in cmd_set_names] results = [] if param_names: for name in cmd_list:
def make_rst(self): INDENT = ' ' DOUBLEINDENT = INDENT * 2 parser_keys = [] parser_values = [] sub_parser_keys = [] sub_parser_values = [] # similar to what the Application object provides for in "az" cli_name = "vsts" vstscli = CLI(cli_name=cli_name, config_dir=os.path.join('~', '.{}'.format(cli_name)), config_env_var_prefix=cli_name, commands_loader_cls=VstsCommandsLoader, help_cls=VstsCLIHelp) loader = vstscli.commands_loader_cls() loader.__init__(vstscli) loader.load_command_table([]) for command in loader.command_table: loader.load_arguments(command) vstsclihelp = vstscli.help_cls(cli_ctx=vstscli) global_parser = vstscli.parser_cls.create_global_parser( cli_ctx=vstscli) parser = vstscli.parser_cls(cli_ctx=vstscli, prog=vstscli.name, parents=[global_parser]) parser.load_command_table(loader.command_table) _store_parsers(parser, parser_keys, parser_values, sub_parser_keys, sub_parser_values) for cmd, parser in zip(parser_keys, parser_values): if cmd not in sub_parser_keys: sub_parser_keys.append(cmd) sub_parser_values.append(parser) doc_source_map = _load_doc_source_map() help_files = [] for cmd, parser in zip(sub_parser_keys, sub_parser_values): try: help_file = _help.GroupHelpFile(cmd, parser) if _is_group( parser) else _help.CommandHelpFile(cmd, parser) help_file.load(parser) help_files.append(help_file) except Exception as ex: print("Skipped '{}' due to '{}'".format(cmd, ex)) help_files = sorted(help_files, key=lambda x: x.command) for help_file in help_files: is_command = isinstance(help_file, _help.CommandHelpFile) yield '.. cli{}:: {}'.format( 'command' if is_command else 'group', help_file.command if help_file.command else 'vsts') #it is top level group vsts if command is empty yield '' yield '{}:summary: {}'.format(INDENT, help_file.short_summary) yield '{}:description: {}'.format(INDENT, help_file.long_summary) if not is_command: top_group_name = help_file.command.split( )[0] if help_file.command else 'vsts' yield '{}:docsource: {}'.format( INDENT, doc_source_map[top_group_name] if top_group_name in doc_source_map else '') else: top_command_name = help_file.command.split( )[0] if help_file.command else '' if top_command_name in doc_source_map: yield '{}:docsource: {}'.format( INDENT, doc_source_map[top_command_name]) yield '' if is_command and help_file.parameters: group_registry = _help.ArgumentGroupRegistry([ p.group_name for p in help_file.parameters if p.group_name ]) for arg in sorted( help_file.parameters, key=lambda p: group_registry.get_group_priority( p.group_name) + str(not p.required) + p.name): yield '{}.. cliarg:: {}'.format(INDENT, arg.name) yield '' yield '{}:required: {}'.format(DOUBLEINDENT, arg.required) short_summary = arg.short_summary or '' possible_values_index = short_summary.find( ' Possible values include') short_summary = short_summary[ 0:possible_values_index if possible_values_index >= 0 else len(short_summary)] short_summary = short_summary.strip() yield '{}:summary: {}'.format(DOUBLEINDENT, short_summary) yield '{}:description: {}'.format(DOUBLEINDENT, arg.long_summary) if arg.choices: yield '{}:values: {}'.format( DOUBLEINDENT, ', '.join(sorted([str(x) for x in arg.choices]))) if arg.default and arg.default != argparse.SUPPRESS: yield '{}:default: {}'.format(DOUBLEINDENT, arg.default) if arg.value_sources: yield '{}:source: {}'.format( DOUBLEINDENT, ', '.join(arg.value_sources)) yield '' yield '' if len(help_file.examples) > 0: for e in help_file.examples: yield '{}.. cliexample:: {}'.format(INDENT, e.name) yield '' yield DOUBLEINDENT + e.text yield ''