def _update_command_table_from_extensions(): extensions = get_extension_names() if extensions: logger.debug("Found %s extensions: %s", len(extensions), extensions) for ext_name in extensions: ext_dir = get_extension_path(ext_name) sys.path.append(ext_dir) try: ext_mod = get_extension_modname(ext_name, ext_dir=ext_dir) # Add to the map. This needs to happen before we load commands as registering a command # from an extension requires this map to be up-to-date. # self._mod_to_ext_map[ext_mod] = ext_name start_time = timeit.default_timer() extension_command_table = _load_extension_command_loader(self, args, ext_mod) for cmd_name, cmd in extension_command_table.items(): cmd.command_source = ExtensionCommandSource( extension_name=ext_name, overrides_command=cmd_name in cmd_to_mod_map) self.command_table.update(extension_command_table) elapsed_time = timeit.default_timer() - start_time logger.debug("Loaded extension '%s' in %.3f seconds.", ext_name, elapsed_time) except Exception: # pylint: disable=broad-except logger.warning("Unable to load extension '%s'. Use --debug for more information.", ext_name) logger.debug(traceback.format_exc())
def _update_command_table_from_extensions(ext_suppressions): from azure.cli.core.extension.operations import check_version_compatibility def _handle_extension_suppressions(extensions): filtered_extensions = [] for ext in extensions: should_include = True for suppression in ext_suppressions: if should_include and suppression.handle_suppress(ext): should_include = False if should_include: filtered_extensions.append(ext) return filtered_extensions extensions = get_extensions() if extensions: logger.debug("Found %s extensions: %s", len(extensions), [e.name for e in extensions]) allowed_extensions = _handle_extension_suppressions(extensions) module_commands = set(self.command_table.keys()) for ext in allowed_extensions: try: check_version_compatibility(ext.get_metadata()) except CLIError as ex: # issue warning and skip loading extensions that aren't compatible with the CLI core logger.warning(ex) continue ext_name = ext.name ext_dir = ext.path or get_extension_path(ext_name) sys.path.append(ext_dir) try: ext_mod = get_extension_modname(ext_name, ext_dir=ext_dir) # Add to the map. This needs to happen before we load commands as registering a command # from an extension requires this map to be up-to-date. # self._mod_to_ext_map[ext_mod] = ext_name start_time = timeit.default_timer() extension_command_table, extension_group_table = \ _load_extension_command_loader(self, args, ext_mod) for cmd_name, cmd in extension_command_table.items(): cmd.command_source = ExtensionCommandSource( extension_name=ext_name, overrides_command=cmd_name in module_commands, preview=ext.preview, experimental=ext.experimental) self.command_table.update(extension_command_table) self.command_group_table.update(extension_group_table) elapsed_time = timeit.default_timer() - start_time logger.debug("Loaded extension '%s' in %.3f seconds.", ext_name, elapsed_time) except Exception as ex: # pylint: disable=broad-except self.cli_ctx.raise_event(EVENT_FAILED_EXTENSION_LOAD, extension_name=ext_name) logger.warning( "Unable to load extension '%s: %s'. Use --debug for more information.", ext_name, ex) logger.debug(traceback.format_exc())
def _update_command_table_from_extensions(ext_suppressions): def _handle_extension_suppressions(extensions): filtered_extensions = [] for ext in extensions: should_include = True for suppression in ext_suppressions: if should_include and suppression.handle_suppress(ext): should_include = False if should_include: filtered_extensions.append(ext) return filtered_extensions extensions = get_extensions() if extensions: logger.debug("Found %s extensions: %s", len(extensions), [e.name for e in extensions]) allowed_extensions = _handle_extension_suppressions(extensions) module_commands = set(self.command_table.keys()) for ext in allowed_extensions: ext_name = ext.name ext_dir = get_extension_path(ext_name) sys.path.append(ext_dir) try: ext_mod = get_extension_modname(ext_name, ext_dir=ext_dir) # Add to the map. This needs to happen before we load commands as registering a command # from an extension requires this map to be up-to-date. # self._mod_to_ext_map[ext_mod] = ext_name start_time = timeit.default_timer() extension_command_table = _load_extension_command_loader( self, args, ext_mod) for cmd_name, cmd in extension_command_table.items(): cmd.command_source = ExtensionCommandSource( extension_name=ext_name, overrides_command=cmd_name in module_commands, preview=ext.preview) self.command_table.update(extension_command_table) elapsed_time = timeit.default_timer() - start_time logger.debug("Loaded extension '%s' in %.3f seconds.", ext_name, elapsed_time) except Exception: # pylint: disable=broad-except logger.warning( "Unable to load extension '%s'. Use --debug for more information.", ext_name) logger.debug(traceback.format_exc())
def create_invoker_and_load_cmds_and_args(cli): cli.invocation = mock.MagicMock() cli.invocation.commands_loader = mock.MagicMock() cli.invocation.commands_loader.command_table = self.cmd_table = {} for cmd in [ 'foo command_1', 'foo command_2', 'bar command_1', 'bar command_2', 'foobar' ]: self.cmd_table[cmd] = AzCliCommand( cli.invocation.commands_loader, cmd, lambda: None) for cmd in ['bar command_1', 'bar command_2']: self.cmd_table[cmd].command_source = ExtensionCommandSource( extension_name='bar') self.cmd_table[cmd].command_source.extension_name = 'bar' for cmd in ['foo command_1', 'foo command_2']: self.cmd_table[cmd].command_source = mock.MagicMock() self.cmd_table[cmd].command_source = 'foo'
def _update_command_table_from_extensions(ext_suppressions, extension_modname=None): """Loads command tables from extensions and merge into the main command table. :param ext_suppressions: Extension suppression information. :param extension_modname: Command modules to load, in the format like ['azext_timeseriesinsights']. If None, will do extension discovery and load all extensions. If [], only ALWAYS_LOADED_EXTENSIONS will be loaded. Otherwise, the list will be extended using ALWAYS_LOADED_EXTENSIONS. If the extensions in the list are not installed, it will be skipped. """ def _handle_extension_suppressions(extensions): filtered_extensions = [] for ext in extensions: should_include = True for suppression in ext_suppressions: if should_include and suppression.handle_suppress(ext): should_include = False if should_include: filtered_extensions.append(ext) return filtered_extensions def _filter_modname(extensions): # Extension's name may not be the same as its modname. eg. name: virtual-wan, modname: azext_vwan filtered_extensions = [] for ext in extensions: ext_mod = get_extension_modname(ext.name, ext.path) # Filter the extensions according to the index if ext_mod in extension_modname: filtered_extensions.append(ext) extension_modname.remove(ext_mod) if extension_modname: logger.debug( "These extensions are not installed and will be skipped: %s", extension_modname) return filtered_extensions extensions = get_extensions() if extensions: if extension_modname is not None: extension_modname.extend(ALWAYS_LOADED_EXTENSIONS) extensions = _filter_modname(extensions) allowed_extensions = _handle_extension_suppressions(extensions) module_commands = set(self.command_table.keys()) count = 0 cumulative_elapsed_time = 0 cumulative_group_count = 0 cumulative_command_count = 0 logger.debug("Loading extensions:") logger.debug(self.header_ext) for ext in allowed_extensions: try: # Import in the `for` loop because `allowed_extensions` can be []. In such case we # don't need to import `check_version_compatibility` at all. from azure.cli.core.extension.operations import check_version_compatibility check_version_compatibility(ext.get_metadata()) except CLIError as ex: # issue warning and skip loading extensions that aren't compatible with the CLI core logger.warning(ex) continue ext_name = ext.name ext_dir = ext.path or get_extension_path(ext_name) sys.path.append(ext_dir) try: ext_mod = get_extension_modname(ext_name, ext_dir=ext_dir) # Add to the map. This needs to happen before we load commands as registering a command # from an extension requires this map to be up-to-date. # self._mod_to_ext_map[ext_mod] = ext_name start_time = timeit.default_timer() extension_command_table, extension_group_table = \ _load_extension_command_loader(self, args, ext_mod) for cmd_name, cmd in extension_command_table.items(): cmd.command_source = ExtensionCommandSource( extension_name=ext_name, overrides_command=cmd_name in module_commands, preview=ext.preview, experimental=ext.experimental) self.command_table.update(extension_command_table) self.command_group_table.update(extension_group_table) elapsed_time = timeit.default_timer() - start_time logger.debug(self.item_ext_format_string, ext_name, elapsed_time, len(extension_group_table), len(extension_command_table), ext_dir) count += 1 cumulative_elapsed_time += elapsed_time cumulative_group_count += len(extension_group_table) cumulative_command_count += len( extension_command_table) except Exception as ex: # pylint: disable=broad-except self.cli_ctx.raise_event(EVENT_FAILED_EXTENSION_LOAD, extension_name=ext_name) logger.warning( "Unable to load extension '%s: %s'. Use --debug for more information.", ext_name, ex) logger.debug(traceback.format_exc()) # Summary line logger.debug(self.item_ext_format_string, "Total ({})".format(count), cumulative_elapsed_time, cumulative_group_count, cumulative_command_count, "")