-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
[Core] Linter rule for service_name.json #3186
Merged
Merged
Changes from 8 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
ddb3ba7
service_name.py
qwordy 1afcc30
run on modified extensions
qwordy a45acb8
import
qwordy 82236c6
test
qwordy 4643f13
restore blueprint
qwordy 9ca5d23
remove description
qwordy aa3519b
require extensionname
qwordy cc4dc9c
remove extensionname
qwordy 24f017e
update
qwordy abb193f
resource mover
qwordy 78679f6
message
qwordy 1746549
Merge branch 'master' of https://github.com/Azure/azure-cli-extension…
qwordy 41bcc20
Update scripts/ci/service_name.py
qwordy 0409c48
Update scripts/ci/service_name.py
qwordy File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
#!/usr/bin/env python | ||
|
||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
""" | ||
Check format of service_name.json. Command and AzureServiceName are required. Others are optional. | ||
Each highest level command group should have reference in service_name.json. | ||
""" | ||
import json | ||
|
||
from azure.cli.core import MainCommandsLoader, AzCli | ||
from azure.cli.core._help import AzCliHelp, CliCommandHelpFile | ||
from azure.cli.core.commands import AzCliCommandInvoker, ExtensionCommandSource | ||
from azure.cli.core.parser import AzCliCommandParser | ||
from knack.help import GroupHelpFile | ||
|
||
|
||
def get_extension_help_files(cli_ctx): | ||
|
||
# 1. Create invoker and load command table and arguments. Remember to turn off applicability check. | ||
invoker = cli_ctx.invocation_cls(cli_ctx=cli_ctx, commands_loader_cls=cli_ctx.commands_loader_cls, | ||
parser_cls=cli_ctx.parser_cls, help_cls=cli_ctx.help_cls) | ||
cli_ctx.invocation = invoker | ||
|
||
invoker.commands_loader.skip_applicability = True | ||
cmd_table = invoker.commands_loader.load_command_table(None) | ||
|
||
# turn off applicability check for all loaders | ||
for loaders in invoker.commands_loader.cmd_to_loader_map.values(): | ||
for loader in loaders: | ||
loader.skip_applicability = True | ||
|
||
# filter the command table to only get commands from extensions | ||
cmd_table = {k: v for k, v in cmd_table.items() if isinstance(v.command_source, ExtensionCommandSource)} | ||
invoker.commands_loader.command_table = cmd_table | ||
print('FOUND {} command(s) from the extension.'.format(len(cmd_table))) | ||
|
||
for cmd_name in cmd_table: | ||
invoker.commands_loader.load_arguments(cmd_name) | ||
|
||
invoker.parser.load_command_table(invoker.commands_loader) | ||
|
||
# 2. Now load applicable help files | ||
parser_keys = [] | ||
parser_values = [] | ||
sub_parser_keys = [] | ||
sub_parser_values = [] | ||
_store_parsers(invoker.parser, parser_keys, parser_values, sub_parser_keys, sub_parser_values) | ||
for cmd, parser in zip(parser_keys, parser_values): | ||
if cmd not in sub_parser_keys: | ||
sub_parser_keys.append(cmd) | ||
sub_parser_values.append(parser) | ||
help_ctx = cli_ctx.help_cls(cli_ctx=cli_ctx) | ||
help_files = [] | ||
for cmd, parser in zip(sub_parser_keys, sub_parser_values): | ||
try: | ||
help_file = GroupHelpFile(help_ctx, cmd, parser) if _is_group(parser) \ | ||
else CliCommandHelpFile(help_ctx, cmd, parser) | ||
help_file.load(parser) | ||
help_files.append(help_file) | ||
except Exception as ex: | ||
print("Skipped '{}' due to '{}'".format(cmd, ex)) | ||
help_files = sorted(help_files, key=lambda x: x.command) | ||
return help_files | ||
|
||
|
||
def _store_parsers(parser, parser_keys, parser_values, sub_parser_keys, sub_parser_values): | ||
for s in parser.subparsers.values(): | ||
parser_keys.append(_get_parser_name(s)) | ||
parser_values.append(s) | ||
if _is_group(s): | ||
for c in s.choices.values(): | ||
sub_parser_keys.append(_get_parser_name(c)) | ||
sub_parser_values.append(c) | ||
_store_parsers(c, parser_keys, parser_values, sub_parser_keys, sub_parser_values) | ||
|
||
|
||
def _get_parser_name(s): | ||
return (s._prog_prefix if hasattr(s, '_prog_prefix') else s.prog)[3:] | ||
|
||
|
||
def _is_group(parser): | ||
return getattr(parser, '_subparsers', None) is not None \ | ||
or getattr(parser, 'choices', None) is not None | ||
|
||
|
||
def check(): | ||
az_cli = AzCli(cli_name='az', | ||
commands_loader_cls=MainCommandsLoader, | ||
invocation_cls=AzCliCommandInvoker, | ||
parser_cls=AzCliCommandParser, | ||
help_cls=AzCliHelp) | ||
# with patch('getpass.getuser', return_value='your_system_user_login_name'): | ||
# create_invoker_and_load_cmds_and_args(az_cli) | ||
help_files = get_extension_help_files(az_cli) | ||
high_command_set = set() | ||
qwordy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
for help_file in help_files: | ||
if help_file.command: | ||
high_command_set.add(help_file.command.split()[0]) | ||
print(high_command_set) | ||
|
||
# Load and check service_name.json | ||
with open('src/service_name.json') as f: | ||
service_names = json.load(f) | ||
# print(service_names) | ||
service_name_map = {} | ||
for service_name in service_names: | ||
command = service_name['Command'] | ||
service = service_name['AzureServiceName'] | ||
if not command.startswith('az '): | ||
raise Exception('{} not starts with az'.format(command)) | ||
if not service: | ||
raise Exception('AzureServiceName of {} is empty!'.format(command)) | ||
service_name_map[command[3:]] = service | ||
print(service_name_map) | ||
|
||
# Check existence in service_name.json | ||
for high_command in high_command_set: | ||
if high_command not in service_name_map: | ||
raise Exception('No entry of {} in service_name.json'.format(high_command)) | ||
qwordy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
|
||
if __name__ == "__main__": | ||
check() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reuse the same function in
azure-cli-core
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reuse code from azure-cli-extensions