Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new command command-change tree-export to export command tree #448

Merged
merged 5 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions azdev/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ def operation_group(name):
with CommandGroup(self, 'command-change', operation_group('command_change')) as g:
g.command('meta-export', 'export_command_meta')
g.command('meta-diff', 'cmp_command_meta')
g.command('tree-export', 'export_command_tree')

with CommandGroup(self, 'cli', operation_group('pypi')) as g:
g.command('check-versions', 'verify_versions')
Expand Down
69 changes: 68 additions & 1 deletion azdev/operations/command_change/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import azure_cli_diff_tool
from azdev.utilities import display, require_azure_cli, heading, get_path_table, filter_by_git_diff
from .custom import DiffExportFormat, get_commands_meta, STORED_DEPRECATION_KEY
from .util import export_commands_meta
from .util import export_commands_meta, dump_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
Expand Down Expand Up @@ -129,3 +129,70 @@ def export_command_meta(modules=None, git_source=None, git_target=None, git_repo

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):
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)

if cli_only:
selected_modules['ext'] = {}
if ext_only:
selected_modules['core'] = {}
selected_modules['mod'] = {}

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')
ReaNAiveD marked this conversation as resolved.
Show resolved Hide resolved
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, _ in command_loader.command_table.items():
module_loader = command_loader.cmd_to_loader_map[command_name]
if not module_loader:
continue
module_loader = module_loader[0]
module_path = module_loader.__class__.__module__
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extension module name: azext_spring, azext_amcs etc

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use _get_command_source to retrieve the extension name.

module_name = module_path.rsplit('.', maxsplit=1)[-1]
parts = command_name.split()
subtree = command_tree
for part in parts[:-1]:
if not subtree.get(part):
subtree[part] = {}
subtree = subtree[part]
subtree[parts[-1]] = module_name
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be more clear if expected command tree structure is provided or through test.


dump_command_tree(command_tree, output_file)
5 changes: 5 additions & 0 deletions azdev/operations/command_change/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,8 @@ def export_commands_meta(commands_meta, meta_output_path=None):
os.makedirs(file_folder)
with open(file_name, "w") as f_out:
f_out.write(jsbeautifier.beautify(json.dumps(module_info), options))


def dump_command_tree(command_tree, output_file):
with open(output_file, 'w', encoding='utf-8') as f:
json.dump(command_tree, f, indent=4)
4 changes: 4 additions & 0 deletions azdev/params.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ def load_arguments(self, _):
help='format to print diff and suggest message')
c.argument('output_file', help='command meta diff json file path to store')

with ArgumentsContext(self, 'command-change tree-export') as c:
c.positional('modules', modules_type)
c.argument('output_file', help='command tree json file path to store')

# region cmdcov
with ArgumentsContext(self, 'cmdcov') as c:
c.positional('modules', modules_type)
Expand Down