def test_get_first_line_doc(): def single_line_doc(): """Single line.""" assert get_first_line_doc(single_line_doc) == 'Single line' def multi_line_doc(): # noqa: D400 """ First line. Second line. """ assert get_first_line_doc(multi_line_doc) == 'First line' def no_doc(): pass # pragma: no cover assert get_first_line_doc(no_doc) == '' def whitespace_doc(): """ """ assert get_first_line_doc(whitespace_doc) == '' def empty_lines_doc(): """ """ assert get_first_line_doc(empty_lines_doc) == ''
def add_subparsers(parser, cmd_name, verb_extensions, *, attribute): """ Create argparse subparsers for each verb. The `cmd_name` is used for the title and description of the `add_subparsers` function call. For each verb extension a subparser is created. If the extension has an `add_arguments` method it is being called with the subparser being passed as the only argument. :param parser: The argument parser for this command :param str cmd_name: The name of the command to which the verbs are being added :param dict verb_extensions: The verb extensions indexed by the verb name :returns: The subparsers indexed by the verb name :rtype: dict """ global colcon_logger assert verb_extensions, 'No verb extensions' # list of available verbs with their descriptions verbs = [] for name, extension in verb_extensions.items(): verbs += _format_pair( name, get_first_line_doc(extension), indent=0, align=22) # add subparser with description of verb extensions subparser = parser.add_subparsers( title='{cmd_name} verbs'.format_map(locals()), description='\n'.join(verbs), dest=attribute, help='call `{cmd_name} VERB -h` for specific help' .format_map(locals()) ) # add verb specific group and arguments for name, extension in verb_extensions.items(): verb_parser = subparser.add_parser( getattr(extension, attribute.upper()), description=get_first_line_doc(extension) + '.', formatter_class=parser.formatter_class, ) verb_parser.set_defaults(main=extension.main) if hasattr(extension, 'add_arguments'): try: retval = extension.add_arguments(parser=verb_parser) assert retval is None, 'add_arguments() should return None' except Exception as e: # catch exceptions raised in verb extension exc = traceback.format_exc() colcon_logger.error( "Exception in verb extension '{extension.VERB_NAME}': " '{e}\n{exc}'.format_map(locals()))
def add_parsers_without_arguments( parser, subparser, verb_extensions, *, attribute ): """ Create subparsers for each verb but without any arguments. For each verb extension a subparser is created. :param parser: The argument parser for this command :param subparser: The special action object to add the subparsers to :param dict verb_extensions: The verb extensions indexed by the verb name :param str attribute: The name of the attribute in the extension containing the verb :returns: The subparsers indexed by the verb name :rtype: dict """ verb_parsers = {} # add verb specific group and arguments for name, extension in verb_extensions.items(): verb_parser = subparser.add_parser( getattr(extension, attribute.upper()), description=get_first_line_doc(extension) + '.', formatter_class=parser.formatter_class, ) verb_parser.set_defaults( verb_parser=verb_parser, verb_extension=extension, main=extension.main) verb_parsers[name] = verb_parser return verb_parsers
def create_subparser(parser, cmd_name, verb_extensions, *, attribute): """ Create the special action object to contain subparsers. The `cmd_name` is used for the title and description of the argparse `add_subparsers` function call. :param parser: The argument parser for this command :param str cmd_name: The name of the command to which the verbs are being added :param dict verb_extensions: The verb extensions indexed by the verb name :param str attribute: The name of the attribute in the parsed args for the selected verb :returns: The special action object """ global colcon_logger assert verb_extensions, 'No verb extensions' # list of available verbs with their descriptions verbs = [] for name, extension in verb_extensions.items(): verbs += _format_pair( name, get_first_line_doc(extension), indent=0, align=22) # add subparser with description of verb extensions subparser = parser.add_subparsers( title='{cmd_name} verbs'.format_map(locals()), description='\n'.join(verbs), dest=attribute, help='call `{cmd_name} VERB -h` for specific help' .format_map(locals()) ) return subparser
def add_event_handler_arguments(parser): """ Add the command line arguments for the event handler extensions. :param parser: The argument parser """ group = parser.add_argument_group(title='Event handler arguments') extensions = get_event_handler_extensions(context=None) choices = [] defaults = [] descriptions = '' for key in sorted(extensions.keys()): # only offer the non-default choice choices.append(key + ('-' if extensions[key].enabled else '+')) defaults.append(key + ('+' if extensions[key].enabled else '-')) extension = extensions[key] desc = get_first_line_doc(extension) # ignore extensions without a description # since they are already listed in the defaults if desc: # it requires a custom formatter to maintain the newline descriptions += '\n* {key}: {desc}'.format_map(locals()) group.add_argument( '--event-handlers', nargs='*', choices=choices, metavar=('name1+', 'name2-'), help='Enable (+) or disable (-) event handlers (default: %s)%s' % (' '.join(defaults), descriptions))
def add_python_testing_step_arguments(parser): """ Add the command line arguments for the Python testing step extensions. :param parser: The argument parser """ extensions = get_python_testing_step_extensions() descriptions = '' for key, extension in extensions.items(): desc = get_first_line_doc(extension) if not desc: # show extensions without a description # to mention the available options desc = '<no description>' # it requires a custom formatter to maintain the newline descriptions += '\n* {key}: {desc}'.format_map(locals()) parser.add_argument( '--python-testing', type=str, choices=sorted(extensions.keys()), help='The Python testing framework to use (default: determined ' 'based on the packages `tests_require`)' '{descriptions}'.format_map(locals())) for extension in extensions.values(): try: retval = extension.add_arguments(parser=parser) assert retval is None, 'add_arguments() should return None' except Exception as e: # noqa: F841 # catch exceptions raised in package selection extension exc = traceback.format_exc() logger.error('Exception in Python testing step extension ' "'{extension.STEP_TYPE}': {e}\n{exc}".format_map( locals()))
def _print_extension_point(self, args, name, entry_point): exception = None try: extension_point = load_entry_point(entry_point) except Exception as e: # catch exceptions raised when loading entry point if not args.all: # skip entry points which failed to load return exception = e extension_point = None prefix = '' if exception is None else '- ' print(prefix + name + ':', get_first_line_doc(extension_point)) if args.verbose: print(prefix, ' ', 'module_name:', entry_point.module_name) if entry_point.attrs: print(prefix, ' ', 'attributes:', '.'.join(entry_point.attrs)) if hasattr(extension_point, 'EXTENSION_POINT_VERSION'): print( prefix, ' ', 'version:', extension_point.EXTENSION_POINT_VERSION) if exception: print(prefix, ' ', 'reason:', str(exception))
def add_executor_arguments(parser): """ Add the command line arguments for the executor extensions. :param parser: The argument parser """ group = parser.add_argument_group(title='Executor arguments') extensions = get_executor_extensions() keys = [] descriptions = '' for priority in extensions.keys(): extensions_same_prio = extensions[priority] assert len(extensions_same_prio) == 1, \ 'Executor extensions must have unique priorities' for key, extension in extensions_same_prio.items(): keys.append(key) desc = get_first_line_doc(extension) if not desc: # show extensions without a description # to mention the available options desc = '<no description>' # it requires a custom formatter to maintain the newline descriptions += '\n* {key}: {desc}'.format_map(locals()) assert keys, 'No executor extensions found' default = os.environ.get(DEFAULT_EXECUTOR_ENVIRONMENT_VARIABLE.name) if default not in keys: default = keys[0] group.add_argument( '--executor', type=str, choices=keys, default=default, help='The executor to process all packages (default: {default})' '{descriptions}'.format_map(locals())) for priority in extensions.keys(): extensions_same_prio = extensions[priority] for extension in extensions_same_prio.values(): try: retval = extension.add_arguments(parser=group) assert retval is None, 'add_arguments() should return None' except Exception as e: # noqa: F841 # catch exceptions raised in executor extension exc = traceback.format_exc() logger.error( 'Exception in executor extension ' "'{extension.EXECUTOR_NAME}': {e}\n{exc}".format_map( locals()))
def _print_entry_point(self, args, dist, entry_point): exception = None try: extension = load_entry_point(entry_point) except Exception as e: # catch exceptions raised when loading entry point if not args.all: # skip entry points which failed to load return exception = e extension = None else: try: extension() except Exception as e: # catch exceptions raised in extension constructor if not args.all: # skip extensions which failed to be instantiated return exception = e prefix = ' ' if exception is None else '-' print(prefix, entry_point.name + ':', get_first_line_doc(extension)) if args.verbose: print(prefix, ' ', 'module_name:', entry_point.module_name) if entry_point.attrs: print(prefix, ' ', 'attributes:', '.'.join(entry_point.attrs)) print(prefix, ' ', 'distribution:', repr(dist)) try: print(prefix, ' ', 'priority:', extension.PRIORITY) except AttributeError: pass if exception: print(prefix, ' ', 'reason:', str(exception))