Skip to content

Commit

Permalink
Add new command command-change tree-export to export command tree (#…
Browse files Browse the repository at this point in the history
…448)

* Add new command `command-change tree-export` to export command tree

* Fix style

* apply suggestions

* Update version

* Extract tree build and add test
  • Loading branch information
ReaNAiveD authored May 17, 2024
1 parent 6b2b150 commit 3b507dc
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 3 deletions.
4 changes: 4 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
Release History
===============
0.1.68
++++++
* `azdev command-change tree-export`: Add new command to support export command tree of CLI modules.

0.1.67
++++++
* `azdev extension cal-next-version`: Justify preview/exp tag operation based on last version's tag and next version's stable/preview tag.
Expand Down
2 changes: 1 addition & 1 deletion azdev/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
# license information.
# -----------------------------------------------------------------------------

__VERSION__ = '0.1.67'
__VERSION__ = '0.1.68'
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
59 changes: 58 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, 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
Expand Down Expand Up @@ -129,3 +129,60 @@ 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 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)
15 changes: 15 additions & 0 deletions azdev/operations/command_change/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,18 @@ 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 add_to_command_tree(tree, key, value):
parts = key.split()
subtree = tree
for part in parts[:-1]:
if not subtree.get(part):
subtree[part] = {}
subtree = subtree[part]
subtree[parts[-1]] = value


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)
18 changes: 17 additions & 1 deletion azdev/operations/tests/test_break_change.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import unittest
import os
from azdev.operations.command_change import export_command_meta, cmp_command_meta
from azdev.operations.command_change.util import get_command_tree
from azdev.operations.command_change.util import get_command_tree, add_to_command_tree


class MyTestCase(unittest.TestCase):
Expand Down Expand Up @@ -57,6 +57,22 @@ def test_diff_meta(self):
break
self.assertTrue(ignored, "ignored message found")

def test_command_tree(self):
tree = {}
add_to_command_tree(tree, 'a b c', 'd')
add_to_command_tree(tree, 'a b foo', 'bar')
add_to_command_tree(tree, 'a foo', 'baz')
expected = {
'a': {
'b': {
'c': 'd',
'foo': 'bar'
},
'foo': 'baz'
}
}
self.assertDictEqual(tree, expected)


if __name__ == '__main__':
unittest.main()
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

0 comments on commit 3b507dc

Please sign in to comment.