def register_cli_commands(parser): """Register the CLI's meta-subcommands on `parser`.""" for name, command in commands.items(): help_title, help_body = parse_docstring(command) command_parser = parser.subparsers.add_parser( safe_name(name), help=help_title, description=help_title, epilog=help_body) command_parser.set_defaults(execute=command(command_parser)) # Setup the snap commands into the maascli if in a snap and command exists. if 'SNAP' in os.environ: # Only import snappy if running under the snap. from maascli import snappy for name, command in [ ('init', snappy.cmd_init), ('config', snappy.cmd_config), ('status', snappy.cmd_status), ('migrate', snappy.cmd_migrate)]: help_title, help_body = parse_docstring(command) command_parser = parser.subparsers.add_parser( safe_name(name), help=help_title, description=help_title, epilog=help_body) command_parser.set_defaults(execute=command(command_parser)) # Setup and the allowed django commands into the maascli. management = get_django_management() if management is not None and is_maasserver_available(): os.environ.setdefault( "DJANGO_SETTINGS_MODULE", "maasserver.djangosettings.settings") from django import setup as django_setup django_setup() load_regiond_commands(management, parser)
def register_cli_commands(parser): """Register the CLI's meta-subcommands on `parser`.""" for name, command in commands.items(): help_title, help_body = parse_docstring(command) command_parser = parser.subparsers.add_parser( safe_name(name), help=help_title, description=help_title, epilog=help_body) command_parser.set_defaults(execute=command(command_parser))
def register_cli_commands(parser): """Register the CLI's meta-subcommands on `parser`.""" for name, command in commands.items(): help_title, help_body = parse_docstring(command) command_parser = parser.subparsers.add_parser(safe_name(name), help=help_title, description=help_title, epilog=help_body) command_parser.set_defaults(execute=command(command_parser))
def get_action_class(handler, action): """Return custom action handler class.""" handler_name = handler_command_name(handler["name"]).replace('-', '_') action_name = '%s_%s' % (handler_name, safe_name(action["name"]).replace( '-', '_')) action_module = try_import_module('maascli.actions.%s' % action_name) if action_module is not None: return action_module.action_class return None
def load_regiond_commands(management, parser): """Load the allowed regiond commands into the MAAS cli.""" for name, app, help_text in regiond_commands: klass = management.load_command_class(app, name) if help_text is None: help_text = klass.help command_parser = parser.subparsers.add_parser( safe_name(name), help=help_text, description=help_text) klass.add_arguments(command_parser) command_parser.set_defaults( execute=partial(run_regiond_command, management))
def add_command(name, command): help_title, help_body = parse_docstring(command) arg_name = safe_name(name) if command.hidden: command_parser = parser.subparsers.add_parser(arg_name) else: command_parser = parser.subparsers.add_parser( arg_name, help=help_title, description=help_title, epilog=help_body, ) command_parser.set_defaults(execute=command(command_parser))
def test_safe_name(self): # safe_name attempts to discriminate parts of a vaguely camel-cased # string, and rejoins them using a hyphen. expected = { "NodeHandler": "Node-Handler", "SpadeDiggingHandler": "Spade-Digging-Handler", "SPADE_Digging_Handler": "SPADE-Digging-Handler", "SpadeHandlerForDigging": "Spade-Handler-For-Digging", "JamesBond007": "James-Bond007", "JamesBOND": "James-BOND", "James-BOND-007": "James-BOND-007", } observed = {name_in: utils.safe_name(name_in) for name_in in expected} self.assertItemsEqual(expected.items(), observed.items())
def register_actions(profile, handler, parser): """Register a handler's actions.""" for action in handler["actions"]: help_title, help_body = parse_docstring(action["doc"]) action_name = safe_name(action["name"]).encode("ascii") action_bases = (Action,) action_ns = { "action": action, "handler": handler, "profile": profile, } action_class = type(action_name, action_bases, action_ns) action_parser = parser.subparsers.add_parser( action_name, help=help_title, description=help_title, epilog=help_body) action_parser.set_defaults( execute=action_class(action_parser))
def register_actions(profile, handler, parser): """Register a handler's actions.""" for action in handler["actions"]: help_title, help_body = parse_docstring(action["doc"]) action_name = safe_name(action["name"]).encode("ascii") action_bases = (Action, ) action_ns = { "action": action, "handler": handler, "profile": profile, } action_class = type(action_name, action_bases, action_ns) action_parser = parser.subparsers.add_parser(action_name, help=help_title, description=help_title, epilog=help_body) action_parser.set_defaults(execute=action_class(action_parser))
def test_safe_name(self): # safe_name attempts to discriminate parts of a vaguely camel-cased # string, and rejoins them using a hyphen. expected = { "NodeHandler": "Node-Handler", "SpadeDiggingHandler": "Spade-Digging-Handler", "SPADE_Digging_Handler": "SPADE-Digging-Handler", "SpadeHandlerForDigging": "Spade-Handler-For-Digging", "JamesBond007": "James-Bond007", "JamesBOND": "James-BOND", "James-BOND-007": "James-BOND-007", } observed = { name_in: utils.safe_name(name_in) for name_in in expected } self.assertItemsEqual( expected.items(), observed.items())
def register_actions(profile, handler, parser): """Register a handler's actions.""" for action in handler["actions"]: help_title, help_body = parse_docstring(action["doc"]) action_name = safe_name(action["name"]) action_bases = get_action_class_bases(handler, action) action_ns = { "action": action, "handler": handler, "profile": profile, } action_class = type(action_name, action_bases, action_ns) action_parser = parser.subparsers.add_parser( action_name, help=help_title, description=help_title, epilog=help_body, add_help=False) action_parser.add_argument( '--help', '-h', action=ActionHelp, nargs=0, help="Show this help message and exit.") action_parser.set_defaults(execute=action_class(action_parser))
def test_handlers_registered_using_correct_names(self): profile = self.make_profile() parser = ArgumentParser() api.register_api_commands(parser) for resource in list(profile.values())[0]["description"]["resources"]: for action in resource["auth"]["actions"]: # Profile names are matched as-is. [profile_name] = profile # Handler names are processed with handler_command_name before # being added to the argument parser tree. handler_name = handler_command_name(resource["name"]) # Action names are processed with safe_name before being added # to the argument parser tree. action_name = safe_name(action["name"]) # Parsing these names as command-line arguments yields an # options object. Its execute attribute is an instance of # Action (or a subclass thereof). options = parser.parse_args( (profile_name, handler_name, action_name)) self.assertIsInstance(options.execute, api.Action)
def test_handlers_registered_using_correct_names(self): profile = self.make_profile() parser = ArgumentParser() api.register_api_commands(parser) for resource in profile.values()[0]["description"]["resources"]: for action in resource["auth"]["actions"]: # Profile names are matched as-is. profile_name = profile.keys()[0] # Handler names are processed with handler_command_name before # being added to the argument parser tree. handler_name = handler_command_name(resource["name"]) # Action names are processed with safe_name before being added # to the argument parser tree. action_name = safe_name(action["name"]) # Parsing these names as command-line arguments yields an # options object. Its execute attribute is an instance of # Action (or a subclass thereof). options = parser.parse_args( (profile_name, handler_name, action_name)) self.assertIsInstance(options.execute, api.Action)
def test_safe_name_non_ASCII(self): # safe_name will not break if passed a string with non-ASCII # characters. However, those characters will not be present in the # returned name. self.assertEqual("a-b-c", utils.safe_name("a\u1234_b\u5432_c\u9876"))
def test_safe_name_string_type(self): # Given a unicode string, safe_name will always return a unicode # string, and given a byte string it will always return a byte string. self.assertIsInstance(utils.safe_name(u"fred"), unicode) self.assertIsInstance(utils.safe_name(b"fred"), bytes)
def test_safe_name_non_ASCII(self): # safe_name will not break if passed a string with non-ASCII # characters. However, those characters will not be present in the # returned name. self.assertEqual( "a-b-c", utils.safe_name(u"a\u1234_b\u5432_c\u9876"))