azdev/operations/command_change/__init__.py (124 lines of code) (raw):

# ----------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for # license information. # ----------------------------------------------------------------------------- # pylint: disable=no-else-return, too-many-nested-blocks, too-many-locals, too-many-branches import time from knack.log import get_logger import azure_cli_diff_tool from azdev.utilities import display, require_azure_cli, heading, get_path_table, filter_by_git_diff, \ calc_selected_mod_names from .custom import DiffExportFormat, get_commands_meta, STORED_DEPRECATION_KEY from .util import export_commands_meta, dump_command_tree, add_to_command_tree from ..statistics import _create_invoker_and_load_cmds, _get_command_source, \ _command_codegen_info # pylint: disable=protected-access from ..statistics.util import filter_modules logger = get_logger(__name__) def diff_export_format_choices(): return [form.value for form in DiffExportFormat] # pylint: disable=too-many-statements def export_command_meta(modules=None, git_source=None, git_target=None, git_repo=None, with_help=False, with_example=False, include_whl_extensions=False, meta_output_path=None): require_azure_cli() # allow user to run only on CLI or extensions cli_only = modules == ['CLI'] ext_only = modules == ['EXT'] if cli_only or ext_only: modules = None selected_modules = get_path_table(include_only=modules, include_whl_extensions=include_whl_extensions) if cli_only: selected_modules['ext'] = {} if ext_only: selected_modules['core'] = {} selected_modules['mod'] = {} # filter down to only modules that have changed based on git diff selected_modules = filter_by_git_diff(selected_modules, git_source, git_target, git_repo) if not any(selected_modules.values()): logger.warning('No commands selected to check.') selected_mod_names = list(selected_modules['mod'].keys()) selected_mod_names += list(selected_modules['ext'].keys()) selected_mod_names += list(selected_modules['core'].keys()) if selected_mod_names: display('Modules selected: {}\n'.format(', '.join(selected_mod_names))) heading('Export Command Table Meta') start = time.time() display('Initializing with loading command table...') from azure.cli.core import get_default_cli # pylint: disable=import-error az_cli = get_default_cli() # load commands, args, and help _create_invoker_and_load_cmds(az_cli) stop = time.time() logger.info('Commands loaded in %i sec', stop - start) display('Commands loaded in {} sec'.format(stop - start)) command_loader = az_cli.invocation.commands_loader from azure.cli.core.file_util import get_all_help help_info = {} if with_help or with_example: help_files = get_all_help(az_cli) for help_item in help_files: if not help_item.command: continue help_info[help_item.command] = help_item # trim command table to selected_modules command_loader = filter_modules(command_loader, modules=selected_mod_names, include_whl_extensions=include_whl_extensions) if not command_loader.command_table: logger.warning('No commands selected to check.') commands_info = [] for command_name, command in command_loader.command_table.items(): command_info = { "name": command_name, "source": _get_command_source(command_name, command), "is_aaz": False, "help": help_info[command_name] if command_name in help_info else None, "confirmation": command.confirmation is True, "arguments": [], "az_arguments_schema": None, "supports_no_wait": command.supports_no_wait, "is_preview": command.command_kwargs.get("is_preview", False) } if hasattr(command, "deprecate_info"): for info_key in STORED_DEPRECATION_KEY: if hasattr(command.deprecate_info, info_key) and getattr(command.deprecate_info, info_key): if command_info.get("deprecate_info", None) is None: command_info["deprecate_info"] = {} command_info["deprecate_info"][info_key] = getattr(command.deprecate_info, info_key) module_loader = command_loader.cmd_to_loader_map[command_name] for loader in module_loader: loader.skip_applicability = True codegen_info = _command_codegen_info(command_name, command, module_loader) if codegen_info: command_info['codegen_version'] = codegen_info['version'] command_info['codegen_type'] = codegen_info['type'] if codegen_info['version'] == "v2": command_info['is_aaz'] = True command_loader.load_arguments(command_name) if command.arguments is None: logger.warning('No arguments generated from %i.', command_name) else: command_info['arguments'] = command.arguments if command_info["is_aaz"]: try: command_info['az_arguments_schema'] = command._args_schema # pylint: disable=protected-access except AttributeError: pass commands_info.append(command_info) commands_meta = get_commands_meta(command_loader.command_group_table, commands_info, with_help, with_example) export_commands_meta(commands_meta, meta_output_path) display(f"Total Commands: {len(commands_info)} from {', '.join(selected_mod_names)} have been generated.") def cmp_command_meta(base_meta_file, diff_meta_file, only_break=False, output_type="text", output_file=None): return azure_cli_diff_tool.meta_diff(base_meta_file, diff_meta_file, only_break, output_type, output_file) def export_command_tree(modules, output_file=None, include_whl_extensions=False): require_azure_cli() selected_mod_names = calc_selected_mod_names(modules, include_whl_extensions=include_whl_extensions) if selected_mod_names: display('Modules selected: {}\n'.format(', '.join(selected_mod_names))) heading('Export Command Tree') start = time.time() display('Initializing with loading command table...') from azure.cli.core import get_default_cli # pylint: disable=import-error az_cli = get_default_cli() # load commands, args, and help _create_invoker_and_load_cmds(az_cli) stop = time.time() logger.info('Commands loaded in %i sec', stop - start) display('Commands loaded in {} sec'.format(stop - start)) command_loader = az_cli.invocation.commands_loader # trim command table to selected_modules command_loader = filter_modules(command_loader, modules=selected_mod_names) if not command_loader.command_table: logger.warning('No commands selected to check.') command_tree = {} for command_name, command in command_loader.command_table.items(): module_source = _get_command_source(command_name, command)['module'] # The command tree is a tree structure like our azExtCmdTree: https://aka.ms/azExtCmdTree add_to_command_tree(command_tree, command_name, module_source) dump_command_tree(command_tree, output_file)